fix #124: interior-root building look-ins as a landscape-stage sub-pass
From inside a building, looking out at ANOTHER building with an opening showed its back walls missing (see-through to the world): per-building look-in floods only ran for outdoor roots; under an interior root the far building's interior never flooded. Decomp anchor (named-retail, this session's read): retail runs the look-in INSIDE the landscape stage for ANY root - LScape::draw is the FIRST call of PView::DrawCells' outside-view branch (pc:432719), strictly BEFORE the depth clear (pc:432732) and the exit-portal seals (pc:432785). ConstructView(CBldPortal) (0x005a59a0) clips each aperture via GetClip against the INSTALLED view - the accumulated doorway region when looked into from inside - and build_draw_portals_only pass 1 far-Z punches ALL apertures before pass 2 floods + draws any interior cell. The nested DrawCells has an empty outside view (PView ctor draw_landscape=0): no recursive landscape/clear/seal. Port: - GameWindow's per-building gather (frustum pre-gate on Building.PortalBounds) now runs for interior roots too; the root's own doorway self-excludes via the seed eye-side test (the eye is on its interior side). - PortalVisibilityBuilder.BuildFromExterior/ConstructViewBuilding gain seedRegion - the installed-view clip: interior-root look-ins seed against the OutsideView polygons (a building not visible through the doorway never floods); null = full screen (outdoor roots unchanged). - RetailPViewRenderer.DrawBuildingLookIns: a landscape-stage sub-pass (before ClearDepthForInterior + seals) - per building, punch ALL apertures (new DrawLookInPortalPunch callback, always forceFarZ=true, closing the ISSUES "forceFarZ keys on root kind, under-punches" gap), then draw the flooded cells' shells + statics far->near. Look-in frames are NEVER merged into the main frame: a merged cell would draw post-clear and z-fail against the root's seal (the old ledger portShape sketch was wrong on this point). - Look-in cells join the Prepare + partition set so shells have batches and statics route to ByCell (consumed only by the sub-pass; the main cell-object pass iterates the main flood's cells). Register: AP-33 added in the same commit - look-in statics draw WHOLE (no per-part viewcone; over-include is the safe direction) and look-in DYNAMICS are deferred (an NPC inside a far building stays invisible - retail draws objects per overlapped cell in the landscape stage). Pins: Issue124LookInSeedRegionTests on the real corner-building door - a seed region containing the aperture floods (and never more than the full-screen seed), a disjoint region floods NOTHING, and an interior-side eye never seeds its own exit portal. Suites: App 259+1skip / Core 1439+2skip / UI 420 / Net 294 green. Awaiting the user gate: far-building interiors visible through their apertures from inside; #130 re-gate (top-edge strip) rides the same launch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5135066733
commit
77cef4cd86
6 changed files with 379 additions and 32 deletions
|
|
@ -480,12 +480,18 @@ public static class PortalVisibilityBuilder
|
|||
/// camera cell. It keeps the same retail distance-priority traversal and
|
||||
/// neighbour reciprocal clipping once inside the building.
|
||||
/// </summary>
|
||||
/// <param name="seedRegion">Optional NDC region the seed apertures clip against —
|
||||
/// retail's GetClip runs under the CURRENTLY INSTALLED view (PView::GetClip
|
||||
/// 0x005a4320): full screen when the viewer is outdoors, the accumulated
|
||||
/// outside (doorway) view when a building is looked into from an interior
|
||||
/// root (#124). Null = full screen (the outdoor-root behavior).</param>
|
||||
public static PortalVisibilityFrame BuildFromExterior(
|
||||
IEnumerable<LoadedCell> candidateCells,
|
||||
Vector3 cameraPos,
|
||||
Func<uint, LoadedCell?> lookup,
|
||||
Matrix4x4 viewProj,
|
||||
float maxSeedDistance = float.PositiveInfinity)
|
||||
float maxSeedDistance = float.PositiveInfinity,
|
||||
IReadOnlyList<ViewPolygon>? seedRegion = null)
|
||||
{
|
||||
var frame = new PortalVisibilityFrame();
|
||||
var todo = new CellTodoList();
|
||||
|
|
@ -532,7 +538,7 @@ public static class PortalVisibilityBuilder
|
|||
poly,
|
||||
cell.WorldTransform,
|
||||
viewProj,
|
||||
FullScreenRegion,
|
||||
seedRegion ?? FullScreenRegion,
|
||||
out _);
|
||||
|
||||
// T2 (BR-4): empty clip = no seed, no exceptions (retail's
|
||||
|
|
@ -662,8 +668,9 @@ public static class PortalVisibilityBuilder
|
|||
Vector3 cameraPos,
|
||||
Func<uint, LoadedCell?> lookup,
|
||||
Matrix4x4 viewProj,
|
||||
float maxSeedDistance = float.PositiveInfinity)
|
||||
=> BuildFromExterior(buildingCells, cameraPos, lookup, viewProj, maxSeedDistance);
|
||||
float maxSeedDistance = float.PositiveInfinity,
|
||||
IReadOnlyList<ViewPolygon>? seedRegion = null)
|
||||
=> BuildFromExterior(buildingCells, cameraPos, lookup, viewProj, maxSeedDistance, seedRegion);
|
||||
|
||||
// The NDC [-1,1] viewport quad (CCW), reused by the flap probe's clip recompute.
|
||||
private static readonly Vector2[] FullScreenQuad =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue