fix(render): Phase A8 RR7.2 — _buildingRegistries key mismatch
RR7.1 fixed cell-timing but the indoor branch STILL fired 0 times in the v2 visual gate (125,476 inside=True frames, all routed outdoor). Real root cause: a key-form mismatch between storage and lookup. Storage at line ~5886 used `_buildingRegistries[lb.LandblockId]`. But lb.LandblockId is the LandBlock dat-file id (e.g. 0xA9B4FFFF — the 0xFFFF low word identifies the file as terrain). Lookups at the gate (line ~7090) and the drain late-stamp (line ~5708) used `cell.CellId & 0xFFFF0000u` (e.g. 0xA9B40000). 0xA9B4FFFF ≠ 0xA9B40000 so TryGetValue always missed; camBuildings stayed empty; the gate fell to the outdoor branch unconditionally. Fix: normalize all four sites to the masked form (`& 0xFFFF0000u`) — storage at the build call, both Remove callbacks in the streaming-controller setup, and the lookups (already correct). User-visible symptom that surfaced the v2 launch: - sky + ground missing through windows - buildings + objects still visible This pattern (stencil-gated outdoor passes failing while ungated indoor pass works) was actually the OUTDOOR branch running with the indoor visibility set — `visibleCellIds` filtered out terrain cells and the sky pre-scene was gated off too because cameraInsideBuilding was True (correctly) but camBuildings was empty (incorrectly). Wait — re-reading the indoor branch's gate: it requires camBuildings.Count > 0 too, so with the key mismatch it took the outdoor branch. The sky+terrain visibility pattern user reported is the outdoor branch where sky-pre-scene was correctly gated off by !cameraInsideBuilding (cameraInsideBuilding is what computes the ROUTING; it doesn't have to match the actual branch taken when the extra `camBuildings.Count > 0` filter trips). So initial-sky was skipped (cameraInsideBuilding=true) but indoor branch didn't fire either — outdoor branch with no initial sky = the dark window visual. RR7.2 closes both. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a1a3e0ee3e
commit
efe35201fc
1 changed files with 14 additions and 4 deletions
|
|
@ -1863,7 +1863,7 @@ public sealed class GameWindow : IDisposable
|
||||||
_terrain?.RemoveLandblock(id);
|
_terrain?.RemoveLandblock(id);
|
||||||
_physicsEngine.RemoveLandblock(id);
|
_physicsEngine.RemoveLandblock(id);
|
||||||
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
|
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
|
||||||
_buildingRegistries.Remove(id); // Phase A8
|
_buildingRegistries.Remove(id & 0xFFFF0000u); // Phase A8 RR7.2: masked key matches storage
|
||||||
});
|
});
|
||||||
// A.5 T22.5: apply max-completions from resolved quality.
|
// A.5 T22.5: apply max-completions from resolved quality.
|
||||||
_streamingController.MaxCompletionsPerFrame = _resolvedQuality.MaxCompletionsPerFrame;
|
_streamingController.MaxCompletionsPerFrame = _resolvedQuality.MaxCompletionsPerFrame;
|
||||||
|
|
@ -5872,7 +5872,7 @@ public sealed class GameWindow : IDisposable
|
||||||
_physicsEngine.AddLandblock(lb.LandblockId, terrainSurface, cellSurfaces,
|
_physicsEngine.AddLandblock(lb.LandblockId, terrainSurface, cellSurfaces,
|
||||||
portalPlanes, origin.X, origin.Y);
|
portalPlanes, origin.X, origin.Y);
|
||||||
|
|
||||||
// Phase A8 (2026-05-26, fixed 2026-05-27 RR7.1): build per-landblock
|
// Phase A8 (2026-05-26, fixed 2026-05-27 RR7.2): build per-landblock
|
||||||
// BuildingRegistry from LandBlockInfo.Buildings, stamping
|
// BuildingRegistry from LandBlockInfo.Buildings, stamping
|
||||||
// LoadedCell.BuildingId for each cell in a building's cell set.
|
// LoadedCell.BuildingId for each cell in a building's cell set.
|
||||||
// Uses _cellVisibility.AllLoadedCells (every cell loaded so far,
|
// Uses _cellVisibility.AllLoadedCells (every cell loaded so far,
|
||||||
|
|
@ -5881,9 +5881,19 @@ public sealed class GameWindow : IDisposable
|
||||||
// pass get stamped at drain time (see _pendingCells loop above).
|
// pass get stamped at drain time (see _pendingCells loop above).
|
||||||
// Cells without a building stay at BuildingId == null (outdoor
|
// Cells without a building stay at BuildingId == null (outdoor
|
||||||
// surface cells; dungeon cells not in LandBlockInfo.Buildings).
|
// surface cells; dungeon cells not in LandBlockInfo.Buildings).
|
||||||
|
//
|
||||||
|
// KEY NORMALIZATION (RR7.2): lb.LandblockId is the LandBlock file
|
||||||
|
// id (e.g. 0xA9B4FFFF — the 0xFFFF low word is the dat-file
|
||||||
|
// discriminator), but cell ids like 0xA9B40150 mask to
|
||||||
|
// 0xA9B40000. All lookups (drain late-stamp at line ~5708, gate
|
||||||
|
// check at line ~7090) use `& 0xFFFF0000u`, so storage MUST use
|
||||||
|
// the same masked form or every lookup misses — which silently
|
||||||
|
// routed every indoor frame through the outdoor branch in the
|
||||||
|
// RR7.1 launch.
|
||||||
if (lbInfo is not null)
|
if (lbInfo is not null)
|
||||||
{
|
{
|
||||||
_buildingRegistries[lb.LandblockId] =
|
uint lbRegistryKey = lb.LandblockId & 0xFFFF0000u;
|
||||||
|
_buildingRegistries[lbRegistryKey] =
|
||||||
AcDream.App.Rendering.Wb.BuildingLoader.Build(
|
AcDream.App.Rendering.Wb.BuildingLoader.Build(
|
||||||
lbInfo, lb.LandblockId, _cellVisibility.AllLoadedCells);
|
lbInfo, lb.LandblockId, _cellVisibility.AllLoadedCells);
|
||||||
}
|
}
|
||||||
|
|
@ -9083,7 +9093,7 @@ public sealed class GameWindow : IDisposable
|
||||||
_terrain?.RemoveLandblock(id);
|
_terrain?.RemoveLandblock(id);
|
||||||
_physicsEngine.RemoveLandblock(id);
|
_physicsEngine.RemoveLandblock(id);
|
||||||
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
|
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
|
||||||
_buildingRegistries.Remove(id); // Phase A8
|
_buildingRegistries.Remove(id & 0xFFFF0000u); // Phase A8 RR7.2: masked key
|
||||||
});
|
});
|
||||||
_streamingController.MaxCompletionsPerFrame = newResolved.MaxCompletionsPerFrame;
|
_streamingController.MaxCompletionsPerFrame = newResolved.MaxCompletionsPerFrame;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue