feat(render) Campaign FW1: the degrade-level BSP gate kills the wrong punches
The offline degrade probe proved the mechanism: every Holtburg building carries PORT nodes ONLY in its level-0 GfxObj (out to ~24-48 m); every degraded level has zero. Retail walks the CURRENT degrade level BSP (part->gfxobj[deg_level]) - that is what limits look-in punches to the nearest buildings. WalkBuilding gains the degrade ladder + SelectDrawingBsp (band pick; UpdateViewerDistance hysteresis is a port TODO), the walk selects per viewer distance, the adapter builds per-level BSPs, and the stab-list load rule (CLandBlock::init_buildings @0052fd80: a full-res block loads exactly its buildings portal stab cells) replaces load-everything in the landscape builder. The sweep now shows clean rosters with all far-building punches gone; remaining deltas: the near buildings 001a/0022 (50 m/28 m center distance vs the 48 m band edge - sphere-adjusted distance/hysteresis to port) and the one ring-1 frustum boundary pair (aab50002/a9b3003c). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e5cdd2364e
commit
b3ac5872e9
8 changed files with 90 additions and 12 deletions
|
|
@ -108,9 +108,31 @@ public static class WalkLandscapeDatBuilder
|
|||
int cellIndex = (int)(entry.Building.PositionCellId & 0xFFFFu) - 1;
|
||||
if (cellIndex >= 0 && cellIndex < 64)
|
||||
block.CellBuildings[cellIndex] = entry.Building;
|
||||
|
||||
// Retail's loaded-interior rule (CLandBlock::init_buildings
|
||||
// @0052fd80 → add_to_stablist → grab_visible_cells): a
|
||||
// full-res block loads exactly its buildings' portal
|
||||
// stab cells — NOT every interior. The flood halts at
|
||||
// unloaded cells (GetVisible null), which is what
|
||||
// limits retail's look-in punches to nearby doorways.
|
||||
foreach (WalkBldPortal portal in entry.Building.Portals)
|
||||
{
|
||||
if (portal.OtherCellId != 0xFFFFFFFFu
|
||||
&& !cells.ContainsKey(portal.OtherCellId))
|
||||
{
|
||||
WalkCell? c = WalkWorldDatAdapter.BuildCell(
|
||||
dats, portal.OtherCellId, blockOffset);
|
||||
if (c is not null) cells[c.CellId] = c;
|
||||
}
|
||||
foreach (uint stab in portal.StabList)
|
||||
{
|
||||
if (cells.ContainsKey(stab)) continue;
|
||||
WalkCell? c = WalkWorldDatAdapter.BuildCell(
|
||||
dats, stab, blockOffset);
|
||||
if (c is not null) cells[c.CellId] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
WalkWorldDatAdapter.BuildInteriorCells(
|
||||
dats, landblockId, blockOffset, cells);
|
||||
}
|
||||
landscape.Blocks[gx * midWidth + gy] = block;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue