fix(renderer): mesh collider source positions in render space for skinned meshes

Skinned meshes keep vertices in raw mesh space (bakeTransform=false);
rendering transforms them via bind palette (global(bone) x invBind, folds
FBX unit scale). Physics MeshShape/ConvexHull and the mesh bounding sphere
consumed the raw positions directly -> M1911 hull measured ~10x the visual
size. ParseFromDisk now bakes bind-palette-skinned positions per vertex
(same formula as the skinning shader) into ParsedMesh::cpuPositions; Mesh
uses them for m_CpuPositions and bounds. GPU vertex data and rendering are
untouched.
This commit is contained in:
2026-10-03 17:43:55 +08:00
parent e1cef53158
commit d5a86c170e
4 changed files with 70 additions and 11 deletions
+4 -1
View File
@@ -28,10 +28,13 @@ namespace Engine
public:
// material 非拥有指针:Model 的材质缓存拥有(同贴图共享一份)
// lods[0] 必须为原始索引(与 vertices 对应),各级简化链由解析期生成
// cpuPositions 非空(蒙皮 mesh)= 物理数据源与包围球改用它
//(绑定姿态渲染空间,与视觉同源;vertices.position 是蒙皮原始空间)
Mesh(Device& device, MemoryAllocator& allocator,
const std::vector<Vertex>& vertices,
const std::vector<std::vector<u32>>& lods,
Material* material);
Material* material,
const std::vector<glm::vec3>* cpuPositions = nullptr);
~Mesh();
Mesh(const Mesh&) = delete;
+7
View File
@@ -42,6 +42,13 @@ namespace Engine
std::array<std::string, Material::kSlotCount> texPaths;
MaterialParams params;
bool transparent = false; // glTF alphaMode=BLEND(透明绘制队列)
bool skinned = false; // 有骨骼(渲染走 palette 蒙皮)
// 蒙皮 mesh 专属:绑定姿态渲染空间的位置副本(palette(bind) 按
// 顶点权重混合,与 shader 同式)。非空 = Mesh 的物理数据源与
// 包围球改用它——FBX 单位换算折在骨骼链上(bind palette ≠ I),
// 直接用原始顶点会让物理凸包大一个数量级(M1911 实测 10×)
std::vector<glm::vec3> cpuPositions;
};
// ---- 骨骼动画数据(assimp aiNode/aiAnimation/aiBone 的引擎侧镜像)----