From a49b35e41bcfad47031da3c4469dea6963929c7b Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 02:37:10 -0700 Subject: [PATCH] fix(wob): aggregate unique materials across ALL groups in toWMOModel Previously only group[0]'s materials were emitted. Buildings with group-specific materials (e.g., the indoor groups using a different texture set than outdoor) lost those materials, leaving batches in later groups pointing to materialIndex out of range. Now dedupes by (texture, blend, flags) across every group. --- src/pipeline/wowee_building.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pipeline/wowee_building.cpp b/src/pipeline/wowee_building.cpp index e6f61e20..1dcafbf5 100644 --- a/src/pipeline/wowee_building.cpp +++ b/src/pipeline/wowee_building.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace wowee { namespace pipeline { @@ -224,8 +225,17 @@ bool WoweeBuildingLoader::toWMOModel(const WoweeBuilding& building, WMOModel& ou return static_cast(outModel.textures.size() - 1); }; - if (!building.groups.empty()) { - for (const auto& mat : building.groups[0].materials) { + // Collect unique materials across all groups. WMO has a single global + // materials array shared by every group's batches; pulling only from + // group[0] dropped per-group materials. Dedupe by (texture, blend, flags). + auto materialKey = [](const WoweeBuilding::Material& m) { + return m.texturePath + "|" + std::to_string(m.flags) + "|" + std::to_string(m.blendMode); + }; + std::unordered_map materialIndex; + for (const auto& grp : building.groups) { + for (const auto& mat : grp.materials) { + std::string key = materialKey(mat); + if (materialIndex.count(key)) continue; WMOMaterial wm{}; wm.flags = mat.flags; wm.shader = mat.shader; @@ -236,6 +246,7 @@ bool WoweeBuildingLoader::toWMOModel(const WoweeBuilding& building, WMOModel& ou wm.color2 = 0; wm.texture3 = 0; wm.color3 = 0; + materialIndex[key] = static_cast(outModel.materials.size()); outModel.materials.push_back(wm); } }