fix(wob): sanitize doodad transform during fromWMO conversion

A WMO with a NaN doodad quaternion would produce NaN euler angles
through glm::eulerAngles() and persist them into the WoB. Identity
quaternion fallback for a non-finite source, plus NaN scrub on
position/rotation/scale separately so the converted WOB is always
load-safe.
This commit is contained in:
Kelsi 2026-05-06 07:13:49 -07:00
parent 5af4bba556
commit d1f347a9c1

View file

@ -519,11 +519,21 @@ WoweeBuilding WoweeBuildingLoader::fromWMO(const WMOModel& wmo, const std::strin
if (dot != std::string::npos)
dp.modelPath = dp.modelPath.substr(0, dot) + ".wom";
dp.position = doodad.position;
// Convert quaternion rotation to euler angles
// Sanitize position before euler conversion. NaN in the source
// quaternion would propagate to NaN euler angles and ruin the
// doodad transform forever after; same for the position floats.
for (int k = 0; k < 3; k++)
if (!std::isfinite(dp.position[k])) dp.position[k] = 0.0f;
glm::quat q(doodad.rotation.w, doodad.rotation.x,
doodad.rotation.y, doodad.rotation.z);
if (!std::isfinite(q.w) || !std::isfinite(q.x) ||
!std::isfinite(q.y) || !std::isfinite(q.z))
q = glm::quat(1.0f, 0.0f, 0.0f, 0.0f); // identity
dp.rotation = glm::degrees(glm::eulerAngles(q));
dp.scale = doodad.scale;
for (int k = 0; k < 3; k++)
if (!std::isfinite(dp.rotation[k])) dp.rotation[k] = 0.0f;
dp.scale = (std::isfinite(doodad.scale) && doodad.scale > 0.0001f)
? doodad.scale : 1.0f;
bld.doodads.push_back(dp);
}