Commit graph

3 commits

Author SHA1 Message Date
Erik
86ecdf9ee1 fix(physics): tighten FindWalkableSphere test assertions + header
Code review feedback on Task 2 commit 7f55e14:

- Tests 1 and 2 now assert on adjustedCenter.Z (was the wrapper's
  primary behavioral contract — sphere placed on polygon plane —
  but it was unverified). Math derived from AdjustSphereToPlane:
  iDist = (dpPos - radius) / dpMove; new center = center - movement * iDist.
- Test 2 also gains the hitPoly.Plane.Normal.Z assertion that
  Test 1 already had.
- Test 4 comment slope-angle clarification.
- BSPQuery.cs FindWalkableSphere section header now notes this is
  not a direct retail port (it wraps BSPNODE::find_walkable +
  BSPLEAF::find_walkable via the existing FindWalkableInternal).

No behavior change. Build clean; 4/4 tests pass; same 8 pre-existing
failures.

Spec: docs/superpowers/specs/2026-05-19-indoor-walkable-plane-bsp-port-design.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 21:41:13 +02:00
Erik
7f55e14cd7 feat(physics): add BSPQuery.FindWalkableSphere wrapper
Thin public wrapper over the existing retail-faithful
FindWalkableInternal (BSPNODE::find_walkable + BSPLEAF::find_walkable
port). Probes downward by probeDistance along up, returns the closest
walkable polygon the sphere would rest on plus the adjusted center.

Will replace Transition.TryFindIndoorWalkablePlane's linear first-match
scan (next commit). The wrapper is callable from any "stand here, find
my floor" use case; current intent is indoor walkable-plane synthesis.

4 unit tests covering: two-floors-foot-between (sphere overlapping lower
floor), only-upper-floor-foot-above (sphere overlapping upper floor),
no-walkable-in-probe-range (sphere out of overlap distance for all
polygons), steep-poly-rejected-by-WalkableAllowance. Note: find_walkable
requires sphere to overlap the polygon plane (|dist| <= radius);
the tests use geometry that exercises this correctly, unlike the spec's
illustrative values which assumed a "nearest below" scan.

Spec: docs/superpowers/specs/2026-05-19-indoor-walkable-plane-bsp-port-design.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 21:33:27 +02:00
Erik
874d267117 feat(physics): PhysicsDataCache + BSP sphere query
Load PhysicsBSP and PhysicsPolygons from GfxObj dats during streaming.
BSPQuery.SphereIntersectsPoly traverses the tree for collision detection.
Ported from decompiled FUN_00539270, cross-ref ACE BSPNode.sphere_intersects_poly.

- PhysicsDataCache: thread-safe ConcurrentDictionary-backed cache of GfxObjPhysics
  (BSP tree + polygon dict + vertex array) and SetupPhysics (capsule dimensions).
  CacheGfxObj/CacheSetup are idempotent — safe to call at every dat load site.
- BSPQuery.SphereIntersectsPoly: recursive BSP descent with bounding-sphere broad
  phase, leaf polygon test via existing CollisionPrimitives.SphereIntersectsPoly
  (FUN_00539500), and splitting-plane classification for internal nodes.
- GameWindow: _physicsDataCache populated at all GfxObj/Setup dat load sites
  (streaming worker path, live-spawn path, ApplyLoadedTerrain render-thread path).
- 6 new unit tests covering null node, bounding-sphere miss, leaf hit, no-contact,
  internal node recursion, and empty cache behaviour. All 447 tests green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 23:28:39 +02:00