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>
31 lines
1.7 KiB
C#
31 lines
1.7 KiB
C#
using System.Numerics;
|
|
|
|
namespace AcDream.App.Rendering;
|
|
|
|
/// <summary>
|
|
/// Factory for the OUTDOOR render root — the cell the render roots at when the camera eye is outdoors.
|
|
/// Retail roots every in-world frame at <c>viewer_cell</c> (SmartBox::RenderNormalMode →
|
|
/// DrawInside(viewer_cell), decomp:92635); when outdoors that is a <c>CLandCell</c>. acdream models it
|
|
/// as a portal-less <see cref="LoadedCell"/> carrying only <see cref="LoadedCell.IsOutdoorNode"/> (so
|
|
/// <see cref="PortalVisibilityBuilder.Build"/> seeds OutsideView FULL-SCREEN → terrain/sky/scenery draw
|
|
/// as the root's shell) and <see cref="LoadedCell.SeenOutside"/>.
|
|
///
|
|
/// <para>R-A2 (2026-06-08): the node no longer carries reverse portals into nearby buildings. Retail
|
|
/// does NOT flood buildings from the land root — buildings flood SEPARATELY, per-building, during the
|
|
/// landscape draw (terrain BSP → DrawPortal → ConstructView(CBldPortal), decomp:326881/433895/433827).
|
|
/// acdream issues those via <see cref="PortalVisibilityBuilder.ConstructViewBuilding"/> per nearby
|
|
/// building inside <see cref="RetailPViewRenderer.DrawInside"/>. The pre-R-A2 design flooded all
|
|
/// buildings from one root through reverse portals, coupling their interior membership to a single
|
|
/// root-level portal-side test that oscillated as the chase eye grazed a doorway — the indoor flap.</para>
|
|
/// </summary>
|
|
public static class OutdoorCellNode
|
|
{
|
|
public static LoadedCell Build(uint outdoorCellId) => new LoadedCell
|
|
{
|
|
CellId = outdoorCellId,
|
|
SeenOutside = true,
|
|
IsOutdoorNode = true,
|
|
WorldTransform = Matrix4x4.Identity,
|
|
InverseWorldTransform = Matrix4x4.Identity,
|
|
};
|
|
}
|