Fix WMO instance duplication causing 16x Stormwind rendering

Added deduplication for WMO instances based on uniqueId, matching the
existing M2 doodad deduplication logic. This prevents creating multiple
instances of the same WMO when it's referenced from multiple ADT tiles.

Before: STORMWIND.WMO (uniqueId=10047) was being rendered 16 times
        (one instance per ADT tile that references it)
After:  Only 1 instance is created and shared across all tiles

Changes:
- Added placedWmoIds set to TerrainManager (like placedDoodadIds)
- Check uniqueId before creating WMO instance
- Skip duplicate WMO placements across tile boundaries
- Log dedup statistics: 'X instances, Y dedup skipped'

This should fix the floating cathedral visual issue if it was caused by
rendering artifacts from 16x overdraw, and will massively improve
performance in Stormwind.
This commit is contained in:
Kelsi 2026-02-09 18:38:45 -08:00
parent 8788ab57ec
commit 7ffb5f1de1
2 changed files with 16 additions and 0 deletions

View file

@ -323,6 +323,9 @@ private:
// Dedup set for doodad placements across tile boundaries
std::unordered_set<uint32_t> placedDoodadIds;
// Dedup set for WMO placements across tile boundaries (prevents rendering Stormwind 16x)
std::unordered_set<uint32_t> placedWmoIds;
};
} // namespace rendering

View file

@ -683,11 +683,20 @@ void TerrainManager::finalizeTile(const std::shared_ptr<PendingTile>& pending) {
int loadedWMOs = 0;
int loadedLiquids = 0;
int skippedWmoDedup = 0;
for (auto& wmoReady : pending->wmoModels) {
// Deduplicate WMO instances by uniqueId (prevents Stormwind from rendering 16x)
// uniqueId is stored in modelId field (see line 522 in prepareTile)
if (placedWmoIds.count(wmoReady.modelId)) {
skippedWmoDedup++;
continue;
}
if (wmoRenderer->loadModel(wmoReady.model, wmoReady.modelId)) {
uint32_t wmoInstId = wmoRenderer->createInstance(wmoReady.modelId, wmoReady.position, wmoReady.rotation);
if (wmoInstId) {
wmoInstanceIds.push_back(wmoInstId);
placedWmoIds.insert(wmoReady.modelId);
loadedWMOs++;
// Load WMO liquids (canals, pools, etc.)
@ -710,6 +719,10 @@ void TerrainManager::finalizeTile(const std::shared_ptr<PendingTile>& pending) {
}
}
}
if (loadedWMOs > 0 || skippedWmoDedup > 0) {
LOG_INFO(" Loaded WMOs for tile [", x, ",", y, "]: ",
loadedWMOs, " instances, ", skippedWmoDedup, " dedup skipped");
}
if (loadedLiquids > 0) {
LOG_DEBUG(" Loaded WMO liquids for tile [", x, ",", y, "]: ", loadedLiquids);
}