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 c7d9a6d511
commit 411ee8b485
2 changed files with 16 additions and 0 deletions

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);
}