601 lines
24 KiB
Java
601 lines
24 KiB
Java
|
|
package com.chuangzhou.vivid2D.test;
|
||
|
|
|
||
|
|
import com.chuangzhou.vivid2D.render.model.Model2D;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.ModelPart;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.AnimationParameter;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.util.Mesh2D;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.util.AnimationLayer;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.util.PhysicsSystem;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.util.ModelPose;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.util.BoundingBox;
|
||
|
|
import com.chuangzhou.vivid2D.render.model.util.Texture;
|
||
|
|
import org.joml.Vector2f;
|
||
|
|
import org.lwjgl.glfw.GLFW;
|
||
|
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||
|
|
import org.lwjgl.opengl.GL;
|
||
|
|
import org.lwjgl.system.MemoryUtil;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 用于测试Model2D模型的保存和加载功能
|
||
|
|
*
|
||
|
|
* @author tzdwindows 7
|
||
|
|
*/
|
||
|
|
public class ModelTest {
|
||
|
|
|
||
|
|
private static long window;
|
||
|
|
private static boolean glInitialized = false;
|
||
|
|
|
||
|
|
public static void main(String[] args) {
|
||
|
|
System.out.println("=== Model2D Extended Save and Load Test Start ===");
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Initialize OpenGL context for texture testing
|
||
|
|
initializeOpenGL();
|
||
|
|
|
||
|
|
// Test 1: Create model and save (with texture)
|
||
|
|
testCreateAndSaveModelWithTexture();
|
||
|
|
|
||
|
|
// Test 2: Load model and verify data including textures
|
||
|
|
testLoadAndVerifyModelWithTexture();
|
||
|
|
|
||
|
|
// Test 3: Test compressed file operations with textures
|
||
|
|
testCompressedFileOperationsWithTexture();
|
||
|
|
|
||
|
|
// Other existing tests...
|
||
|
|
testAnimationSystem();
|
||
|
|
testPhysicsSystem();
|
||
|
|
testComplexTransformations();
|
||
|
|
testPerformance();
|
||
|
|
|
||
|
|
} finally {
|
||
|
|
// Cleanup OpenGL
|
||
|
|
cleanupOpenGL();
|
||
|
|
}
|
||
|
|
|
||
|
|
System.out.println("=== Model2D Extended Save and Load Test Complete ===");
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Initialize OpenGL context for texture testing
|
||
|
|
*/
|
||
|
|
private static void initializeOpenGL() {
|
||
|
|
try {
|
||
|
|
// Setup error callback
|
||
|
|
GLFWErrorCallback.createPrint(System.err).set();
|
||
|
|
|
||
|
|
// Initialize GLFW
|
||
|
|
if (!GLFW.glfwInit()) {
|
||
|
|
throw new IllegalStateException("Unable to initialize GLFW");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Configure GLFW
|
||
|
|
GLFW.glfwDefaultWindowHints();
|
||
|
|
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); // Hide window
|
||
|
|
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_FALSE);
|
||
|
|
|
||
|
|
// Create window
|
||
|
|
window = GLFW.glfwCreateWindow(100, 100, "Texture Test", MemoryUtil.NULL, MemoryUtil.NULL);
|
||
|
|
if (window == MemoryUtil.NULL) {
|
||
|
|
throw new RuntimeException("Failed to create GLFW window");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Make OpenGL context current
|
||
|
|
GLFW.glfwMakeContextCurrent(window);
|
||
|
|
GLFW.glfwSwapInterval(1); // Enable v-sync
|
||
|
|
|
||
|
|
// Initialize OpenGL capabilities
|
||
|
|
GL.createCapabilities();
|
||
|
|
|
||
|
|
System.out.println("OpenGL initialized successfully");
|
||
|
|
System.out.println("OpenGL Version: " + org.lwjgl.opengl.GL11.glGetString(org.lwjgl.opengl.GL11.GL_VERSION));
|
||
|
|
glInitialized = true;
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Failed to initialize OpenGL: " + e.getMessage());
|
||
|
|
// Continue without OpenGL for other tests
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Cleanup OpenGL resources
|
||
|
|
*/
|
||
|
|
private static void cleanupOpenGL() {
|
||
|
|
if (window != MemoryUtil.NULL) {
|
||
|
|
GLFW.glfwDestroyWindow(window);
|
||
|
|
}
|
||
|
|
GLFW.glfwTerminate();
|
||
|
|
GLFW.glfwSetErrorCallback(null).free();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 1: Create model with textures and save to file
|
||
|
|
*/
|
||
|
|
public static void testCreateAndSaveModelWithTexture() {
|
||
|
|
System.out.println("\n--- Test 1: Create and Save Model with Textures ---");
|
||
|
|
|
||
|
|
if (!glInitialized) {
|
||
|
|
System.out.println("Skipping texture test - OpenGL not available");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Create model
|
||
|
|
Model2D model = new Model2D("textured_character");
|
||
|
|
model.setVersion("1.0.0");
|
||
|
|
|
||
|
|
// Create parts
|
||
|
|
ModelPart body = model.createPart("body");
|
||
|
|
ModelPart head = model.createPart("head");
|
||
|
|
|
||
|
|
// Build hierarchy
|
||
|
|
body.addChild(head);
|
||
|
|
|
||
|
|
// Set part properties
|
||
|
|
body.setPosition(0, 0);
|
||
|
|
head.setPosition(0, -50);
|
||
|
|
|
||
|
|
// Create test textures
|
||
|
|
System.out.println("Creating test textures...");
|
||
|
|
|
||
|
|
// Create solid color texture
|
||
|
|
Texture bodyTexture = Texture.createSolidColor("body_texture", 64, 64, 0xFFFF0000); // Red
|
||
|
|
Texture headTexture = Texture.createSolidColor("head_texture", 64, 64, 0xFF00FF00); // Green
|
||
|
|
|
||
|
|
// Create checkerboard texture
|
||
|
|
Texture checkerTexture = Texture.createCheckerboard("checker_texture", 128, 128, 16,
|
||
|
|
0xFFFFFFFF, 0xFF0000FF); // White and Blue
|
||
|
|
|
||
|
|
// === 关键修复:确保纹理数据被缓存 ===
|
||
|
|
System.out.println("Ensuring texture data is cached...");
|
||
|
|
bodyTexture.ensurePixelDataCached();
|
||
|
|
headTexture.ensurePixelDataCached();
|
||
|
|
checkerTexture.ensurePixelDataCached();
|
||
|
|
|
||
|
|
// 验证缓存状态
|
||
|
|
System.out.println("Texture cache status:");
|
||
|
|
System.out.println(" - body_texture: " + (bodyTexture.hasPixelData() ? "CACHED" : "MISSING"));
|
||
|
|
System.out.println(" - head_texture: " + (headTexture.hasPixelData() ? "CACHED" : "MISSING"));
|
||
|
|
System.out.println(" - checker_texture: " + (checkerTexture.hasPixelData() ? "CACHED" : "MISSING"));
|
||
|
|
|
||
|
|
// Add textures to model
|
||
|
|
model.addTexture(bodyTexture);
|
||
|
|
model.addTexture(headTexture);
|
||
|
|
model.addTexture(checkerTexture);
|
||
|
|
|
||
|
|
// Create meshes and assign textures
|
||
|
|
Mesh2D bodyMesh = Mesh2D.createQuad("body_mesh", 40, 80);
|
||
|
|
Mesh2D headMesh = Mesh2D.createQuad("head_mesh", 50, 50);
|
||
|
|
|
||
|
|
// Set textures for meshes
|
||
|
|
bodyMesh.setTexture(bodyTexture);
|
||
|
|
headMesh.setTexture(headTexture);
|
||
|
|
|
||
|
|
// Add meshes to model and parts
|
||
|
|
model.addMesh(bodyMesh);
|
||
|
|
model.addMesh(headMesh);
|
||
|
|
body.addMesh(bodyMesh);
|
||
|
|
head.addMesh(headMesh);
|
||
|
|
|
||
|
|
// Create animation parameters
|
||
|
|
AnimationParameter smileParam = model.createParameter("smile", 0, 1, 0);
|
||
|
|
model.setParameterValue("smile", 0.5f);
|
||
|
|
|
||
|
|
// Update model
|
||
|
|
model.update(0.016f);
|
||
|
|
|
||
|
|
// Save to regular file
|
||
|
|
String regularFilePath = "textured_character.model";
|
||
|
|
model.saveToFile(regularFilePath);
|
||
|
|
System.out.println("Textured model saved to regular file: " + regularFilePath);
|
||
|
|
|
||
|
|
// Save to compressed file
|
||
|
|
String compressedFilePath = "textured_character.model.gz";
|
||
|
|
model.saveToCompressedFile(compressedFilePath);
|
||
|
|
System.out.println("Textured model saved to compressed file: " + compressedFilePath);
|
||
|
|
|
||
|
|
// Verify model state before saving
|
||
|
|
System.out.println("Textured model created successfully:");
|
||
|
|
System.out.println(" - Name: " + model.getName());
|
||
|
|
System.out.println(" - Textures: " + model.getTextures().size());
|
||
|
|
System.out.println(" - Meshes: " + model.getMeshes().size());
|
||
|
|
|
||
|
|
// Print texture information
|
||
|
|
for (Texture texture : model.getTextures().values()) {
|
||
|
|
System.out.println(" - Texture: " + texture.getName() +
|
||
|
|
" (" + texture.getWidth() + "x" + texture.getHeight() +
|
||
|
|
", format: " + texture.getFormat() +
|
||
|
|
", cached: " + texture.hasPixelData() + ")");
|
||
|
|
}
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testCreateAndSaveModelWithTexture: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
|
||
|
|
// 提供更详细的错误信息
|
||
|
|
if (e.getCause() != null) {
|
||
|
|
System.err.println("Caused by: " + e.getCause().getMessage());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 2: Load model with textures and verify data integrity
|
||
|
|
*/
|
||
|
|
public static void testLoadAndVerifyModelWithTexture() {
|
||
|
|
System.out.println("\n--- Test 2: Load and Verify Model with Textures ---");
|
||
|
|
|
||
|
|
if (!glInitialized) {
|
||
|
|
System.out.println("Skipping texture test - OpenGL not available");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Load from regular file
|
||
|
|
String filePath = "textured_character.model";
|
||
|
|
Model2D loadedModel = Model2D.loadFromFile(filePath);
|
||
|
|
|
||
|
|
System.out.println("Textured model loaded successfully from: " + filePath);
|
||
|
|
|
||
|
|
// Verify basic properties
|
||
|
|
System.out.println("Basic properties:");
|
||
|
|
System.out.println(" - Name: " + loadedModel.getName());
|
||
|
|
System.out.println(" - Version: " + loadedModel.getVersion());
|
||
|
|
|
||
|
|
// Verify textures
|
||
|
|
System.out.println("Textures verification:");
|
||
|
|
System.out.println(" - Total textures: " + loadedModel.getTextures().size());
|
||
|
|
|
||
|
|
for (Texture texture : loadedModel.getTextures().values()) {
|
||
|
|
System.out.println(" - Texture '" + texture.getName() + "': " +
|
||
|
|
texture.getWidth() + "x" + texture.getHeight() +
|
||
|
|
", format: " + texture.getFormat() +
|
||
|
|
", disposed: " + texture.isDisposed());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Verify parts and meshes
|
||
|
|
System.out.println("Parts and meshes verification:");
|
||
|
|
for (ModelPart part : loadedModel.getParts()) {
|
||
|
|
System.out.println(" - Part '" + part.getName() + "': " +
|
||
|
|
part.getMeshes().size() + " meshes");
|
||
|
|
|
||
|
|
for (Mesh2D mesh : part.getMeshes()) {
|
||
|
|
Texture meshTexture = mesh.getTexture();
|
||
|
|
System.out.println(" * Mesh '" + mesh.getName() + "': " +
|
||
|
|
(meshTexture != null ? "has texture '" + meshTexture.getName() + "'" : "no texture"));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test texture functionality
|
||
|
|
System.out.println("Texture functionality test:");
|
||
|
|
Texture bodyTexture = loadedModel.getTexture("body_texture");
|
||
|
|
if (bodyTexture != null) {
|
||
|
|
System.out.println(" - Body texture validation:");
|
||
|
|
System.out.println(" * Width: " + bodyTexture.getWidth());
|
||
|
|
System.out.println(" * Height: " + bodyTexture.getHeight());
|
||
|
|
System.out.println(" * Format: " + bodyTexture.getFormat());
|
||
|
|
System.out.println(" * Memory usage: " + bodyTexture.getEstimatedMemoryUsage() + " bytes");
|
||
|
|
|
||
|
|
// Test texture binding (if OpenGL context is available)
|
||
|
|
try {
|
||
|
|
bodyTexture.bind(0);
|
||
|
|
System.out.println(" * Texture binding: SUCCESS");
|
||
|
|
bodyTexture.unbind();
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.out.println(" * Texture binding: FAILED - " + e.getMessage());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test parameter modification
|
||
|
|
System.out.println("Parameter modification test:");
|
||
|
|
loadedModel.setParameterValue("smile", 0.8f);
|
||
|
|
float newSmileValue = loadedModel.getParameterValue("smile");
|
||
|
|
System.out.println(" - Modified smile parameter to: " + newSmileValue);
|
||
|
|
|
||
|
|
// Test model update
|
||
|
|
loadedModel.update(0.016f);
|
||
|
|
System.out.println(" - Model update completed successfully");
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testLoadAndVerifyModelWithTexture: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 3: Test compressed file operations with textures
|
||
|
|
*/
|
||
|
|
public static void testCompressedFileOperationsWithTexture() {
|
||
|
|
System.out.println("\n--- Test 3: Compressed File Operations with Textures ---");
|
||
|
|
|
||
|
|
if (!glInitialized) {
|
||
|
|
System.out.println("Skipping texture test - OpenGL not available");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Load from compressed file
|
||
|
|
String compressedFilePath = "textured_character.model.gz";
|
||
|
|
Model2D compressedModel = Model2D.loadFromCompressedFile(compressedFilePath);
|
||
|
|
|
||
|
|
System.out.println("Textured model loaded successfully from compressed file: " + compressedFilePath);
|
||
|
|
System.out.println(" - Name: " + compressedModel.getName());
|
||
|
|
System.out.println(" - Textures: " + compressedModel.getTextures().size());
|
||
|
|
System.out.println(" - Parts: " + compressedModel.getParts().size());
|
||
|
|
|
||
|
|
// Verify textures in compressed model
|
||
|
|
System.out.println("Compressed model texture verification:");
|
||
|
|
for (Texture texture : compressedModel.getTextures().values()) {
|
||
|
|
System.out.println(" - Texture '" + texture.getName() + "': " +
|
||
|
|
texture.getWidth() + "x" + texture.getHeight());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Modify and re-save
|
||
|
|
compressedModel.setName("modified_textured_character");
|
||
|
|
compressedModel.setParameterValue("smile", 0.9f);
|
||
|
|
|
||
|
|
String newCompressedPath = "modified_textured_character.model.gz";
|
||
|
|
compressedModel.saveToCompressedFile(newCompressedPath);
|
||
|
|
System.out.println("Modified textured model saved to new compressed file: " + newCompressedPath);
|
||
|
|
|
||
|
|
// Verify the new compressed file can be loaded
|
||
|
|
Model2D reloadedModel = Model2D.loadFromCompressedFile(newCompressedPath);
|
||
|
|
System.out.println("Reloaded modified textured model verification:");
|
||
|
|
System.out.println(" - Name: " + reloadedModel.getName());
|
||
|
|
System.out.println(" - Smile parameter value: " + reloadedModel.getParameterValue("smile"));
|
||
|
|
System.out.println(" - Textures: " + reloadedModel.getTextures().size());
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testCompressedFileOperationsWithTexture: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 4: Test animation system
|
||
|
|
*/
|
||
|
|
public static void testAnimationSystem() {
|
||
|
|
System.out.println("\n--- Test 4: Animation System Test ---");
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Load model
|
||
|
|
Model2D model = Model2D.loadFromFile("test_character.model");
|
||
|
|
|
||
|
|
System.out.println("Testing animation system:");
|
||
|
|
|
||
|
|
// Test parameter-driven animation
|
||
|
|
System.out.println("Parameter-driven animation test:");
|
||
|
|
for (int frame = 0; frame < 10; frame++) {
|
||
|
|
float walkValue = (float) Math.sin(frame * 0.2f) * 0.5f + 0.5f;
|
||
|
|
float waveValue = (float) Math.sin(frame * 0.3f);
|
||
|
|
float blinkValue = frame % 20 == 0 ? 1.0f : 0.0f; // Blink every 20 frames
|
||
|
|
|
||
|
|
model.setParameterValue("walk_cycle", walkValue);
|
||
|
|
model.setParameterValue("wave", waveValue);
|
||
|
|
model.setParameterValue("blink", blinkValue);
|
||
|
|
|
||
|
|
model.update(0.016f);
|
||
|
|
|
||
|
|
System.out.println(" - Frame " + frame +
|
||
|
|
": walk=" + String.format("%.2f", walkValue) +
|
||
|
|
", wave=" + String.format("%.2f", waveValue) +
|
||
|
|
", blink=" + String.format("%.2f", blinkValue));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test pose system
|
||
|
|
System.out.println("Pose system test:");
|
||
|
|
ModelPose currentPose = model.getCurrentPose();
|
||
|
|
if (currentPose != null) {
|
||
|
|
System.out.println(" - Current pose: " + currentPose);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test animation layer blending
|
||
|
|
System.out.println("Animation layer test:");
|
||
|
|
for (AnimationLayer layer : model.getAnimationLayers()) {
|
||
|
|
System.out.println(" - Layer: " + layer.getName());
|
||
|
|
}
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testAnimationSystem: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 5: Test physics system
|
||
|
|
*/
|
||
|
|
public static void testPhysicsSystem() {
|
||
|
|
System.out.println("\n--- Test 5: Physics System Test ---");
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Load model
|
||
|
|
Model2D model = Model2D.loadFromFile("test_character.model");
|
||
|
|
|
||
|
|
System.out.println("Testing physics system:");
|
||
|
|
|
||
|
|
PhysicsSystem physics = model.getPhysics();
|
||
|
|
System.out.println(" - Physics system: " +
|
||
|
|
(physics != null ? "available" : "not available"));
|
||
|
|
|
||
|
|
if (physics != null) {
|
||
|
|
Vector2f gravity = physics.getGravity();
|
||
|
|
System.out.println(" - Gravity: (" + gravity.x + ", " + gravity.y + ")");
|
||
|
|
System.out.println(" - Air resistance: " + physics.getAirResistance());
|
||
|
|
System.out.println(" - Time scale: " + physics.getTimeScale());
|
||
|
|
System.out.println(" - Enabled: " + physics.isEnabled());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test physics simulation
|
||
|
|
System.out.println("Physics simulation test:");
|
||
|
|
|
||
|
|
// 初始化物理系统
|
||
|
|
physics.initialize();
|
||
|
|
|
||
|
|
// 添加一些物理粒子
|
||
|
|
PhysicsSystem.PhysicsParticle particle1 = physics.addParticle("test_particle1", new Vector2f(0, 0), 1.0f);
|
||
|
|
PhysicsSystem.PhysicsParticle particle2 = physics.addParticle("test_particle2", new Vector2f(10, 0), 1.0f);
|
||
|
|
|
||
|
|
// 添加弹簧连接
|
||
|
|
physics.addSpring("test_spring", particle1, particle2, 15.0f, 0.5f, 0.1f);
|
||
|
|
|
||
|
|
for (int step = 0; step < 15; step++) {
|
||
|
|
model.update(0.016f); // Simulate physics
|
||
|
|
|
||
|
|
if (step % 5 == 0) {
|
||
|
|
System.out.println(" - Step " + step + ": model updated with physics");
|
||
|
|
Vector2f pos1 = particle1.getPosition();
|
||
|
|
System.out.println(" Particle1 position: (" +
|
||
|
|
String.format("%.2f", pos1.x) + ", " +
|
||
|
|
String.format("%.2f", pos1.y) + ")");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test physics properties
|
||
|
|
System.out.println("Physics properties verification:");
|
||
|
|
System.out.println(" - Active physics: " + physics.hasActivePhysics());
|
||
|
|
System.out.println(" - Particle count: " + physics.getParticles().size());
|
||
|
|
System.out.println(" - Spring count: " + physics.getSprings().size());
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testPhysicsSystem: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 6: Test complex transformations
|
||
|
|
*/
|
||
|
|
public static void testComplexTransformations() {
|
||
|
|
System.out.println("\n--- Test 6: Complex Transformations Test ---");
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Load model
|
||
|
|
Model2D model = Model2D.loadFromFile("test_character.model");
|
||
|
|
|
||
|
|
System.out.println("Testing complex transformations:");
|
||
|
|
|
||
|
|
// Test nested transformations
|
||
|
|
ModelPart root = model.getRootPart();
|
||
|
|
if (root != null) {
|
||
|
|
Vector2f position = root.getPosition();
|
||
|
|
Vector2f scale = root.getScale();
|
||
|
|
System.out.println("Root transformation:");
|
||
|
|
System.out.println(" - Local position: (" + position.x + ", " + position.y + ")");
|
||
|
|
System.out.println(" - Rotation: " + root.getRotation() + " degrees");
|
||
|
|
System.out.println(" - Scale: (" + scale.x + ", " + scale.y + ")");
|
||
|
|
|
||
|
|
// 获取世界变换矩阵中的位置
|
||
|
|
float worldX = root.getWorldTransform().m02();
|
||
|
|
float worldY = root.getWorldTransform().m12();
|
||
|
|
System.out.println(" - World position (from matrix): (" + worldX + ", " + worldY + ")");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test transformation inheritance
|
||
|
|
System.out.println("Transformation inheritance test:");
|
||
|
|
ModelPart head = model.getPart("head");
|
||
|
|
if (head != null) {
|
||
|
|
Vector2f headPos = head.getPosition();
|
||
|
|
float headWorldX = head.getWorldTransform().m02();
|
||
|
|
float headWorldY = head.getWorldTransform().m12();
|
||
|
|
System.out.println("Head transformation (relative to body):");
|
||
|
|
System.out.println(" - Local position: (" + headPos.x + ", " + headPos.y + ")");
|
||
|
|
System.out.println(" - World position (from matrix): (" + headWorldX + ", " + headWorldY + ")");
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test bounds calculation
|
||
|
|
BoundingBox bounds = model.getBounds();
|
||
|
|
if (bounds != null) {
|
||
|
|
System.out.println("Bounds calculation:");
|
||
|
|
System.out.println(" - Min: (" + bounds.getMinX() + ", " + bounds.getMinY() + ")");
|
||
|
|
System.out.println(" - Max: (" + bounds.getMaxX() + ", " + bounds.getMaxY() + ")");
|
||
|
|
System.out.println(" - Width: " + bounds.getWidth());
|
||
|
|
System.out.println(" - Height: " + bounds.getHeight());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test visibility system
|
||
|
|
System.out.println("Visibility system test:");
|
||
|
|
model.setVisible(false);
|
||
|
|
System.out.println(" - Model visible: " + model.isVisible());
|
||
|
|
model.setVisible(true);
|
||
|
|
System.out.println(" - Model visible: " + model.isVisible());
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testComplexTransformations: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test 7: Test performance with large model
|
||
|
|
*/
|
||
|
|
public static void testPerformance() {
|
||
|
|
System.out.println("\n--- Test 7: Performance Test ---");
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Create a more complex model for performance testing
|
||
|
|
Model2D complexModel = new Model2D("complex_character");
|
||
|
|
|
||
|
|
// Add many parts
|
||
|
|
ModelPart root = complexModel.createPart("root");
|
||
|
|
for (int i = 0; i < 10; i++) {
|
||
|
|
ModelPart part = complexModel.createPart("part_" + i);
|
||
|
|
root.addChild(part);
|
||
|
|
part.setPosition(i * 10, i * 5);
|
||
|
|
part.setRotation(i * 5);
|
||
|
|
|
||
|
|
// Add mesh
|
||
|
|
Mesh2D mesh = Mesh2D.createQuad("mesh_" + i, 20, 20);
|
||
|
|
complexModel.addMesh(mesh);
|
||
|
|
part.addMesh(mesh);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Add multiple parameters
|
||
|
|
for (int i = 0; i < 8; i++) {
|
||
|
|
complexModel.createParameter("param_" + i, 0, 1, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
System.out.println("Performance test with complex model:");
|
||
|
|
System.out.println(" - Parts: " + complexModel.getParts().size());
|
||
|
|
System.out.println(" - Parameters: " + complexModel.getParameters().size());
|
||
|
|
System.out.println(" - Meshes: " + complexModel.getMeshes().size());
|
||
|
|
|
||
|
|
// Performance test: multiple updates
|
||
|
|
long startTime = System.currentTimeMillis();
|
||
|
|
int frameCount = 100;
|
||
|
|
|
||
|
|
for (int i = 0; i < frameCount; i++) {
|
||
|
|
// Animate parameters
|
||
|
|
for (int j = 0; j < 8; j++) {
|
||
|
|
float value = (float) Math.sin(i * 0.1f + j * 0.5f) * 0.5f + 0.5f;
|
||
|
|
complexModel.setParameterValue("param_" + j, value);
|
||
|
|
}
|
||
|
|
complexModel.update(0.016f);
|
||
|
|
}
|
||
|
|
|
||
|
|
long endTime = System.currentTimeMillis();
|
||
|
|
long totalTime = endTime - startTime;
|
||
|
|
double avgTimePerFrame = (double) totalTime / frameCount;
|
||
|
|
|
||
|
|
System.out.println("Performance results:");
|
||
|
|
System.out.println(" - Total time for " + frameCount + " frames: " + totalTime + "ms");
|
||
|
|
System.out.println(" - Average time per frame: " + String.format("%.2f", avgTimePerFrame) + "ms");
|
||
|
|
System.out.println(" - Estimated FPS: " + String.format("%.1f", 1000.0 / avgTimePerFrame));
|
||
|
|
|
||
|
|
} catch (Exception e) {
|
||
|
|
System.err.println("Error in testPerformance: " + e.getMessage());
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Utility method to print part hierarchy
|
||
|
|
*/
|
||
|
|
private static void printPartHierarchy(ModelPart part, int depth) {
|
||
|
|
String indent = " ".repeat(depth);
|
||
|
|
System.out.println(indent + "- " + part.getName() +
|
||
|
|
" (children: " + part.getChildren().size() + ")");
|
||
|
|
|
||
|
|
for (ModelPart child : part.getChildren()) {
|
||
|
|
printPartHierarchy(child, depth + 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|