Arms playtest-1 fixes: open-loop torso lean (chest hunting), hand-driven elbow pole + height cap, held-prop arm collision exceptions
- Lean computed from PhysicsTorso.NominalTarget/TargetBasis, not the body's own shoulders: the closed loop made the chest hunt (spike: |v| 1.1 -> 0.019 m/s, lean range 2.7 cm -> 0.9 mm) - Elbow on its IK circle, 75% hand-axis (forearm continues behind the wrist), bounded-rate rotation smoothing (no flips), capped at max(shoulder, wrist) + 5 cm - PhysicsArms.SetHeld: held prop ignores that side's arm segments (PropGrabber calls it) - ArmSpike: stretch settle, hug elbows out (0.17 m vs 0.02 m old pole), held-anvil stability; all six spikes PASS x3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7589b13aba
commit
464cda2f71
6 files changed
+288
-65
No files matched your search
+25
-9
@@ -145,16 +145,25 @@ TERMINOLOGY (owner-corrected — use precisely):
|
||||
NO joints (Box3D has no usable 3-DOF shoulder/wrist joint — PinJoint's identity spring, no
|
||||
Generic6DOF — and AGENTS.md forbids joints between tracked bodies): each segment PD-chases
|
||||
its analytic 2-bone IK pose, solved EVERY PHYSICS TICK from the PHYSICAL chest shoulders to
|
||||
the PHYSICAL hand bodies (IK moved here from BodyRig: soft IK 0.98, torso-frame pole with
|
||||
the shoulder→hand axis projected out, hand-forward push, exp-smoothed). **Hierarchical
|
||||
the PHYSICAL hand bodies (IK moved here from BodyRig: soft IK 0.98; elbow picked on its circle, 75% HAND-DRIVEN —
|
||||
the forearm continues behind the wrist along the aim pose's forward axis, which gives
|
||||
outward elbows for wraps/hugs — 25% torso-frame down/back/out; smoothed by bounded-rate
|
||||
ROTATION around the arm axis (can't pass through zero and flip); capped at
|
||||
max(shoulder, wrist) + 5 cm height). **Hierarchical
|
||||
budgets** (Nimso muscle model) from `BodyMassStat` 60 kg: hand 90 N ≺ forearm 180 N ≺ upper
|
||||
arm 360 N ≺ chest 2400 N. Orientation = slewed angular-velocity servo via
|
||||
`BodyMath.RotationError`; segment roll follows the body's current X axis (no flips).
|
||||
Safety: 1 m snap (teleports), `ResetIfNonFinite`. Also owns calibration (arm lengths +
|
||||
shoulder width from first head height > 0.5 m; segments spawn then) and the REACH BUDGET
|
||||
(torso lean toward overreach → `PhysicsTorso.ReachOffset`, hysteresis unchanged). Exposes
|
||||
shoulder width from first head height > 0.5 m; segments spawn then) and the torso LEAN
|
||||
toward overreaching hands → `PhysicsTorso.ReachOffset`, computed OPEN-LOOP from
|
||||
`PhysicsTorso.NominalTarget/TargetBasis` (the head-derived pose without the lean). The old
|
||||
closed loop (lean from the body's own shoulders) made the chest hunt back and forth —
|
||||
owner-reported, spike-measured 1.1 m/s → 0.019 m/s after the fix. Props held by a hand get
|
||||
a collision exception with that side's arm segments (`SetHeld`, called by PropGrabber) —
|
||||
a 180 N forearm shoving a prop welded to a 90 N hand was a fight. Exposes
|
||||
`Shoulder/Elbow/Wrist/ElbowTarget/WristTarget(side)`; `Elbow` = where the two physical
|
||||
segments meet. Spike: `scenes/arm_spike.tscn` (track gap, fast swing, arm pushes a prop
|
||||
segments meet. Spike: `scenes/arm_spike.tscn` (stretch-beyond-reach chest settle, hug elbows out
|
||||
0.17 m (old pole: 0.02), held 50 kg anvil stable + forearm out of it, track gap, fast swing, arm pushes a prop
|
||||
with the hand clear, forearm blocked by a bar without tunneling + quiet while pinned,
|
||||
teleport snap, NaN-injection reset, chest undisturbed by own arms).
|
||||
- **BodyRig.cs** — placeholder rig VISUALS only: head cube (HMD-driven) + arm boxes drawn
|
||||
@@ -262,7 +271,14 @@ Floor StaticBody mask 1|3|4|5 (collision_mask 29).
|
||||
static table + two-hand-welded 50 kg anvil) was tested and is stable. Full record:
|
||||
`research/body-stage1-failure-brief.md` (RESOLUTION section). **RULE: never use
|
||||
`Quaternion.GetAngle()/GetAxis()` for servo errors — use `BodyMath.RotationError`.**
|
||||
- **Body Stage 2 (physical arms) — unvalidated in-headset.** Things to watch in the first
|
||||
- **Body Stage 2 arms — owner playtest 1 (2026-10-02)**: "works fine for the most part";
|
||||
reported forearm clipping through a held anvil, chest jitter when stretching one arm,
|
||||
elbows mostly pointing down / unnatural. Fixed: open-loop lean (jitter), hand-driven
|
||||
elbow + height cap, held-prop exceptions. The exact screenshot clip (forearm through the
|
||||
held anvil) was NOT reproduced headless across 3 anvil heights — the drawn forearm is a
|
||||
straight line from the PHYSICAL elbow to the hand wrist, so any elbow below a held object's
|
||||
near edge can still draw through it; re-check in-headset.
|
||||
- **Body Stage 2 (physical arms) — remaining watch-list.** Things to watch in the first
|
||||
playtest: elbow drawn displaced when a segment is blocked (that's the honest physics view),
|
||||
arms sweeping props when seated at the table, any stutter at fast swings (spike: ≤ 6 cm
|
||||
joint lag at 2 Hz × 0.4 m). Known gaps by design (Stage 2b, feel-driven): a blocked forearm
|
||||
@@ -337,14 +353,14 @@ Floor StaticBody mask 1|3|4|5 (collision_mask 29).
|
||||
| `PalmGrabOffset` | PropGrabber.cs | ±0.045 m along hand +X (left +, right −) | grab point on the palm (taste choice) |
|
||||
| Grip/trigger thresholds | several files | 0.6 | polled Float edges |
|
||||
| `SoftIKFactor` | PhysicsArms.cs | 0.98 | shoulder→hand distance clamp before IK solve (lower toward 0.95 if shake persists) |
|
||||
| `PoleHandWeight` / `PoleSmoothRate` | PhysicsArms.cs | 0.25 / 10 | elbow pole: hand-forward push / exp smoothing |
|
||||
| `PoleHandWeight` / `PoleSmoothRate` | PhysicsArms.cs | 0.75 / 12 | elbow pole: hand-axis share (forearm continues behind the wrist) vs torso-frame down/back/out; bounded-rate rotation smoothing |
|
||||
| `ElbowRiseAllowance` | PhysicsArms.cs | 0.05 m | elbow capped at max(shoulder, wrist) height + this (no chicken wings) |
|
||||
| `TorsoYawHandsWeight` / `TorsoYawForwardness` / `TorsoYawSmoothRate` | PhysicsTorso.cs | 0.6 / 0.3 m / 12 | torso yaw spring: hands blend / forwardness normalizer / exp smoothing (≈200 ms) |
|
||||
| `TorsoMass` / `MaxForce` / `MaxSpeed` | PhysicsTorso.cs | 30 kg / 2400 N / 6 m/s | chest chase budget (force-clamped PD) |
|
||||
| `OrientKp` / `OrientMaxSpin` / `OrientMaxAlpha` | PhysicsTorso.cs | 20 / 10 rad/s / 150 rad/s² | chest orientation servo (yaw hold + self-right) |
|
||||
| `SnapDistance` | PhysicsTorso.cs | 2 m | chest teleport snap safety |
|
||||
| `armTotal` | PhysicsArms.cs | clamp(0.46×headHeight, 0.5, 0.72) | total arm length, 50/50 split |
|
||||
| `ReachPushSpeed` / `ReachDecaySpeed` | PhysicsArms.cs | 0.8 / 0.4 m/s | torso lean toward / back from overreach |
|
||||
| `ReachDecayFactor` | PhysicsArms.cs | 0.92 | hysteresis band (decay only below 92% of reach) |
|
||||
| `LeanReachFactor` / `LeanSmoothRate` | PhysicsArms.cs | 0.95 / 6 per s | torso lean starts past 95% reach (open-loop from the nominal chest pose), exp-smoothed ≈170 ms |
|
||||
| `ReachBudgetMax` | PhysicsArms.cs | 0.25 m | horizontal torso offset clamp |
|
||||
| `ReachVerticalMin/Max` | PhysicsArms.cs | −0.05 / +0.12 m | vertical torso offset clamp (stops upward oscillation) |
|
||||
| `HeadBackOffset` | BodyRig.cs / PhysicsTorso.cs | 0.06 m | keeps the head cube out of the view |
|
||||
|
||||
Reference in new issue
Block a user