Revert "fix(render): outdoor look-in draws interior cells only through real doorway apertures (no see-through walls)"

This reverts commit 0030dacaaa.
This commit is contained in:
Erik 2026-06-07 21:16:11 +02:00
parent 0030dacaaa
commit 774cb22713

View file

@ -76,18 +76,11 @@ public sealed class RetailPViewRenderer
ctx.EmitDiagnostics?.Invoke(result);
// Render unification: from the OUTDOOR-node root a flooded interior cell must draw ONLY within
// its real doorway aperture (a plane-clip slot). A cell whose aperture degenerates to the
// no-clip slot 0 (screen-covering / edge-on) would otherwise draw FULL-SCREEN and paint the
// building interior across the whole screen — the see-through-walls bug. Indoor roots keep the
// seal-everything slot-0 fallback (load-bearing: it seals the room the camera stands in).
bool outdoorRoot = ctx.RootCell.IsOutdoorNode;
DrawLandscapeThroughOutsideView(ctx, clipAssembly, partition);
UseIndoorMembershipOnlyRouting();
DrawExitPortalMasks(ctx, pvFrame, clipAssembly, drawableCells);
DrawEnvCellShells(ctx, pvFrame, clipAssembly, drawableCells, outdoorRoot);
DrawCellObjectLists(ctx, pvFrame, clipAssembly, drawableCells, partition, outdoorRoot);
DrawEnvCellShells(ctx, pvFrame, clipAssembly, drawableCells);
DrawCellObjectLists(ctx, pvFrame, clipAssembly, drawableCells, partition);
return result;
}
@ -135,11 +128,8 @@ public sealed class RetailPViewRenderer
ctx.EmitDiagnostics?.Invoke(result);
DrawExitPortalMasks(ctx, pvFrame, clipAssembly, drawableCells);
// DrawPortal is the exterior look-in (camera outside, peering in) → same outdoor gate: an
// interior cell with no real doorway aperture must not draw full-screen. (This path is dead
// after the cutover flip; kept compiling until the Step-D deletion.)
DrawEnvCellShells(ctx, pvFrame, clipAssembly, drawableCells, outdoorRoot: true);
DrawCellObjectLists(ctx, pvFrame, clipAssembly, drawableCells, partition, outdoorRoot: true);
DrawEnvCellShells(ctx, pvFrame, clipAssembly, drawableCells);
DrawCellObjectLists(ctx, pvFrame, clipAssembly, drawableCells, partition);
RestoreNoClip(ctx.SetTerrainClipUbo);
return result;
@ -191,19 +181,15 @@ public sealed class RetailPViewRenderer
IRetailPViewCellDrawCallbacks ctx,
PortalVisibilityFrame pvFrame,
ClipFrameAssembly clipAssembly,
HashSet<uint> drawableCells, // param kept this task; removed in Task 4
bool outdoorRoot)
HashSet<uint> drawableCells) // param kept this task; removed in Task 4
{
// Retail DrawCells Loop 2: every visible cell's shell, reverse cell_draw_list
// (far→near), per portal_view slice. Indoors a cell without a clip-slot falls through
// GetCellSlicesOrNoClip to NoClipSlice and draws unclipped (sealed — load-bearing R1 seal).
// Outdoors (outdoor-node root) that same unclipped draw IS the see-through bug, so a cell with
// no real plane-clip aperture is skipped entirely (see DrawInside).
// (far→near), per portal_view slice. No drawableCells filter — a cell without a
// clip-slot falls through GetCellSlicesOrNoClip to NoClipSlice and draws unclipped
// (sealed; per-slice trim returns in Task 4).
foreach (var entry in IndoorDrawPlan.ShellPass(pvFrame))
{
uint cellId = entry.CellId;
if (outdoorRoot && !HasRealClipSlot(clipAssembly, cellId))
continue;
_oneCell.Clear();
_oneCell.Add(cellId);
@ -221,8 +207,7 @@ public sealed class RetailPViewRenderer
PortalVisibilityFrame pvFrame,
ClipFrameAssembly clipAssembly,
HashSet<uint> drawableCells,
InteriorEntityPartition.Result partition,
bool outdoorRoot)
InteriorEntityPartition.Result partition)
{
for (int i = pvFrame.OrderedVisibleCells.Count - 1; i >= 0; i--)
{
@ -230,11 +215,6 @@ public sealed class RetailPViewRenderer
if (!drawableCells.Contains(cellId))
continue;
// Outdoor-node root: skip a cell with no real doorway aperture (would draw full-screen) —
// matches DrawEnvCellShells so a skipped interior cell shows neither walls nor furniture.
if (outdoorRoot && !HasRealClipSlot(clipAssembly, cellId))
continue;
if (!partition.ByCell.TryGetValue(cellId, out var bucket) || bucket.Count == 0)
continue;
@ -260,24 +240,6 @@ public sealed class RetailPViewRenderer
return new[] { NoClipSlice };
}
/// <summary>
/// True iff <paramref name="cellId"/> has at least one view slice backed by a real plane-clip
/// slot (slot != 0) in this frame's assembly — i.e. a genuine doorway aperture. A cell with no
/// entry, or only the no-clip slot 0 (screen-covering / degenerate aperture → scissor fallback),
/// returns false. Used by the outdoor-node root to refuse drawing an interior cell that would
/// otherwise paint full-screen (the see-through-walls bug). Slot 0 is reserved as no-clip
/// (<see cref="NoClipSlice"/>), so "real aperture" is precisely "some slot != 0".
/// </summary>
private static bool HasRealClipSlot(ClipFrameAssembly clipAssembly, uint cellId)
{
if (!clipAssembly.CellIdToViewSlices.TryGetValue(cellId, out var slices))
return false;
foreach (var slice in slices)
if (slice.Slot != 0)
return true;
return false;
}
private void UseIndoorMembershipOnlyRouting()
{
// Retail's PView portal views decide which cells/objects are eligible,