Body step 1: one-time T-pose calibration (prefs.json, forced gate) + True Body solver + shared ArmSolver
- BodyProfile (Winter anthropometry, T-pose: arm = (span - shoulder width)/2 - 1.5 cm) and Prefs (gitignored prefs.json next to the executable / project folder in editor builds) - Calibration node: loads prefs, else head-locked prompt + jitter-proof TPoseDetector; body systems wait for BodyProfile.Current; Recalibrate() in group "calibration"; recal rebuilds arms - ArmSolver: PhysicsArms' elbow solve extracted (behaviour-identical) + min reach |U-F| fix - TrueBody: derived real-body pose (neck, chest yaw + crouch lean at neck pivot, lagging pelvis, moving shoulder girdle with scapulohumeral shrug, arms) + debug skeleton - PhysicsArms/PhysicsTorso/BodyRig now profile-driven (arm length no longer from head height) - TrueBodySpike PASS x3; all spikes PASS x3 (arm spike thresholds re-based for correct 0.57 m arms; CollapseSpike uses a fixed standing profile) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3a990c6dbe
commit
81a9b1fca2
15 files changed
+994
-106
No files matched your search
+31
-2
@@ -38,8 +38,8 @@ TERMINOLOGY (owner-corrected — use precisely):
|
||||
collapse spike takes seconds instead of minutes). Spikes and their pass lines:
|
||||
`physics_spike` "SPIKE: overall PASS", `weld_spike` "WELD: …", `grab_spike` "GRAB: …",
|
||||
`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).
|
||||
All seven PASS 3× as of this handoff. Headless asset import:
|
||||
`sixdof_spike` "6DOF: overall PASS" (run FIRST with `weld_spike` whenever the addon binary changes),
|
||||
`truebody_spike` "TRUEBODY: overall PASS" (no physics; plain `--headless`). All eight PASS 3× as of this handoff. Headless asset import:
|
||||
`godot-mono --headless --import`.
|
||||
- Engine logs: `~/.local/share/godot/app_userdata/VR Messs/logs/godot.log` — **read after user
|
||||
playtests instead of guessing**.
|
||||
@@ -182,6 +182,32 @@ TERMINOLOGY (owner-corrected — use precisely):
|
||||
connected (an obstructed segment shows as a displaced elbow). Hidden until PhysicsArms
|
||||
calibrates. IK, calibration and reach budget moved to PhysicsArms; torso mesh + yaw spring
|
||||
live in PhysicsTorso.
|
||||
- **Calibration.cs + BodyProfile.cs (body step 1, 2026-10-02)** — ONE-TIME T-POSE CALIBRATION (owner design:
|
||||
VRChat-FBT-like, persists, forced on launch if missing). `BodyProfile` = the player's real metrics (eye height,
|
||||
stature = eye/0.936, shoulder half-width = 0.1295·stature, shoulder drop below the eyes, upper arm/forearm in
|
||||
the 0.186:0.146 Winter split, stored 1.5 cm SHORT so the real elbow never locks first). `Prefs` stores it in
|
||||
**`prefs.json` next to the executable (editor builds incl. headless: the project folder) — gitignored,
|
||||
portable (copy the file)**. `Calibration` (node in group "calibration", `Recalibrate()` for the menu) loads it;
|
||||
if missing it shows a head-locked Label3D and runs `TPoseDetector`: arms level (±8 cm), at shoulder height,
|
||||
symmetric about the head (±10 cm), to the sides (not forward), span 1.0–2.4 m, every point within 3 cm of where
|
||||
the hold began (jitter-proof) for 1 s → measure: arm = (wrist span − shoulder width)/2 − margin. Body systems
|
||||
(PhysicsTorso, PhysicsArms, BodyRig, TrueBody) WAIT for `BodyProfile.Current`; recalibration rebuilds them.
|
||||
Flat preview (no headset) can't calibrate → no body there (expected). Headless spikes that inject a head use
|
||||
`BodyProfile.Estimate(eye)`; CollapseSpike sets a fixed standing profile (posture never shrinks the body).
|
||||
- **ArmSolver.cs** — the shared analytic 2-bone solve (moved verbatim from PhysicsArms: soft IK 0.98, pole as an
|
||||
angle about the arm axis vs torso-frame down/back/out, 85% controller-forward suggestion read nearest the current
|
||||
angle, ±110° clamp, 6 rad/s, elbow height cap). NEW: minimum reach |upper − fore| + 1 cm (unequal anatomical
|
||||
segments made the law of cosines invalid for hands right at the shoulder).
|
||||
- **TrueBody.cs (body step 1)** — `TrueBodySolver`: Nimso's TRUE BODY — the derived pose of the real body from
|
||||
head + controllers + profile (trigonometry, not IK): neck pivot 9 cm below / 7 cm behind the eyes (head frame);
|
||||
chest yaw = the HMD/hands yaw spring; chest pitch = crouch lean (crouch measured at the NECK PIVOT so nodding
|
||||
isn't crouching; up to ~43°) + ¼ of head pitch-down; neck base along chest-up/head-up average; pelvis hangs
|
||||
0.288·stature below the shoulder line through a critically damped 2.5 Hz spring (hip lag/sway, hips kick back in
|
||||
a crouch); MOVING SHOULDER GIRDLE: past 98% reach the shoulder joint travels toward the hand within anatomical
|
||||
limits (out +3/in −2, up +7/down −2, forward +8/back −3 cm) plus a scapulohumeral shrug up to 4 cm overhead;
|
||||
arms via ArmSolver. `TrueBody` node solves every physics tick and draws a translucent cyan DEBUG SKELETON
|
||||
(`TrueBody.ShowDebug`) for in-headset judgement. Step 2 (muscle ragdoll) will drive its joints toward this pose.
|
||||
Spike `scenes/truebody_spike.tscn`.
|
||||
- **BodyMath.cs** — shared servo math. `RotationError(target, current)` = shortest-arc
|
||||
axis·angle via `2·atan2(|xyz|, W)` — **the only allowed way to compute servo rotation
|
||||
errors** (`Quaternion.GetAngle()` NaNs at W = 1.0000001, `GetAxis()` is un-normalized near
|
||||
@@ -402,6 +428,9 @@ Floor StaticBody mask 1|3|4|5 (collision_mask 29).
|
||||
|
||||
## 7. Next steps (in order)
|
||||
|
||||
0. **Owner playtest of body step 1** — T-pose calibration (forced on first launch; delete `prefs.json` to redo,
|
||||
or the menu's Recalibrate), arm length should now match; judge the cyan True Body skeleton (shoulders that
|
||||
shrug/reach, crouch lean, hip sway, elbows). Then body step 2 = the muscle ragdoll on the 6-DOF joints.
|
||||
1. **Owner re-playtest of the body (chest fix + Stage 2 arms)** — the Stage-1 collapse is
|
||||
fixed (`collapse_spike` 49/49); feel is unvalidated in-headset. Read the log after.
|
||||
2. **Locomotion decision** — owner report 2026-10-01: two-hand anchor turning broken (not
|
||||
|
||||
Reference in new issue
Block a user