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:
1 parent
ce1e0e3b0c
commit
cb518999e5
9 files changed
+466
-47
No files matched your search
@@ -92,6 +92,9 @@ public partial class PhysicsTorso : Node
|
||||
_mesh.Visible = true;
|
||||
}
|
||||
|
||||
if (BodyMath.ResetIfNonFinite(_body, new Transform3D(_torsoBasis, target), "PhysicsTorso"))
|
||||
return;
|
||||
|
||||
if (_body.GlobalPosition.DistanceTo(target) > SnapDistance)
|
||||
{
|
||||
_body.GlobalTransform = new Transform3D(_torsoBasis, target);
|
||||
@@ -109,13 +112,9 @@ public partial class PhysicsTorso : Node
|
||||
force = force.Normalized() * MaxForce;
|
||||
_body.LinearVelocity += force / TorsoMass * dt;
|
||||
|
||||
Quaternion qErr = _torsoBasis.GetRotationQuaternion()
|
||||
* _body.GlobalTransform.Basis.GetRotationQuaternion().Inverse();
|
||||
if (qErr.W < 0f)
|
||||
qErr = new Quaternion(-qErr.X, -qErr.Y, -qErr.Z, -qErr.W);
|
||||
float angle = qErr.GetAngle();
|
||||
Vector3 spinAxis = angle > 1e-5f ? qErr.GetAxis() : Vector3.Up;
|
||||
Vector3 spinDesired = spinAxis * Mathf.Min(angle * OrientKp, OrientMaxSpin);
|
||||
Vector3 rotErr = BodyMath.RotationError(_torsoBasis.GetRotationQuaternion(),
|
||||
_body.GlobalTransform.Basis.GetRotationQuaternion());
|
||||
Vector3 spinDesired = (rotErr * OrientKp).LimitLength(OrientMaxSpin);
|
||||
|
||||
Vector3 wErr = spinDesired - _body.AngularVelocity;
|
||||
float maxDeltaW = OrientMaxAlpha * dt;
|
||||
|
||||
Reference in new issue
Block a user