fix: WOM2 bone data in client renderer, WOM tests, docs update

- Fix WOM→M2Model conversion: copy boneWeights/boneIndices from WOM2
  vertices (was dropping skeletal binding data, breaking animation)
- Copy bone hierarchy and animation sequences from WOM2 to M2Model
  so animated WOM2 models render with proper skeletal deformation
- Add 3 WOM format tests: WOM1 binary structure, WOM2 magic check,
  invalid magic rejection (6 new assertions)
- CHANGELOG: document WOM1/WOM2 animated model support
- README: clarify WOM1 (static) vs WOM2 (animated) models
- 334 total assertions across 87 test cases
This commit is contained in:
Kelsi 2026-05-05 16:23:22 -07:00
parent f6dfc295ab
commit b439f12c36
4 changed files with 92 additions and 2 deletions

View file

@ -503,6 +503,8 @@ std::shared_ptr<PendingTile> TerrainManager::prepareTile(int x, int y) {
mv.position = v.position;
mv.normal = v.normal;
mv.texCoords[0] = v.texCoord;
std::memcpy(mv.boneWeights, v.boneWeights, 4);
std::memcpy(mv.boneIndices, v.boneIndices, 4);
m2Model.vertices.push_back(mv);
}
m2Model.indices.reserve(wom.indices.size());
@ -537,6 +539,25 @@ std::shared_ptr<PendingTile> TerrainManager::prepareTile(int x, int y) {
mat.blendMode = 0;
m2Model.materials.push_back(mat);
// Copy bone hierarchy from WOM2
for (const auto& wb : wom.bones) {
pipeline::M2Bone bone;
bone.keyBoneId = wb.keyBoneId;
bone.parentBone = wb.parentBone;
bone.pivot = wb.pivot;
bone.flags = wb.flags;
m2Model.bones.push_back(bone);
}
// Copy animation sequences from WOM2
for (const auto& wa : wom.animations) {
pipeline::M2Sequence seq;
seq.id = wa.id;
seq.duration = wa.durationMs;
seq.movingSpeed = wa.movingSpeed;
m2Model.sequences.push_back(seq);
}
pending->m2Models.push_back({modelId, std::move(m2Model), {}});
preparedModelIds.insert(modelId);
LOG_INFO("Loaded WOM model: ", womPath);