T4 (BR-6): ONE visibility gate - ACME BFS deleted from the frame, legacy second render path deleted
The one-gate rule (feedback_render_one_gate) is now structural: - The per-frame ACME BFS (CellVisibility.ComputeVisibilityFromRoot) is GONE from the frame. Its only production consumer was the cameraInsideCell boolean - which is exactly 'viewerRoot is not null' (the TryGetCell that produced viewerRoot already proves cells are loaded; ComputeVisibilityFromRoot returned null iff root was null). A full second visibility computation ran every frame to derive a boolean we already had. The method + its tests remain as quarantined non-production code (dual-live-visibility-computations, confirmed). - The clipRoot==null mini-pipeline is DELETED (legacy-outdoor-branch- remnant, adjusted-confirmed): the outdoor partition draw, the Chebyshev look-in gather, the DrawPortal invocation and the dynamics fallback. clipRoot is null only when NO viewer cell exists (pre-login, fly/debug cameras, transient gaps) - those frames draw flat through the dispatcher; every normal outdoor frame is the outdoor node. - DELETED with it: InteriorRenderer (class file - its only caller was the legacy branch), RetailPViewRenderer.DrawPortal + RetailPViewPortalDrawContext (the look-in product; outdoor-root frames flood buildings via MergeNearbyBuildingFloods inside DrawInside), the _exteriorPortal*/_outdoorRootNoCells fields. Per frame there is now exactly ONE visibility computation (PortalVisibilityBuilder) and ONE render path (DrawInside). Suites: build green, App 226 green, Core baseline (1398 + 4 pre-existing #99-era). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a6aec8c32f
commit
4a307d33b5
3 changed files with 20 additions and 360 deletions
|
|
@ -186,62 +186,6 @@ public sealed class RetailPViewRenderer
|
|||
}
|
||||
}
|
||||
|
||||
public RetailPViewFrameResult? DrawPortal(RetailPViewPortalDrawContext ctx)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ctx);
|
||||
|
||||
var pvFrame = PortalVisibilityBuilder.BuildFromExterior(
|
||||
ctx.CandidateCells,
|
||||
ctx.ViewerEyePos,
|
||||
ctx.CellLookup,
|
||||
ctx.ViewProjection,
|
||||
ctx.MaxSeedDistance);
|
||||
|
||||
if (pvFrame.OrderedVisibleCells.Count == 0)
|
||||
{
|
||||
RestoreNoClip(ctx.SetTerrainClipUbo);
|
||||
return null;
|
||||
}
|
||||
|
||||
var clipAssembly = ClipFrameAssembler.Assemble(_clipFrame, pvFrame);
|
||||
UploadClipFrame(ctx.SetTerrainClipUbo);
|
||||
|
||||
var drawableCells = new HashSet<uint>(clipAssembly.CellIdToSlot.Keys);
|
||||
UseIndoorMembershipOnlyRouting();
|
||||
|
||||
_envCells.PrepareRenderBatches(
|
||||
ctx.ViewProjection,
|
||||
ctx.CameraWorldPosition,
|
||||
filter: drawableCells,
|
||||
centerLbX: ctx.RenderCenterLbX,
|
||||
centerLbY: ctx.RenderCenterLbY,
|
||||
renderRadius: ctx.RenderRadius);
|
||||
|
||||
var partition = InteriorEntityPartition.Partition(drawableCells, ctx.LandblockEntries);
|
||||
var result = new RetailPViewFrameResult
|
||||
{
|
||||
PortalFrame = pvFrame,
|
||||
ClipAssembly = clipAssembly,
|
||||
DrawableCells = drawableCells,
|
||||
Partition = partition,
|
||||
};
|
||||
|
||||
ctx.EmitDiagnostics?.Invoke(result);
|
||||
|
||||
// T1: look-in order — punch the apertures, then interior cells WHOLE,
|
||||
// then the looked-into building's per-cell statics. Dynamics are NOT
|
||||
// drawn here: they belong exclusively to the frame's single last
|
||||
// entity pass (the outdoor root's DrawDynamicsLast), which prevents
|
||||
// double-draws of entities inside looked-into buildings.
|
||||
var viewcone = ViewconeCuller.Build(clipAssembly, ctx.ViewProjection);
|
||||
DrawExitPortalMasks(ctx, pvFrame, clipAssembly, drawableCells);
|
||||
DrawEnvCellShells(pvFrame);
|
||||
DrawCellObjectLists(ctx, pvFrame, clipAssembly, drawableCells, partition, viewcone);
|
||||
RestoreNoClip(ctx.SetTerrainClipUbo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void DrawLandscapeThroughOutsideView(
|
||||
RetailPViewDrawContext ctx,
|
||||
ClipFrameAssembly clipAssembly,
|
||||
|
|
@ -644,30 +588,6 @@ public sealed class RetailPViewDrawContext : IRetailPViewCellDrawContext
|
|||
public Action<RetailPViewFrameResult>? EmitDiagnostics { get; init; }
|
||||
}
|
||||
|
||||
public sealed class RetailPViewPortalDrawContext : IRetailPViewCellDrawContext
|
||||
{
|
||||
public required IEnumerable<LoadedCell> CandidateCells { get; init; }
|
||||
public required Vector3 ViewerEyePos { get; init; }
|
||||
public required Matrix4x4 ViewProjection { get; init; }
|
||||
public required Func<uint, LoadedCell?> CellLookup { get; init; }
|
||||
public required ICamera Camera { get; init; }
|
||||
public required Vector3 CameraWorldPosition { get; init; }
|
||||
public required FrustumPlanes? Frustum { get; init; }
|
||||
public required uint? PlayerLandblockId { get; init; }
|
||||
public required HashSet<uint>? AnimatedEntityIds { get; init; }
|
||||
public required int RenderCenterLbX { get; init; }
|
||||
public required int RenderCenterLbY { get; init; }
|
||||
public required int RenderRadius { get; init; }
|
||||
public required float MaxSeedDistance { get; init; }
|
||||
public required IEnumerable<(uint LandblockId, Vector3 AabbMin, Vector3 AabbMax,
|
||||
IReadOnlyList<WorldEntity> Entities,
|
||||
IReadOnlyDictionary<uint, WorldEntity>? AnimatedById)> LandblockEntries { get; init; }
|
||||
public required Action<uint> SetTerrainClipUbo { get; init; }
|
||||
public Action<RetailPViewCellSliceContext>? DrawExitPortalMasks { get; init; }
|
||||
public Action<RetailPViewCellSliceContext>? DrawCellParticles { get; init; }
|
||||
public Action<RetailPViewFrameResult>? EmitDiagnostics { get; init; }
|
||||
}
|
||||
|
||||
public sealed class RetailPViewFrameResult
|
||||
{
|
||||
public required PortalVisibilityFrame PortalFrame { get; init; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue