Body Stage 1 collapse root-caused + fixed: NaN in torso servo math (GetAngle = 2*acos(W) at W=1.0000001), not solver stacking

- BodyMath.RotationError: atan2-based shortest-arc error (no NaN, no GetAxis gain collapse
  inside 0.16 deg); used by PhysicsTorso orientation servo and PhysicsHands rotation lock
- BodyMath.ResetIfNonFinite escape hatch on torso + hands
- PhysicsHands.Drive extracted (static) so spikes run the real hand chase
- CollapseSpike: deterministic repro (slow yaw drift across a parked chest, 7/40 NaN on old
  code) + solver-stacking scenarios (seated chest in table, two-hand-welded 50 kg anvil,
  real PropShop) — 49/49 clean after fix, x3; all other spikes PASS x3
- Failure brief RESOLUTION section; HANDOFF/AGENTS updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
FoxyzandClaude Opus 5.5 committed 2026-10-01 23:55:46 +03:00
1 parent ce1e0e3b0c
commit cb518999e5
9 files changed
+466 -47

No files matched your search

+7 -7
View File
@@ -235,18 +235,18 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x
angular-velocity servo (self-rights, holds yaw), 2 m snap safety, torso-yaw spring moved
here from BodyRig. Camera stays KINEMATIC — torso chases the head, never the reverse
(Boneworks sickness lesson). No self-collision with own hands (layer scheme above).
**First in-headset session NaN'd the solver** (owner seated: chest overlapped the table;
two-handed 50 kg anvil weld pressed into it → `!v.is_finite()` transform flood, "head
detaching from the body"). **DO NOT extend the body track until diagnosed** — analysis,
hypotheses and the headless-repro plan live in `research/body-stage1-failure-brief.md`
(self-contained, forwardable to the owner's external agent). `BodyRig.cs` is
**First in-headset session NaN'd the chest — ROOT-CAUSED + FIXED same day**: script
math, not the solver (`Quaternion.GetAngle()` = 2·acos(W) → NaN at W = 1.0000001; see
`research/body-stage1-failure-brief.md` RESOLUTION). **Never use `GetAngle()/GetAxis()`
for servo errors — `BodyMath.RotationError` (atan2) is the rule; every driven body runs
`BodyMath.ResetIfNonFinite`.** Regression: `scenes/collapse_spike.tscn` (run headless with
`--fixed-fps 90`) must print "COLLAPSE: overall PASS". `BodyRig.cs` is
VISUALS-only (head cube + 2-bone analytic arms, soft IK, elbow pole,
reach budget feeding `PhysicsTorso.ReachOffset`). Headless regression:
`scenes/body_spike.tscn` must print "BODY: overall PASS" (also proves the Box3D pair
rules: one-way contact, hand-through-chest exclusion, prop contact) — note its repro gap:
no static-table overlap, no welded heavy props. Stage 2 (physical
arm chains + hierarchical per-joint budgets, Nimso/Boneworks tier) is BLOCKED on the
Stage-1 fix; design + prior art in `research/vr-body-physics-hugs.md`,
arm chains + hierarchical per-joint budgets, Nimso/Boneworks tier) — see item 10; design + prior art in `research/vr-body-physics-hugs.md`,
stack facts in `research/vr-body-physics-godot.md`.
9. **Getting a body (rig) — placeholder v1.3 (cube character, agent-built).** `BodyRig.cs`:
all-BOX primitives (owner preference) — head 0.15³ behind the eyes, slim torso retracted,