feat(render): Phase 3 (Step A) — outdoor-root seeds full-screen OutsideView

Render unification cutover, Step A (additive, behavior-neutral until Step B). When PortalVisibilityBuilder.Build roots at the synthetic outdoor node, seed OutsideView with the full-screen NDC quad so ClipFrameAssembler yields a full-screen OutsideView slice and DrawInside's DrawLandscapeThroughOutsideView draws terrain/sky/scenery/weather as the node's shell — the same callback that already draws the doorway slice for an interior root looking out.

Keyed on a new explicit LoadedCell.IsOutdoorNode flag (set by OutdoorCellNode.Build), NOT a cell-id heuristic: production EnvCell ids are >= 0x100 but test fixtures use low interior ids, so an id test misfired on 4 existing PortalVisibilityBuilderTests.

Nothing roots at the node until Step B, so this is behavior-neutral. Tests: App 216/0 (2 new UnifiedFloodTests incl. the spec section 10 pure-outdoor regression guard + 2 OutdoorCellNode flag assertions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-07 19:06:13 +02:00
parent 9bc0db9351
commit 5379f6ecd3
5 changed files with 71 additions and 0 deletions

View file

@ -104,6 +104,16 @@ public sealed class LoadedCell
/// grab_visible_cells decomp:311878). The stable anchor for the terrain-draw test.
/// </summary>
public bool SeenOutside;
/// <summary>
/// Render unification (2026-06-07): true for the synthetic OUTDOOR cell node built by
/// <see cref="OutdoorCellNode.Build"/> — the outdoor world modelled as a flood-graph cell whose
/// shell is the landscape. <see cref="PortalVisibilityBuilder.Build"/> seeds OutsideView
/// full-screen when the root carries this flag (so terrain/sky/scenery draw as the node's shell).
/// An explicit flag, not a cell-id heuristic: interior EnvCell ids are >= 0x100 in production but
/// test fixtures use low ids for interior cells, so keying on the id would misfire.
/// </summary>
public bool IsOutdoorNode;
}
/// <summary>