fix(physics): Phase 2 — pass foot-sphere center to ResolveCellId

Visual test of Phase 2 portal traversal showed walls still didn't
block from inside buildings. Diagnosis: ResolveCellId was being
called with sp.CheckPos (entity reference, at the feet — world
Z=terrain) instead of sp.GlobalSphere[0].Origin (foot sphere center,
~0.5m above terrain). Combined with the +0.02f Z-bump on cached
cell origins (for render z-fight prevention), the test position
landed at cell-local Z=-0.02 — just below the cell floor — and
PointInsideCellBsp correctly reported "outside" for every cell.
CheckBuildingTransit never added candidates; player CellId stayed
outdoor; indoor cell-BSP collision branch never fired; walls didn't
block.

Retail's check_building_transit uses sphere.Center (the sphere CENTER,
not the entity reference) per the pseudocode at
docs/research/acclient_indoor_transitions_pseudocode.md:222-238.

Three call sites updated (PhysicsEngine x2 inside ResolveWithTransition;
TransitionTypes inside Transition.FindEnvCollisions).

Also adds a [check-bldg] diagnostic line to CheckBuildingTransit (gated
on the existing ACDREAM_PROBE_INDOOR_BSP flag) so future verification
captures show per-portal inside/outside results without needing
another diagnostic flag.

Spec: docs/superpowers/specs/2026-05-19-indoor-portal-cell-tracking-design.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-19 18:54:10 +02:00
parent 702b30a63e
commit 3ffe1e44f6
3 changed files with 22 additions and 5 deletions

View file

@ -769,7 +769,7 @@ public sealed class PhysicsEngine
return new ResolveResult(
sp.CheckPos,
ResolveCellId(sp.CheckPos, sphereRadius, sp.CheckCellId),
ResolveCellId(sp.GlobalSphere[0].Origin, sphereRadius, sp.CheckCellId),
onGround,
collisionNormalValid,
collisionNormal);
@ -787,7 +787,7 @@ public sealed class PhysicsEngine
uint partialCellId = sp.CheckCellId != 0 ? sp.CheckCellId : cellId;
return new ResolveResult(
sp.CheckPos,
ResolveCellId(sp.CheckPos, sphereRadius, partialCellId),
ResolveCellId(sp.GlobalSphere[0].Origin, sphereRadius, partialCellId),
partialOnGround,
collisionNormalValid,
collisionNormal);