Files
VR-Mess/research/vr-arm-ik-deep.md

42 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Research: arm IK stability, elbow poles, torso yaw, overextension (follow-up)
Second research pass for VR Messs, after v1.1 of the placeholder rig showed: residual shaking
when the arm tugs the body near (but not at) full extension, twitchy elbows driven by wrist
rotation, and pure-HMD chest yaw. Label: [S] = sourced, [I] = inference.
See also `vr-arm-ik.md` (prior art) and `vr-grabbing.md` (grab architecture).
## 1. Full-extension elbow jitter = the classic 2-bone singularity
- [S] At cos(±1) the elbow solution is bistable and tiny target noise flips it (robotics "elbow singularity"; FINAL IK threads confirm the "elbow pops to fully straight" symptom: https://discussions.unity.com/t/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released/525769).
- [S] The established fix is SOFT IK: clamp the effective target distance to a fraction of chain length (recommended 0.98) and ease over the last percent of reach (MSMotion docs "Soft IK Ratio": https://maharajastudiocustomerservice-cell.github.io/MaharajaStudioWeb/ms-motion-docs.html; Blender soft-IK threads: https://blenderartists.org).
- [S] VRIK docs: elbow bones should be slightly bent in their natural bend direction — production solvers NEVER allow the perfectly-straight configuration (http://www.root-motion.com/finalikdox/html/page16.html).
- [I] Pole smoothing alone does NOT fix a singular solve — the pole is undefined exactly at full extension.
- **Recommendation applied/usable**: clamp shoulder→hand distance to reach×0.98 before the law-of-cosines solve; keep ~5–8° minimum elbow bend; slerp the elbow over 2–3 frames; hysteresis 0.97/0.99 on the straight-arm state so the transition can't oscillate.
## 2. Elbow direction (pole) heuristics
- [S] VRIK does NOT use hand rotation as the primary pole driver — it samples the avatar's start pose for the natural bend direction, then uses twist weights (`shoulderTwistWeight` etc.) and optional bend goals (docs above; Resonite VRIK mirror: https://wiki.resonite.com/Component:VRIK).
- [S] Community practice for aiming: a bend goal at the elbow's down/back/outward position as a SOFT bias (Unreal forums on driving the middle joint from hand orientation: https://forums.unrealengine.com).
- [I] Controller-rotation-driven poles (ours) are common in physics-hands recreations but are the twitchiest variant; Boneworks-style arms derive elbow direction mostly from body-relative geometry.
- **Recommendation**: build the pole in a stable torso frame ("down + back + outward"), PROJECT OUT the shoulder→hand axis so wrist spin can't rotate it, add hand-forward only as a small weight (~0.2–0.3) that ramps in when aiming, and exponentially smooth the final pole; never let a blend weight cross zero (flip risk).
## 3. Chest/torso yaw from HMD + hands
- [S] Academic prior art: Ponton et al. 2022, "Combining Motion Matching and Orientation Prediction to Animate Avatars for Consumer-Grade VR Devices" (https://arxiv.org/abs/2209.11478) — HMD-forward alone has 14.5° mean body-orientation error vs 5.4° for a learned predictor; AvatarPoser (https://arxiv.org/abs/2107.04044), HMD-NeMo (https://arxiv.org/html/2308.11261v1), MirrorPoser are the NN lineage.
- [S] Classic game heuristic: torso yaw from the controller-to-controller line blended with HMD yaw (https://forums.unrealengine.com).
- [S] Ponton et al. smooth predicted orientation with a spring-damper/slerp and DECOUPLE orientation from the head (never hard-blended against head yaw).
- **Recommendation (non-NN)**: yaw = HMD yaw base blended toward a hands-derived yaw with weight proportional to how far forward/raised the hands are (0 idle → ~0.6 aiming), applied through a critically damped spring with ~150–250 ms response.
## 4. Overextension with physics hands
- [S] VRIF-style frameworks render an "arm stretch" but clamp within a limit; soft IK is the standard clamp (VRIF: https://discussions.unity.com; MSMotion above).
- [S] Boneworks is fully physics-driven: at max reach the arm simply straightens and the whole physics body is pulled/leaning rather than the arm stretching (GDC coverage: https://www.gamedeveloper.com/design/how-classical-game-mechanics-and-physics-converge-in-vr-hit-i-boneworks-i/; https://www.reddit.com/r/StressLevelZero/comments/frucx5/).
- [I] No documented game stretches the visual arm beyond bone length — everyone clamps the target to a sphere around the shoulder; the physics hand continuing past reach reads fine because the straight arm still points at it.
- **Recommendation**: clamp the VISUAL hand target to a sphere around the shoulder (~98% reach, soft-eased) while the physics hand body keeps moving freely; the reach-budget torso shift covers the remainder.
## Applied to VR Messs (BodyRig.cs)
Soft IK factor 0.98; pole projected in torso frame with hand weight 0.25 and exponential
smoothing; torso yaw spring (HMD base + hands-derived yaw × forwardness, exp smoothing ~12/s);
reach-budget hysteresis unchanged. Next dial if shaking persists: SoftIKFactor → 0.95.