fix(physics): #149 — collide BSP-less landblock statics via Setup cylsphere

Town props placed as landblock stabs whose ONLY collision is a Setup
CylSphere/Sphere (no physics BSP) registered ZERO collision shapes and were
walk-through -- torches, braziers, lamp-posts, candle-stands, posts.

Root: the ISSUES #83 / A1.6 gate `!_isLandblockStab` skipped Setup
cyl/sphere registration for ALL landblock stabs, on the false assumption
"landblock stabs collide via BSP only (retail CBuildingObj)." That
over-broadened -- it also killed collision for BSP-less stabs.

Retail's CPhysicsObj::FindObjCollisions (@0x0050f050) uses binary dispatch:
the object's physics BSP if it HAS one (HAS_PHYSICS_BSP_PS 0x10000), ELSE its
CSetup CylSpheres/Spheres -- never both. Confirmed via live retail cdb on the
Holtburg torch (Setup 0x020005D8 at world (105.99,17.17)): FindObjCollisions
target num_cylsphere=1, cyl h=2.2 -- a cylsphere, exact-matching the dat
(cylSphere r=0.2 h=2.2); the StabList confirms stab[95]=0x020005D8 there.

Fix: gate the Setup cyl/sphere registration on `entityBsp == 0` instead of
stab-ness. Preserves #83's anti-doubling (stab WITH a BSP -> BSP-only) while
restoring collision for BSP-less stabs. Other landblock entities on this path
(scenery -- tree-trunk cylspheres) are unaffected.

Live-verified: torch + candle/brazier family block now; ~115 cyl/sphere
Setups register across streamed landblocks. Core suite green (1595/0).

The earlier selection-sphere hypothesis was WRONG and is reverted -- the cdb's
r=0.48 sphere was the player/NPC body (every body sphere is ~0.48), not the
torch. The correct cdb method: capture the TARGET at FindObjCollisions (not
`this` in CSphere::intersects_sphere) and confirm by position + Setup-id.

(Issue numbered #149 to stay clear of main's #148; this worktree branched
before main's #145-148 were added.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-25 10:15:34 +02:00
parent 989cc25d80
commit 2ac7ea776f
2 changed files with 46 additions and 12 deletions

View file

@ -5482,6 +5482,28 @@ outdoors at the angle that previously erased it.
# Recently closed
## #149 — BSP-less landblock statics (torches/braziers/lamp-posts) were walk-through
**Status:** DONE (2026-06-25, `4cf6eeb`) — town props placed as landblock stabs
whose ONLY collision is a Setup CylSphere/Sphere (no physics BSP) had ZERO collision
shapes registered → walk-through. Root: the ISSUES #83 / A1.6 gate `!_isLandblockStab`
skipped Setup cyl/sphere for ALL stabs, on the false assumption *"landblock stabs
collide via BSP only (retail CBuildingObj)."* Confirmed end-to-end via live retail
cdb: the Holtburg torch (Setup `0x020005D8`, world (105.99,17.17)) hits
`CPhysicsObj::FindObjCollisions` with `num_cylsphere=1`, cyl h=2.2 — a cylsphere,
matching the dat (cylSphere r=0.2 h=2.2) exactly; the StabList confirms stab[95]=
`0x020005D8` at that position. Fix: gate the Setup cyl/sphere registration on
`entityBsp == 0` (retail's binary dispatch — BSP if the object has one, ELSE
cyl/sphere; see `feedback_retail_binary_dispatch`) instead of stab-ness — preserves
#83's anti-doubling (stab WITH a BSP → BSP-only) while restoring collision for
BSP-less stabs. Live-verified (torch + candle/brazier family block now; ~115
cyl/sphere Setups register across streamed landblocks). The earlier selection-sphere
hypothesis was WRONG and reverted — the cdb's r=0.48 sphere was the player/NPC body
(every body sphere is ~0.48), not the torch; capturing the *target* at
`FindObjCollisions` (not `this` in `intersects_sphere`) + confirming by position +
Setup-id is the correct cdb method. `GameWindow.cs:7281`. Core suite green (1595/0).
(Numbered #149 to stay clear of main's #148; worktree branched before #145148.)
## Dense-town (Arwic) FPS deep-dive — 75 → ~165 fps
**Status:** DONE (2026-06-24) — `290e731` (cell-object draw batching) + `9f51a4d`