diff --git a/src/AcDream.App/Rendering/RetailPViewRenderer.cs b/src/AcDream.App/Rendering/RetailPViewRenderer.cs index e7c0e0a2..024ec3d9 100644 --- a/src/AcDream.App/Rendering/RetailPViewRenderer.cs +++ b/src/AcDream.App/Rendering/RetailPViewRenderer.cs @@ -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 drawableCells, // param kept this task; removed in Task 4 - bool outdoorRoot) + HashSet 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 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 }; } - /// - /// True iff 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 - /// (), so "real aperture" is precisely "some slot != 0". - /// - 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,