feat(render): R-A2 — per-building floods (the flap fix)
Replace the outdoor root's single unified reverse-portal flood (whose root-level portal-side test oscillated as the chase eye grazed a doorway — the measured flood 2<->6) with retail's per-building floods. - OutdoorCellNode.Build(uint): portal-less land root; floods only itself -> full-screen OutsideView -> terrain (PortalVisibilityBuilder IsOutdoorNode seed). - PortalVisibilityBuilder.ConstructViewBuilding: per-building flood seeded at a building's own finite entrance (retail ConstructView(CBldPortal) 0x5a59a0 via DrawPortal 0x5a5ab0 / portal_draw_portals_only 0x53d870). Entrance-bounded -> consistent ~2-cell depth (measured retail cell_draw_num, handoff OPTION-A 3.4). - RetailPViewRenderer.DrawInside: when the root is the outdoor node, group nearby cells by BuildingId and merge each per-building flood into the frame before assembly; existing shells/object-list draw path unchanged. 48 m seed cutoff. - GameWindow: pass flat NearbyBuildingCells only on outdoor-node frames. Tests: +3 PortalVisibilityRobustnessTests (per-building touches ~2 cells, membership stable under the measured 36 um eye jitter). UnifiedFloodTests retired (its subject, the unified flood from the outdoor node, is removed); surviving full-screen-OutsideView coverage moved to OutdoorCellNodeTests. App Rendering 207/207, Core movement 14/14. Conformance-verified sound; the grazing-doorway flap is the visual acceptance test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7fe98098f5
commit
c62663d7cb
8 changed files with 251 additions and 198 deletions
|
|
@ -517,6 +517,25 @@ public static class PortalVisibilityBuilder
|
|||
return frame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retail per-building flood — <c>PView::ConstructView(CBldPortal*, …)</c> (decomp:433827),
|
||||
/// reached from <c>BSPPORTAL::portal_draw_portals_only</c> (0x53d870) → <c>DrawPortal</c>
|
||||
/// (0x5a5ab0) during the terrain BSP walk. Floods ONE building's cells from its outside-facing
|
||||
/// entrance portal(s). Identical machinery to <see cref="BuildFromExterior"/>, but the CONTRACT is
|
||||
/// per-building: the caller passes exactly one building's cells, so the seed is that building's
|
||||
/// FINITE entrance opening (bounded flood depth → the stable ~2-cell view retail draws per visible
|
||||
/// building, measured live §3.4). This differs from the synthetic outdoor node's single unified
|
||||
/// flood whose full-screen-ish seed reaches variable depth into a building as the eye moves — the
|
||||
/// 2↔6 oscillation. Robustness is validated by the conformance test, not assumed.
|
||||
/// </summary>
|
||||
public static PortalVisibilityFrame ConstructViewBuilding(
|
||||
IEnumerable<LoadedCell> buildingCells,
|
||||
Vector3 cameraPos,
|
||||
Func<uint, LoadedCell?> lookup,
|
||||
Matrix4x4 viewProj,
|
||||
float maxSeedDistance = float.PositiveInfinity)
|
||||
=> BuildFromExterior(buildingCells, cameraPos, lookup, viewProj, maxSeedDistance);
|
||||
|
||||
// The NDC [-1,1] viewport quad (CCW), reused by the flap probe's clip recompute.
|
||||
private static readonly Vector2[] FullScreenQuad =
|
||||
{ new Vector2(-1f, -1f), new Vector2(1f, -1f), new Vector2(1f, 1f), new Vector2(-1f, 1f) };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue