Arms playtest-2 fixes: flip-proof elbow (angle clamp + rate limit, controller-driven), Stage 2b hand coupling (blocked arm holds the hand back)
- Elbow stored as an angle around the arm axis vs a torso-frame reference: 85% hand-suggested, from the controller pose (not the physics palm), clamped +-110 deg, 6 rad/s rate limit (flip spike: 1.8 cm/tick max vs 13.8 unclamped) - PhysicsArms.ConstrainHand: while an arm segment is in contact the hand may lead the forearm end by 3 cm; PhysicsHands applies it and suspends stuck-snap while active - ArmSpike: forearm-rest-over-anvil (owner pose: collider fine, drawn forearm 3.9 cm -> 0), flip sweep, bar test now asserts the hand is held back; all six spikes PASS x3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
464cda2f71
commit
7bc6a866eb
5 files changed
+193
-51
No files matched your search
+25
-8
@@ -77,7 +77,8 @@ TERMINOLOGY (owner-corrected — use precisely):
|
||||
jointed hand yanks the prop — the grabber's grip break runs first instead, rip at 0.8 m).
|
||||
Hand ghosts: translucent palm boxes shown at the controller pose when the physical hand lags
|
||||
> 0.1 m — ghosts belong to the HANDS, not props. Static `GetBody(controller)` lookup used by
|
||||
grabber and rig.
|
||||
grabber and rig. The chase target passes through `PhysicsArms.ConstrainHand` first (arm
|
||||
coupling); the stuck snap is also suspended while that coupling is active.
|
||||
- **PropGrabber.cs** — grab v5.3: SOLVER-OWNED RIGID WELD via a LOCALLY PATCHED addon (needs
|
||||
`research/godot-box3d-weld.md` + the v5.2 history in `research/vr-two-handed-grab.md` — the
|
||||
pin joint's hidden spring targets IDENTITY and made every earlier iteration a "winch":
|
||||
@@ -145,11 +146,12 @@ 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; 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
|
||||
the PHYSICAL hand bodies (IK moved here from BodyRig: soft IK 0.98; elbow picked on its circle as an ANGLE around the arm axis relative to a torso-frame
|
||||
down/back/out reference: 85% of the angle the HAND suggests — the forearm continues behind
|
||||
the wrist along the CONTROLLER's (aim pose) forward axis, not the physics palm's, so a palm
|
||||
fighting contact can't swing the elbow — clamped to ±110° (never through the inward/up side)
|
||||
and rate-limited to 6 rad/s (no 180° flips; spike: 1.8 cm/tick max vs 13.8 unclamped);
|
||||
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).
|
||||
@@ -160,7 +162,12 @@ TERMINOLOGY (owner-corrected — use precisely):
|
||||
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
|
||||
a 180 N forearm shoving a prop welded to a 90 N hand was a fight. **Stage 2b hand coupling**
|
||||
(`ConstrainHand`, called by PhysicsHands before chasing): while an arm segment is in
|
||||
contact, the hand may lead the forearm's end by at most `HandArmSlack` 3 cm — a blocked
|
||||
forearm holds the hand back and the hand ghost shows the controller. Free arms never limit
|
||||
the hand. Fixes the owner's "palm behind the anvil, forearm rests on it" clip (drawn
|
||||
forearm 3.9 cm into the anvil → 0; the collider was always fine at ≤ 6 mm). Exposes
|
||||
`Shoulder/Elbow/Wrist/ElbowTarget/WristTarget(side)`; `Elbow` = where the two physical
|
||||
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
|
||||
@@ -278,6 +285,14 @@ Floor StaticBody mask 1|3|4|5 (collision_mask 29).
|
||||
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 arms — owner playtest 2 (2026-10-02)**: jitter fixed, elbows "pretty
|
||||
good". Reported: occasional 180° elbow flip → angle clamp + rate limit, elbow now from the
|
||||
controller pose; forearm clipping when RESTING the forearm on the anvil with the palm behind
|
||||
it → measured: collider fine, DRAWN forearm 3.9 cm in (the hand was somewhere a straight
|
||||
forearm can't connect to) → hand coupling. Owner raised max_physics_steps_per_frame to
|
||||
12–14: harmless but NOT a quality knob (only catch-up ticks); Box3D's solver quality is
|
||||
compiled in (`SUB_STEP_COUNT` 4 in `src/spaces/box3d_space_3d.cpp`, contactHertz 30) — the
|
||||
fork could expose them if contact stiffness ever matters.
|
||||
- **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
|
||||
@@ -353,7 +368,9 @@ 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.75 / 12 | elbow pole: hand-axis share (forearm continues behind the wrist) vs torso-frame down/back/out; bounded-rate rotation smoothing |
|
||||
| `PoleHandWeight` / `PoleSmoothRate` | PhysicsArms.cs | 0.85 / 12 | share of the hand-suggested elbow angle (from the controller's forward axis); exp smoothing of the angle |
|
||||
| `PoleMaxAngle` / `PoleMaxSpeed` | PhysicsArms.cs | 110° / 6 rad/s | elbow angle clamp around the down/back/out reference + rate limit (anti-flip) |
|
||||
| `HandArmSlack` | PhysicsArms.cs | 0.03 m | how far a hand may lead its forearm's end while the arm is in contact |
|
||||
| `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) |
|
||||
|
||||
Reference in new issue
Block a user