Files
VR-Mess/research/vr-body-physics-hugs.md
T

242 lines
19 KiB
Markdown
Raw 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: physics player bodies + hugging/contact in VR
Fourth research pass for VR Messs (Godot 4.7, C#, physics hands = force-clamped rigid palms
chasing controllers at 90 N; placeholder box rig = procedural torso + 2-bone analytic arms,
no Skeleton3D yet; Box3D physics server, joints: pin/hinge/slider/cone-twist→weld-patched).
Goal: player arms+chest react physically — hugging characters, body reacting when grabbed.
Label: [S] = sourced, [I] = inference. See also `vr-arm-ik.md`, `vr-arm-ik-deep.md`,
`vr-grabbing.md`, `vr-two-handed-grab.md`.
## 1. Prior art — player body physics in VR
- [S] **Boneworks/Bonelab** (GDC 2020 "Heuristic Based Approaches to Physics Systems"; coverage:
https://www.gamedeveloper.com/design/how-classical-game-mechanics-and-physics-converge-in-vr-hit-i-boneworks-i/,
Marrow wiki: https://boneworks.fandom.com/wiki/1Marrow_Interaction_Engine): the ENTIRE virtual
body is one physics object, 82 kg, "no infinite forces" — every interaction draws on the body's
force budget; jumping = physically thrusting feet down; exploits die because classical mechanics
is the ruleset. Arms = 2-bone chains driven by constraints toward controller targets with a
heuristic force/velocity limit; over budget → the BODY moves, not the hand. Internal solver
details beyond that are not public. Motion sickness is the accepted cost: players report it as
one of the most nauseating VR games because the physics body can shove the camera off the real
head pose (https://www.resetera.com/threads/highly-anticipated-vr-title-boneworks-is-a-collection-of-vr-sins.158449/page-5).
- [S] **HL:Alyx** shipped HANDS ONLY, deliberately — IK arms mislead because there is no
proprioception for elbow/shoulder (dev commentary:
https://combineoverwiki.net/wiki/Developer_commentary/Half-Life:_Alyx). The strongest evidence
that "collision-enabled limbs" were considered not worth it.
- [S] **Stormland** (Insomniac): fully ANIMATED rendered arms + hip/shoulder holsters that ground
body awareness; body position handled by "invisible logic" for player intent, not a simulated
chain (https://roadtovr.com/stormland-behind-the-scenes-insomniac-games/2/). Kinematic body,
fake arms — feels great, can't hug anyone.
- [S] **Vertigo 2**: solo dev moved to a full physics-driven first-person body + hand physics and
committed to "full physics going forward" (devblog:
https://www.reddit.com/r/ValveIndex/comments/d48pex/vertigo_2_devblog_new_first_person_body_hand);
no postmortem numbers published. Proof one person can ship it in a standard engine.
- [S] **Open-source / community implementations**: Valem's Boneworks-style full-body-physics Unity
tutorial series (https://www.youtube.com/watch?v=D9qQb3EvU8c — rigidbody torso + jointed limbs
chasing trackers); RealMotionVR physics player controller
(https://github.com/pierricklyons/real-motion-vr); community full-body-physics WIPs with the
recurring pattern "rigidbody hands diverge from ghost hands → haptic + visual snap-back"
(https://www.reddit.com/r/Unity3D/comments/9sjsm9/vr_fullbody_physics_because_im_tired_of_reaching/,
https://www.reddit.com/r/ValveIndex/comments/ircdm3/wip_full_body_physics_high_fidelity_hands_in).
[I] No repo named "Hurdy" surfaced in any search — likely misremembered.
- [I] Pattern across all of them: simulate at most ONE powered body (the chest/torso root) driven
toward the HMD, and let limbs be either kinematic (Stormland/Alyx) or weakly-driven physics
chains (Boneworks). Nobody ships a fully self-colliding humanoid player rig — self-collision +
comfort + tuning cost is why.
## 2. Active ragdoll / puppet techniques (how pose-tracking-on-physics is done)
- [S] **Canonical recipe** (Gang Beasts-style; https://www.reddit.com/r/Unity3D/comments/3v6kt8/does_anyone_know_how_gang_beasts_physics_are):
semi-procedural blend of keyframed pose-matching + active ragdoll. Implementation lineage:
- Joint drive to animated "master" pose: duplicate physical body, each ConfigurableJoint's
angular drive target-rotation = the animated counterpart's rotation
(https://github.com/sergioabreu-g/active-ragdolls).
- PD control per joint: proportional-derivative torques toward target pose — the standard
formulation (EggyStudio Unity.Humanoid.ActiveRagdoll, "follows an animation using a simple
PD controller" with configurable joints, weakening drives on collision:
https://github.com/CanTalat-Yakan/Unity.Humanoid.ActiveRagdoll).
- Research tier: DReCon (Bergamin et al. 2019, ACM TOG) = motion matching picks the target
pose, RL-trained policy applies PD torques + root drive for balance
(https://www.researchgate.net/publication/337117918_DReCon_data-driven_responsive_control_of_physics-based_characters);
SIMBICON-style feedback and stepping controllers for balance
(https://arxiv.org/html/2210.14730v1; survey: Geijtenbeek et al. 2012,
https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1467-8659.2012.03189.x).
- Balance practicals: lock hips X/Z rotation so the ragdoll can't fall while still being pushed
(https://sergioabreu-g.medium.com/how-to-make-active-ragdolls-in-unity-35347dcb952d), or apply
an external upright torque/com-height controller — joint motors alone don't balance
(https://medium.com/@jacasch/balancing-of-active-ragdolls-in-games-367f146b25fb).
- Practical tips for making them look alive, not spastic:
https://www.gamedeveloper.com/design/8-tips-for-animating-active-ragdolls.
- [S] **Human Fall Flat** never published a technique talk (closest is design retrospectives);
the joint-motor active-ragdoll recipe above is the community-reconstructed equivalent
(https://www.reddit.com/r/godot/comments/1fnwu2v/how_to_make_an_active_ragdoll_using_joint_motors).
- [I] **Failure modes** (consistent across sources): too-high drive gains inject energy →
jitter/explosions at solver limits; too-low → mush that can't hold a pose; the balance layer is
the whole difficulty — pose tracking is easy, staying upright while pushed is not. Gain tuning
is per-body and iterative (tens of iterations), and (per wirewhiz Alyx-hands notes in
`vr-grabbing.md`) "overly aggressive joint values destabilize the sim" is a physics-server-level
truth, not engine-specific.
## 3. Hugging / close contact with characters in VR
- [S] **In-game examples are almost nonexistent.** The closest known artifact is a Unity dev
clip "Added arm physics so now you can hug stuff in VR!" — physics-driven arms colliding with
bodies produce a passable hug for free (https://www.reddit.com/r/Unity3D/comments/jnfau2/added_arm_physics_so_now_you_can_hug_stuff_in_vr);
"The Hug Game" makes the other player's arms the hug implement
(https://automaton-media.com/en/news/20220225-10037). No shipped AAA VR game has a simulated
embrace — the user's "not even Bonelab had it" observation is correct.
- [S] **VRChat avatar "hugging"** is theater, not physics: PhysBones are spring chains for
secondary motion that can collide but carry no character-to-character force exchange
(https://creators.vrchat.com/common-components/physbones); Contacts are overlap event triggers —
sender touches receiver → animator parameter — auto-placed on hand/finger colliders
(https://creators.vrchat.com/common-components/contacts). So VRChat hugs = arms clip through +
contact event plays an animation. It still sells, which is evidence contact EVENTS + reaction
matter more than force fidelity.
- [S] **HCI/haptics research on hugs** (what makes a hug read as a hug):
Hugvie — a hug-shaped pillow that improves conversation affect, i.e. the SHAPE of contact does
the work (https://eng.irl.sys.es.osaka-u.ac.jp/projects/hugvie; study:
https://www.semanticscholar.org/paper/3a11fff7f3945f1a103ef233aba2d46de1122f35);
HuggieBot — established design tenets of natural robotic hugging, haptic REACTIVITY (responding
during the hug) significantly improves perception (https://arxiv.org/html/2101.07679v1,
https://is.mpg.de/hi/projects/huggiebot-evolution-of-an-interactive-hugging-robot-with-visual-and-haptic-perception);
intra-hug gestures the huggee should respond to: holding, rubbing, patting, squeezing
(https://dl.acm.org/doi/fullHtml/10.1145/3526110);
"Anatomy of a Hug in Virtual Reality" (Deusdado & Antunes, Procedia CS 239, 2024) — hug =
wrap + pressure + duration, haptic presence over fidelity
(https://www.sciencedirect.com/science/article/pii/S187705092401528X).
- [I] Synthesis: a hug reads correctly when (1) your arms VISIBLY wrap (no clipping, no
IK explosion), (2) contact is mutual — you can push and feel resistance, (3) the other party
RESPONDS (pressure → squeeze-back, pat → shift). Force simulation provides 1+2 cheaply; 3 is
gameplay code reading contact events.
## 4. What sells contact — full sim vs pseudo-physics
- [S] Boneworks' GDC claim in essence: physics contact sells because forces are CONSISTENT
(one 82 kg budget, no infinite forces) — not because bones are individually simulated.
- [S] Alyx cut arm physics and shipped the best-feeling hands of its generation; Stormland faked
arms entirely and scored on body presence. Both prove partial approaches can carry immersion.
- [S] But neither can HUG: pseudo-physics limbs clip through characters by design, and clip = no
hug, no lean, no tug. Boneworks CAN be leaned on things and shove bodies with its chest.
- [I] Decision rule: pseudo-physics (kinematic torso collider + IK arms) is enough for
self-presence, NOT enough for contact mechanics. The minimum real-physics set for hugging is
exactly: one physics torso/chest collider + two physical arm segments (we already have palms)
with weak pose drives — i.e. an active-ragdoll-torso, not a full skeleton sim.
## 5. Recommended approach for VR Messs
Constraints: Box3D (pin/hinge/slider/weld-patched-cone-twist), placeholder box rig, no
Skeleton3D, physics hands exist. [I] throughout this section unless noted.
1. **Torso = one RigidBody3D (capsule/box), PD-driven toward an HMD-derived target** — position
from HMD, yaw from the torso-yaw spring already specced in `vr-arm-ik-deep.md`. Force-CLAMPED
chase (same 90 N-class budget pattern as the palms). This body grounds all contact: hug
pressure, tug response, door pushes. DO NOT weld the HMD to it — camera stays kinematic
(Boneworks' sickness lesson, §1); torso chases the camera, never the reverse.
2. **Arms phase 1 = visual-only 2-bone analytic IK (existing) + existing palm bodies.** Chest
contact comes from the torso body; arms don't need physics to hug at chest height. Palms
colliding with the NPC's body already provide "arms resist contact" below the face.
3. **Arms phase 2 (only if phase 1 reads as clipping) = active-ragdoll upper-arm/forearm
segments**: rigidbodies per segment, hinge joints, hinge MOTOR targets = the analytic IK
solution's angles, low gain + velocity cap (§2 recipe, adapted to Box3D's hinge motors).
Joint motors beat per-frame force application — let the solver own it (same lesson as
`vr-grabbing.md`). Skip self-collision entirely (torso↔arm excluded pairs); nobody notices.
4. **Hug detection = contact events, not force analysis**: both palms (or forearm segments) in
contact with NPC torso + player chest collider touching NPC torso + sustained ≥0.5 s →
"embracing" state; read total contact impulse for a pressure value. NPC response = squeeze
force ramp on the player torso body + reaction gestures (HuggieBot reactivity finding, §3).
Optional: fade the visual arms into a scripted wrap pose during the state — VRChat proves
players forgive clipped/faked hugs if the reaction is right.
5. **Grabbed/tugged**: free — any joint from an NPC/prop to the torso body makes the whole body
react, because the torso is now the anchored mass the palms were implicitly missing. Cap the
coupling force below the torso chase budget so tugs can't yank the camera frame (sickness).
6. **Box3D-specific risks**: [I] cone-twist is weld-patched → use hinge+motor for limb drives and
pin for torso coupling; verify hinge motor max-impulse behavior at 90 Hz before building on
it (the `godot-box3d-weld.md` patch is the precedent for upstreaming what's missing).
7. **Explicitly rejected**: full per-bone simulated player skeleton (§1 — nobody ships it;
comfort + tuning cost), VRChat-style event-only hugs (no mutual force = no resistance = hollow),
Go-Go stretch arms (rejected before in `vr-arm-ik.md`).
## 6. Nimso Studios' "Hybrid Presence" — the closest known full-arm-physics VR body (researched 2026-10-01)
Owner-pointer. Unity, CLOSED demos — no source, no Unity package (commenters asked; refused),
no written technical breakdown exists anywhere.
- [S] Itch: `https://nimsostudios.itch.io/hybrid-presence-samples2` — "The Hybrid Presence
system on the arms only" (Spideriini: web-swinging/wall-climbing with physics arms that
climb ledges, push off walls, slow you down). Dev's OWN admitted issues: "some small issues
with elbows and with stuttering hands" — i.e., the exact failure modes our research predicts
(elbow singularities, chase-gain jitter) persist even in the best-known implementation.
- [S] `https://nimsostudios.itch.io/hybrid-test-chamber-tech-demo` — physics-simulated
interactions (physical hands, grip points, two-handed weapons "using a Hybrid system"
blending primary-hand rotation with secondary-hand position), physics locomotion (sway/jog
detection from natural bounce frequency). Known issues: physics glitches "inherent to the
physics engine", shoulder logic UNIMPLEMENTED (butt stocks have no effect). For an FPS.
- [S] Channel `youtube.com/@NimsoStudios` — the technique lives only in videos: "IN-DEPTH VR
PHYSICS INTERACTIONS" parts 1–2 (`youtube.com/watch?v=tMDmwD1cQPg`,
`youtube.com/watch?v=BTlY8SWLtgo`), "Hybrid Muscle System – Fast VR Physics" (arm
force/strength model), "FLUID VR HAND ADAPTATION + Hand Tracking" (hands deform to fit
objects on contact), "Project TX – physics NPCs". Community framing: Boneworks-class body,
"muscle-like" force constraints driving simulated arms/body from the controllers.
- [S] Godot-land has NOTHING at this tier — the ceiling is XR Tools' kinematic PlayerBody
(`github.com/GodotVR/godot-xr-tools`) + physical-hands templates
(`github.com/jtnicholl/godot4-vr-physics-template`). A Godot full-physics body would be
novel; as reusable tech for the owner's second project that novelty is a feature.
- [I] Assessment feed: Nimso validates BOTH directions — full arm physics is achievable by
one person (samples are free and rated 4.8/5), AND its cost is visible in his own issue
lists (elbows, hand stutter, shoulder logic missing after years). His "muscle" language =
force-clamped chase drives, i.e. the same pattern as our PhysicsHands generalized to limbs;
"hybrid" = tracked targets + simulated bodies, which is ALSO our layer-3 architecture
(AGENTS.md). We are not inventing a new technique — we'd be porting a known-shaped one.
## 7. Project TX video extractions (owner-provided AI summaries, 2026-10-01)
Owner extracted AI breakdowns of Nimso's videos: "IN-DEPTH VR PHYSICS INTERACTIONS" pt. 1–2
(`youtube.com/watch?v=tMDmwD1cQPg`, `BTlY8SWLtgo`), plus asks on joint/force model, muscle
system, hand adaptation, and physics NPCs. Distilled to what bears on OUR design:
- [S] **Force model = ours, generalized.** Script = "brain" reading tracker data, feeding
targets; solver executes via ConfigurableJoints in force/acceleration mode with PD-tuned
spring (Slerp) drives — never infinite force. Heavy object ⇒ spring stretches ⇒ hand lags
the controller ⇒ weight feel. Exactly our PhysicsHands pattern (90 N chase) and the grab
weld's philosophy: the solver owns the coupling, the script owns the intent.
- [S] **Muscle = hierarchical per-joint force budgets.** Base avatar mass 60 kg scales the
joint drives' F_max. Shoulders get HIGH torque budgets (climb-hangs the whole body);
wrists/forearms get strict caps. A 12 kg sledgehammer held out straight exceeds the
wrist/forearm cap via lever arm ⇒ hand buckles; two-hand sliding down the shaft shortens
the lever ⇒ liftable. Fatigue is modeled as mechanical disadvantage ONLY — no stamina
meter; strain reads through visual lag and drift. → Refinement for our Stage 2: replace
the flat 90 N hand budget with per-joint budgets (hand ≺ forearm ≺ shoulder ≺ torso)
scaled from a body-mass stat; props with attachment coordinates register their mass at
the attachment point (holstered 12 kg hammer scaled the whole avatar 60→72 kg).
- [S] **Hand adaptation = script-side relaxation on contact (anti-winch).** When the hand
hits structural limits, the script temporarily relinquishes axes, SHIFTS THE PIVOT (palm
→ fingertips against a magazine baseplate), and eases joint boundaries dynamically
("dynamic radius gripping" tracks a bat's changing radius as the hand slides). The winch
lesson in reverse: don't fight the solver — reconfigure. Our analog already exists as
break thresholds; a future nicety is pivot-shift on contact for resting palms on surfaces.
- [S] **Physics NPCs (the huggee half) = active ragdoll + kinematic grab anchors.** The NPC
is a live ragdoll driven by internal joint-matching springs (Boneworks-class). Strikes
compare impact velocity against NPC joint stiffness; enough momentum overrides the NPC's
balance solver (deflection before hit registration). Grabbing an NPC's hand/head creates
a TEMPORARY fixed/distance joint between the player's hand rigidbody and the NPC
hitboxes — the NPC instantly feels the player's weight; you can swing, push off-balance,
pull close. → For us: hug/touch = contact between player chest/palms and an NPC
active-ragdoll; grabbing NPCs = our existing ConeTwist weld against NPC anchor bodies;
squeeze-back = NPC joint-matching drives ramping against the player's budget.
- [S] **Leg colliders exist but are buggy** (legs lock up, impede crawling) — the dev
shipped them anyway for climbing/tire-swing play. Validates deferring legs LAST.
- [S] **Locomotion is physics-native**: stick push at slow speed, natural sway raises walk,
jog bounce frequency triggers run ("remember your feet aren't tracked"); two-handed
weapons blend primary-hand rotation with secondary-hand position ("Hybrid system").
- [S] **Out of scope for VR Messs** (noted for completeness): extended physics materials as
data wrappers (surface-pair impact audio, density-based stabbing, material magnetism),
dynamic recoil from muzzle/bullet-mass integration, geometric mag-well sliding with
ergonomic posing rules, mass-independent buoyancy (surface-area/displacement forces so a
1 kg box floats a 70 kg body without jitter), modular attachments shifting center of mass
locally, cross-compatible ammo systems.
- [I] **What the extractions change in our plan:** confidence only + two concrete design
upgrades (hierarchical budgets; NPC anchors via existing welds). No architectural
surprises — an independent implementation converged on our exact shape. Remaining unknown
= tuning numbers (per-joint gains; published nowhere, must be tuned in-headset) and
locomotion/balance/comfort (only relevant at a Stage 3+ we may never reach).