diff --git a/src/pipeline/wowee_model.cpp b/src/pipeline/wowee_model.cpp index 15ac0d16..391bb625 100644 --- a/src/pipeline/wowee_model.cpp +++ b/src/pipeline/wowee_model.cpp @@ -109,6 +109,18 @@ WoweeModel WoweeModelLoader::load(const std::string& basePath) { f.read(reinterpret_cast(&bone.parentBone), 2); f.read(reinterpret_cast(&bone.pivot), 12); f.read(reinterpret_cast(&bone.flags), 4); + // Sanitize pivot — bones with NaN pivots produce broken + // skeleton matrices that ripple into every child bone. + if (!std::isfinite(bone.pivot.x)) bone.pivot.x = 0.0f; + if (!std::isfinite(bone.pivot.y)) bone.pivot.y = 0.0f; + if (!std::isfinite(bone.pivot.z)) bone.pivot.z = 0.0f; + // parentBone must be < boneCount (or -1) — out-of-range + // parents would cause a use-after-free during bone-matrix + // computation that walks the parent chain. + if (bone.parentBone >= 0 && + static_cast(bone.parentBone) >= boneCount) { + bone.parentBone = -1; + } } }