diff --git a/AGENTS.md b/AGENTS.md index 0e7e7c0..80f97fa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -144,7 +144,7 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x moves the player OPPOSITE to hand motion in full 3D, both grips = anchor translation + IN-PLACE yaw turn around the head. All grab deltas and turn pivots are computed in WORLD space (tracking-space math made turns orbit the map center — do not regress). - Spawn/teleport placement pins arrival height (head height preserved). Locomotion drives + Spawn/teleport placement lands the floor on the target's height (head height above the floor preserved). Locomotion drives `XROrigin3D` directly; physics reconciliation comes with the embodiment layer. Grip/trigger are polled Floats with thresholds per docs (bool actions unreliable across runtimes). Engine logs land in @@ -162,8 +162,8 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x real Godot Control UI (`MainMenu.cs`: tabs Player / World / System, normal-sized buttons, slider, scrollable log, FPS) rendered by `MenuScreen.cs` into a 960×640 SubViewport shown on a thin 0.36×0.24 m panel (~2.7 px/mm ≈ 1:1 with headset pixels at 45 cm — viewport textures - have no mipmaps, so don't oversample). Summoned/dismissed via `ax_button` (A/X — - menu_button belongs to the runtime). It is PARENTED UNDER `XROrigin3D` — Koikatsu-VR-style + have no mipmaps, so don't oversample). Summoned/dismissed via the LEFT `ax_button` (X — right A is + jump; menu_button belongs to the runtime). It is PARENTED UNDER `XROrigin3D` — Koikatsu-VR-style "fixed in the player's room": IRL movement doesn't move it relative to you, game locomotion carries it. If that feel is wrong, reverting = reparenting to `Main` and fixing the `_Ready` node paths. Appears 0.3 m in front of the summoning hand facing the head (full 3D facing — @@ -318,7 +318,18 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x with a free-space check; strength asymmetric by direction (pull-down/flexion strong, raise weak; structural guide strength push-only); **Box3D wrapper reads physics-material friction only at shape creation — set `PhysicsMaterialOverride` before AddChild.** - Owner scope: thumbstick locomotion only, no jump, avatar scaling and NPCs later. + **Step 2.6:** landing DIP is physics (legs touch down only within reach → leg strength stops the body below + its stance; big falls fold the legs, Boneworks-style; rise eased so gravity alone can stop it at the stance); + JUMP on right A (countermovement dip + leg push over the stroke — crouching first jumps higher); STICK CROUCH on + right stick Y (`RagdollDriver.StickCrouch` = virtual floor offset); body facing from `BodyMath.HeadFacing` + (no flip looking down past vertical); the XR origin is DRAWN interpolated like the bodies (`PlayerRig` + `_physOrigin`, restored before physics) — the camera/body "two places at once" desync. Rule learned: play-space + corrections may shift feed-forward history HORIZONTALLY only (vertical goals are floor-relative already). + `ragdoll_spike -- only=` runs a subset of phases. + **The crag** (`Crag.cs`): a 26 m box-rock cliff north of the playground with one graded route (boulders → + ladder → 8 m ledge → jug wall → traverse → overhang → 16 m ledge → chimney → summit with props); the way down + is the "Crag" teleport marker at the base. Regression `scenes/crag_spike.tscn` "CRAG: overall PASS" (layout only). + Owner scope: avatar scaling and NPCs later. 10. **Body physics Stage 2 — PHYSICAL ARMS, implemented 2026-10-02, awaiting owner playtest.** `PhysicsArms.cs`: per side an upper-arm + forearm RigidBody3D (2.0 / 1.2 kg, layer 5) that PD-chase their analytic 2-bone IK pose, solved each physics tick from the PHYSICAL chest diff --git a/HANDOFF.md b/HANDOFF.md index 8466831..925d786 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -40,7 +40,7 @@ TERMINOLOGY (owner-corrected — use precisely): `body_spike` "BODY: …", `collapse_spike` "COLLAPSE: …", `arm_spike` "ARM: overall PASS", `sixdof_spike` "6DOF: overall PASS" (run FIRST with `weld_spike` whenever the addon binary changes), `truebody_spike` "TRUEBODY: overall PASS" (no physics; plain `--headless`), `menu_spike` "MENU: overall PASS" - (in-VR menu input injection, no XR). All nine PASS as of this handoff. + (in-VR menu input injection, no XR). `ragdoll_spike` "RAGDOLL: overall PASS" (`-- only=a,b` runs the phases whose names contain a or b), `crag_spike` "CRAG: overall PASS" (layout geometry only). Only run the spikes your change touches — the full set takes a while. All nine PASS as of this handoff. **Fresh checkout / new worktree: run `godot-mono --headless --import` FIRST** (it may segfault at exit — harmless) — without `.godot/extension_list.cfg` the Box3D extension silently doesn't load, Godot falls back to its default physics and weld/grab/arm/6dof spikes report CHECK. Headless asset import: diff --git a/research/ragdoll-player-step2.md b/research/ragdoll-player-step2.md index 928ab19..9f59dca 100644 --- a/research/ragdoll-player-step2.md +++ b/research/ragdoll-player-step2.md @@ -205,3 +205,17 @@ it is what Boneworks/BIMOS does (the rig rides the body; the head is driven to t Results (real-input spike): landing keeps the pelvis at standing height with eye-to-camera ≤ 6.8 cm (during the fall); held poses drift 1 cm with the eye within 7 mm; crawl, mantle, climb, pull-up and hang all pass. + +## Step 2.6 — landing dip, jump, stick crouch, look-down flip, smooth view (2026-10-02) + +| Change | Why / measured | +|---|---| +| **Body facing = `BodyMath.HeadFacing`** (visor projected flat, reversed when it disagrees with the crown; near vertical the crown alone). Stick direction uses it too; the crouch lean's head pitch is `atan2` against the facing (asin peaked at 90°) | Looking down past vertical (crouching, things on the ground) flipped the visor's flat projection 180° and the whole body turned around. Spike: look down to 125° crouched → pelvis/chest yaw change 0.0° | +| **Landing dip from physics**: airborne legs touch down only within `LandingReach` (5 cm) of the pose's hip height; standing contact keeps `GroundProbeExtra` (steps down) | Support used to start 30 cm early and braked the fall in the air — no dip (owner: no landing feedback). Now 4.5 g legs stop the body below the stance: 1 m → 0.23 m dip, 5 m → 0.88 m (legs fully folded), view follows (eye vs camera ≤ 5 cm after impact) | +| **Rise eased to what gravity can stop**: `min(MaxRiseSpeed, √(2·0.7g·below))` | Legs push, never pull: rising at 1.2 m/s into the stance overshot 4 cm on gravity alone | +| **Play-space corrections shift ground control's / head guide's feed-forward history horizontally only** | The vertical goals are floor-relative (− floorY) and don't move with the play space; shifting them turned the view riding the dip into a +1 m/s feed-forward → 15 cm bounce | +| **Legs collider drive speed-limited** (`LegsMaxSpeed` 1.5 m/s) | Untucking after a landing slammed the 6 kg box down; the reaction kicked the pelvis up | +| **Jump (right A)**: state Dip (support goal drops to ≥ JumpDip + extension of stroke) → Push (JumpForce 2.4 × weight to full extension, max stroke 0.5 m) → Flight (no ground while rising) → touchdown. Buffer 0.15 s, coyote 0.12 s, head guide off | Takeoff speed is physics, v² = 2(F/m − g)·stroke (+ the dip's rebound): standing hips rise 0.45 m, from a 0.45 m crouch 0.72 m | +| **Stick crouch (right stick Y)** = `RagdollDriver.StickCrouch`, a virtual floor this far above the real one, fed to the solver, ground control and the view re-centering | The pose crouches, the play space settles that far below the ground, the camera rides down. Spike: 0.6 m → eye 1.045, origin −0.601, eye vs camera 5 mm; back up to 1.650 | +| **XR origin drawn interpolated** (`PlayerRig`: physics owns `_physOrigin`; `_Process` (priority −100) shows `prev.InterpolateWith(cur, Engine.GetPhysicsInterpolationFraction())`, `_PhysicsProcess` (priority −100) restores it; anyone else moving the origin is adopted; jumps/snap turns don't interpolate) | The bodies are drawn interpolated a tick behind while the origin stepped raw at 144 Hz under a 90 Hz display — the body looked like it was in two places when moving (owner). Not verifiable headless; needs the headset | +| Menu summon on left X only | Right A is jump |