refactor(render): make the walk sole production visibility owner
This commit is contained in:
parent
2a3ec09a98
commit
98d2d43fdc
1 changed files with 63 additions and 64 deletions
|
|
@ -165,70 +165,9 @@ public sealed class RetailPViewRenderer
|
||||||
RecycleLookInFrames();
|
RecycleLookInFrames();
|
||||||
ResetBuildingGroups();
|
ResetBuildingGroups();
|
||||||
|
|
||||||
var pvFrame = PortalVisibilityBuilder.Build(
|
// Campaign FW4 production cutover: decide the walk route before any
|
||||||
ctx.RootCell,
|
// old PView construction. A concrete production executor must have all
|
||||||
ctx.ViewerEyePos,
|
// walk registries; otherwise the frame is miswired and fails loud.
|
||||||
ctx.Cells.Find,
|
|
||||||
ctx.ViewProjection,
|
|
||||||
buildingMembership: null,
|
|
||||||
reuseFrame: _mainPortalFrameScratch);
|
|
||||||
|
|
||||||
// R-A2: outdoor root — flood each nearby building SEPARATELY from its own entrance and merge
|
|
||||||
// the small (~2-cell) per-building views into the frame. Retail reaches building interiors via
|
|
||||||
// the terrain BSP -> DrawPortal -> ConstructView(CBldPortal) (decomp:326881/433895/433827); the
|
|
||||||
// land root itself has no portals (it floods nothing into buildings). Per-building seeding is
|
|
||||||
// robust to the eye's ~36 µm rest jitter where the pre-R-A2 single reverse-portal flood
|
|
||||||
// oscillated as the chase eye grazed a doorway (the indoor flap).
|
|
||||||
if (ctx.RootCell.IsOutdoorNode && ctx.NearbyBuildingCells is not null)
|
|
||||||
MergeNearbyBuildingFloods(ctx, pvFrame);
|
|
||||||
|
|
||||||
// #124: interior-root building look-ins. Retail runs the look-in INSIDE
|
|
||||||
// the landscape stage for ANY root — LScape::draw is the FIRST call of
|
|
||||||
// DrawCells' outside-view branch (pc:432719), strictly BEFORE the depth
|
|
||||||
// clear (pc:432732) and the exit-portal seals (pc:432785); a far
|
|
||||||
// building seen through our doorway floods clipped to the INSTALLED
|
|
||||||
// outside view (GetClip vs current view, ConstructView(CBldPortal)
|
|
||||||
// 0x005a59a0). These frames therefore draw in DrawBuildingLookIns
|
|
||||||
// (inside the landscape stage), NEVER merged into the main frame — a
|
|
||||||
// merged cell would draw post-clear and z-fail against the root's seal
|
|
||||||
// (its geometry is beyond the door plane). The eye-side seed test
|
|
||||||
// self-excludes the root's own building (the eye is on its interior
|
|
||||||
// side). Outdoor roots keep the MergeNearbyBuildingFloods path above
|
|
||||||
// (no depth clear under outdoor roots — the merged form is equivalent
|
|
||||||
// there).
|
|
||||||
if (!ctx.RootCell.IsOutdoorNode
|
|
||||||
&& ctx.NearbyBuildingCells is not null
|
|
||||||
&& pvFrame.OutsideView.Polygons.Count > 0)
|
|
||||||
BuildInteriorRootLookIns(ctx, pvFrame);
|
|
||||||
|
|
||||||
var clipAssembly = passes.AssembleClipFrame(
|
|
||||||
pvFrame,
|
|
||||||
_clipAssemblyScratch);
|
|
||||||
passes.AppendLookInClipFrames(_lookInFrames, clipAssembly);
|
|
||||||
// FW4 slice 1: PrepareClipFrame (the one clip-region publication)
|
|
||||||
// moved BELOW the walk block — an interior-rooted walk frame
|
|
||||||
// re-derives the outside-view slices from the walk's own views
|
|
||||||
// first, so the appended slots join the same single publication.
|
|
||||||
|
|
||||||
// R1: draw EVERY visible cell (retail cell_draw_list), not only the cells the
|
|
||||||
// assembler handed a clip-slot. This feeds the Prepare filter + entity partition,
|
|
||||||
// so every visible cell's shell has a prepared batch and seals — killing the grey
|
|
||||||
// (the old clipAssembly.CellIdToSlot.Keys filter silently dropped slot-less cells).
|
|
||||||
// Per-slice trim still applies in DrawEnvCellShells (Task 4 makes it self-contained).
|
|
||||||
_drawableCellsScratch.Clear();
|
|
||||||
_drawableCellsScratch.UnionWith(pvFrame.OrderedVisibleCells);
|
|
||||||
var drawableCells = _drawableCellsScratch;
|
|
||||||
passes.UseIndoorMembershipOnlyRouting();
|
|
||||||
|
|
||||||
// Campaign FW3.2b-2: the production rooting. A concrete executor is
|
|
||||||
// required — the walk submits through WbDrawDispatcher.SubmitOrderedStream
|
|
||||||
// and needs a real GPU frame/encoder (RequireWalkSubmission), which no
|
|
||||||
// test IRetailPViewPassExecutor fake can supply. Whenever a concrete
|
|
||||||
// executor IS present, the retained render scene must ALSO be
|
|
||||||
// wired with all three walk registries — a scene product without the
|
|
||||||
// walk data (or vice versa) is a production miswiring, not a
|
|
||||||
// legacy/diagnostic shape, so it fails loud rather than silently
|
|
||||||
// falling back to the retired static routes (plan §FW3 item 6).
|
|
||||||
RetailPViewPassExecutor? walkExecutor = passes as RetailPViewPassExecutor;
|
RetailPViewPassExecutor? walkExecutor = passes as RetailPViewPassExecutor;
|
||||||
bool walkRegistriesReady =
|
bool walkRegistriesReady =
|
||||||
_walkBuildings is not null
|
_walkBuildings is not null
|
||||||
|
|
@ -252,6 +191,61 @@ public sealed class RetailPViewRenderer
|
||||||
&& _renderSceneShadow is not null
|
&& _renderSceneShadow is not null
|
||||||
&& walkRegistriesReady;
|
&& walkRegistriesReady;
|
||||||
|
|
||||||
|
PortalVisibilityFrame pvFrame;
|
||||||
|
if (walkActive)
|
||||||
|
{
|
||||||
|
// Compatibility carrier only. Production visibility is populated
|
||||||
|
// exclusively by RetailFrameWalk below; this frame supplies the
|
||||||
|
// clip assembler's outdoor full-screen seed until that remaining
|
||||||
|
// shell is deleted later in FW4.
|
||||||
|
pvFrame = _mainPortalFrameScratch;
|
||||||
|
pvFrame.ResetForBuild();
|
||||||
|
if (ctx.RootCell.IsOutdoorNode)
|
||||||
|
{
|
||||||
|
pvFrame.OutsideView.SetFullScreen();
|
||||||
|
pvFrame.OrderedVisibleCells.Add(ctx.RootCell.CellId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Standalone/fake executor compatibility. Production never calls
|
||||||
|
// PortalVisibilityBuilder after the FW4 cutover above.
|
||||||
|
pvFrame = PortalVisibilityBuilder.Build(
|
||||||
|
ctx.RootCell,
|
||||||
|
ctx.ViewerEyePos,
|
||||||
|
ctx.Cells.Find,
|
||||||
|
ctx.ViewProjection,
|
||||||
|
buildingMembership: null,
|
||||||
|
reuseFrame: _mainPortalFrameScratch);
|
||||||
|
|
||||||
|
if (ctx.RootCell.IsOutdoorNode && ctx.NearbyBuildingCells is not null)
|
||||||
|
MergeNearbyBuildingFloods(ctx, pvFrame);
|
||||||
|
if (!ctx.RootCell.IsOutdoorNode
|
||||||
|
&& ctx.NearbyBuildingCells is not null
|
||||||
|
&& pvFrame.OutsideView.Polygons.Count > 0)
|
||||||
|
BuildInteriorRootLookIns(ctx, pvFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
var clipAssembly = passes.AssembleClipFrame(
|
||||||
|
pvFrame,
|
||||||
|
_clipAssemblyScratch);
|
||||||
|
if (!walkActive)
|
||||||
|
passes.AppendLookInClipFrames(_lookInFrames, clipAssembly);
|
||||||
|
// FW4 slice 1: PrepareClipFrame (the one clip-region publication)
|
||||||
|
// moved BELOW the walk block — an interior-rooted walk frame
|
||||||
|
// re-derives the outside-view slices from the walk's own views
|
||||||
|
// first, so the appended slots join the same single publication.
|
||||||
|
|
||||||
|
// R1: draw EVERY visible cell (retail cell_draw_list), not only the cells the
|
||||||
|
// assembler handed a clip-slot. This feeds the Prepare filter + entity partition,
|
||||||
|
// so every visible cell's shell has a prepared batch and seals — killing the grey
|
||||||
|
// (the old clipAssembly.CellIdToSlot.Keys filter silently dropped slot-less cells).
|
||||||
|
// Per-slice trim still applies in DrawEnvCellShells (Task 4 makes it self-contained).
|
||||||
|
_drawableCellsScratch.Clear();
|
||||||
|
_drawableCellsScratch.UnionWith(pvFrame.OrderedVisibleCells);
|
||||||
|
var drawableCells = _drawableCellsScratch;
|
||||||
|
passes.UseIndoorMembershipOnlyRouting();
|
||||||
|
|
||||||
// Campaign FW3.4a: THE ONE WALK. Builds walkContext/walkLandscape/
|
// Campaign FW3.4a: THE ONE WALK. Builds walkContext/walkLandscape/
|
||||||
// walkCameraCell exactly as the pre-FW3.4a pre-walk collection pass
|
// walkCameraCell exactly as the pre-FW3.4a pre-walk collection pass
|
||||||
// did, then drives WalkFrameDriver.Collect — a SINGLE RetailFrameWalk
|
// did, then drives WalkFrameDriver.Collect — a SINGLE RetailFrameWalk
|
||||||
|
|
@ -382,6 +376,11 @@ public sealed class RetailPViewRenderer
|
||||||
viewportHeight);
|
viewportHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The walk's visited set replaces PortalVisibilityFrame's old
|
||||||
|
// OrderedVisibleCells side-channel for every production consumer.
|
||||||
|
_drawableCellsScratch.Clear();
|
||||||
|
_drawableCellsScratch.UnionWith(walkDriver.VisitedCells);
|
||||||
|
|
||||||
// Phase I cathedral instrumentation (synthesis §Phase I.3): the
|
// Phase I cathedral instrumentation (synthesis §Phase I.3): the
|
||||||
// continuous rooting line SEPARATES the true root flood
|
// continuous rooting line SEPARATES the true root flood
|
||||||
// (InteriorFloodCells) from the visited union (root + look-ins —
|
// (InteriorFloodCells) from the visited union (root + look-ins —
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue