Fix WMO MOHD chunk parsing by adding missing nTextures field

The MOHD header structure was missing the nTextures field at the start,
causing all subsequent field reads to be offset by 4 bytes. This corrupted
bounding box values and caused floor geometry to be incorrectly culled.
This commit is contained in:
Kelsi 2026-02-03 11:46:12 -08:00
parent a9dd685398
commit 665a73e75f
2 changed files with 10 additions and 4 deletions

View file

@ -149,8 +149,9 @@ struct WMOGroup {
// Complete WMO Model
struct WMOModel {
// Root WMO data
// Root WMO data (from MOHD chunk)
uint32_t version;
uint32_t nTextures; // Added - was missing, caused offset issues
uint32_t nGroups;
uint32_t nPortals;
uint32_t nLights;

View file

@ -99,7 +99,8 @@ WMOModel WMOLoader::load(const std::vector<uint8_t>& wmoData) {
}
case MOHD: {
// Header
// Header - SMOHeader structure (WotLK 3.3.5a)
model.nTextures = read<uint32_t>(wmoData, offset); // Was missing!
model.nGroups = read<uint32_t>(wmoData, offset);
model.nPortals = read<uint32_t>(wmoData, offset);
model.nLights = read<uint32_t>(wmoData, offset);
@ -107,7 +108,7 @@ WMOModel WMOLoader::load(const std::vector<uint8_t>& wmoData) {
model.nDoodadDefs = read<uint32_t>(wmoData, offset);
model.nDoodadSets = read<uint32_t>(wmoData, offset);
[[maybe_unused]] uint32_t ambColor = read<uint32_t>(wmoData, offset); // Ambient color
[[maybe_unused]] uint32_t ambColor = read<uint32_t>(wmoData, offset); // Ambient color (BGRA)
[[maybe_unused]] uint32_t wmoID = read<uint32_t>(wmoData, offset);
model.boundingBoxMin.x = read<float>(wmoData, offset);
@ -118,7 +119,10 @@ WMOModel WMOLoader::load(const std::vector<uint8_t>& wmoData) {
model.boundingBoxMax.y = read<float>(wmoData, offset);
model.boundingBoxMax.z = read<float>(wmoData, offset);
core::Logger::getInstance().info("WMO groups: ", model.nGroups);
// flags and numLod (uint16 each) - skip for now
offset += 4;
core::Logger::getInstance().info("WMO header: nTextures=", model.nTextures, " nGroups=", model.nGroups);
break;
}
@ -452,6 +456,7 @@ bool WMOLoader::loadGroup(const std::vector<uint8_t>& groupData,
uint32_t vertexCount = subChunkSize / 12; // 3 floats per vertex
for (uint32_t i = 0; i < vertexCount; i++) {
WMOVertex vertex;
// Keep vertices in WoW model-local coords - coordinate swap done in model matrix
vertex.position.x = read<float>(groupData, mogpOffset);
vertex.position.y = read<float>(groupData, mogpOffset);
vertex.position.z = read<float>(groupData, mogpOffset);