feat(render):优化模型渲染与局部变换矩阵计算

- 精简 updateLocalTransform 方法注释并调整代码格式
- 修正局部变换矩阵的构建方式,明确先缩放再旋转的顺序
- 添加 printWorldPosition 方法用于调试世界坐标
- 在 ModelRender 中引入 Vector2f 类(暂未使用)- 调整 renderPartRecursive 方法逻辑结构并增加世界坐标打印注释- 移除冗余空行,提升代码可读性
This commit is contained in:
tzdwindows 7
2025-10-08 12:30:37 +08:00
parent 3cf7f5883c
commit 173c30f277
2 changed files with 29 additions and 20 deletions

View File

@@ -5,6 +5,7 @@ import com.chuangzhou.vivid2D.render.model.ModelPart;
import com.chuangzhou.vivid2D.render.model.util.Mesh2D;
import com.chuangzhou.vivid2D.render.model.util.Texture;
import org.joml.Matrix3f;
import org.joml.Vector2f;
import org.joml.Vector4f;
import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryUtil;
@@ -301,27 +302,28 @@ public final class ModelRender {
}
private static void renderPartRecursive(ModelPart part, Matrix3f parentMat) {
// 使用 part 内置的局部矩阵localTransform并与 parentMat 相乘得到 world 矩阵
Matrix3f local = part.getLocalTransform(); // 返回 copy
Matrix3f local = part.getLocalTransform(); // 局部矩阵
Matrix3f world = new Matrix3f(parentMat).mul(local); // world = parent * local
// world 矩阵传入 shader使用 3x3
setUniformMatrix3(defaultProgram, "uModelMatrix", world);
// world 矩阵取世界坐标
//float worldX = world.m02;
//float worldY = world.m12;
//System.out.println("Rendering part: " + part.getName() + " at world position: " + worldX + ", " + worldY);
// 设置部件相关 uniformopacity / blend / color
// 传入 shader
setUniformMatrix3(defaultProgram, "uModelMatrix", world);
setPartUniforms(defaultProgram, part);
// 绘制该部件的所有网格(使用 ModelRender 的 renderMesh
for (Mesh2D mesh : part.getMeshes()) {
renderMesh(mesh);
}
// 递归绘制子节点(传入当前 world 矩阵)
for (ModelPart child : part.getChildren()) {
renderPartRecursive(child, world);
}
}
private static void renderMesh(Mesh2D mesh) {
// 确保 mesh 的 GL 资源已上传ModelRender 管理 upload
MeshGLResources res = meshResources.computeIfAbsent(mesh, k -> new MeshGLResources());

View File

@@ -169,29 +169,36 @@ public class ModelPart {
transformDirty = false;
}
/**
* 更新局部变换矩阵
*/
// 更新局部矩阵
private void updateLocalTransform() {
float cos = (float)Math.cos(rotation);
float sin = (float)Math.sin(rotation);
// 正确的 R * S 组合(先 scale 再 rotate最终矩阵为 Translate * (Rotate * Scale)
float m00 = cos * scale.x; // = cos * sx
float m01 = -sin * scale.y; // = -sin * sy
float m02 = position.x; // tx
float m00 = cos * scale.x;
float m01 = -sin * scale.y;
float m10 = sin * scale.x;
float m11 = cos * scale.y;
float m10 = sin * scale.x; // = sin * sx
float m11 = cos * scale.y; // = cos * sy
float m12 = position.y; // ty
float m02 = position.x; // 平移直接用 position
float m12 = position.y;
localTransform.set(
m00, m01, m02,
m10, m11, m12,
0.0f, 0.0f, 1.0f
0f, 0f, 1f
);
}
// 打印世界坐标
public void printWorldPosition() {
float worldX = localTransform.m02;
float worldY = localTransform.m12;
System.out.println("World position: " + worldX + ", " + worldY);
}
/**
* 标记变换需要更新
*/