Hand posing: glove curl calibration + two-handed pivot split #42

Open
opened 2026-11-12 01:39:03 +00:00 by muse-lantern · 5 comments
Member

The hand-posing problem is two distinct defects with two distinct fixes, both measured numerically in the issue #40 §5 investigation — not one problem, and neither is a guess. This issue tracks both, in full, so either can be built from it alone.

Where this comes from

Zach's in-headset test of the generic pistol (2026-11-11, issue #40) reported problem 5: "Hand posing STILL BROKEN when holding a grip." The §5 investigation (commit 3bbec44, on editor-addon, in PR #41) measured hypotheses H1–H6 numerically — pistol force-grabbed in the right hand, angles computed from bridge readouts, not eyeballed — and ruled four of them out. What remains is H5 (the visible broken curl) and H6 (the two-handed pivot). Both are their own plans; neither was bundled into the #40 build.

Zach's call, 2026-11-11: the editor-addon branch as it stands is good enough for the framework work; the hands get their own separate issue next. This is that issue.

Ruled out (so nobody re-diagnoses them)

Measured in §5, all on the force-grabbed pistol, one-handed unless noted:

  • H1 grip pitch — NOT the cause. Barrel is level with the aim beam (0.00° apart, one-handed); barrel pitch is 0.00° when the grip is pitched +90° about X, the natural pistol-grip orientation. The −90° barrel seen with an identity grip is the unposed bridge hand, not a game bug.
  • H2 hand correction — NOT the cause. Post-correction finger direction 0.00° off target and post-correction palm 0.00° off target, both hands — computed from the correction basis vectors. (Note from the §5 work: an euler-based reconstruction of the correction was wrong in both XYZ and YXZ order — the euler does not round-trip. Any future check of the correction must use the basis vectors, not eulers.)
  • H3 mirror — NOT the cause. Left/right measured frames symmetric, thumb_dot / palm_flipped opposite as expected.
  • H4 laser vs grip — NOT the cause. Laser and barrel agree at 0.00° one-handed.

Part 1 — H5: the glove curls the wrong way (the measured cause)

The measurement. At full grip the fingertips move AWAY from the palm (dorsal, +X for the right hand) instead of toward it: every finger's fists-minus-open displacement has a negative dot with the palm normal (−0.018 to −0.077), while moving correctly toward the wrist (+Y — the finger shortens). The wrist/knuckle centres the hand debug snapshot already reported do not move with curl, so they cannot test curl direction; the fingertip is the indicator.

The calibration cannot find a palmar curl for this glove. All six cardinal bone-local axis/sign combinations move the index tip dorsally or neutrally at full curl, and the best-scoring one (BACK/+1, chosen for its shortening term) still swings the tip dorsally at amount 1.0.

What was tried and reverted (do not retry as-is). Two straightforward fixes were tried in §5 and reverted because neither changed the chosen axis/sign or the fingertip direction: palm_side via the correction target, and calibration amount 0.8 → 1.0.

What the fix needs. A deeper calibration rework, its own plan: derive the flex axis from bone geometry, or test a wider axis set than the six cardinal bone-local combinations. The fix is NOT a sign flip or an amount tweak — those were tried and measured as no-ops.

Foundation already built (commit 3bbec44, in PR #41). The measurement surface the rework will use, additive and read-only, no behaviour change:

  • Bridge grab_state now carries the grip controller's full transform (grip_transform) per hand, and _item_brief carries the held item's full transform — so barrel, laser, and glove bases can be compared numerically.
  • HandView.debug_snapshot now carries live fingertip positions (fingertips, one entry per finger, last bone of each chain, grip space).

How to reproduce the measurement. Force-grab the pistol in R through the debug bridge, read grab_state (grip transform) and HandView.debug_snapshot (fingertips) at open and full curl, compute fists-minus-open displacement per finger and dot it with the palm normal. Palmar curl = positive dot; the broken state is negative across all fingers.

Held out of this part. The half-curl edit (non-thumb amount *= 0.5) stays Zach's pending call — do not apply it as part of the calibration rework. The per-finger pose API (curl 0–1 per finger, named base poses, thumb curl + opposition, additive per-joint escape hatch) is the LATER iteration after the basic core work — its full design is the appendix in issue #40, not this issue.

Part 2 — H6: the two-handed pivot (confirmed effect, known gap)

The measurement. With the left hand also holding the pistol the barrel pitches to −73.92° (from −90° one-handed) and laser/barrel disagree by 16.08°. That is the full-basis-alignment branch in Grabbable._follow (two-hand branch aligns the primary→secondary axis to the palm-to-palm line), running for ANY two-handed grab regardless of weapon type.

What Zach wants (settled design, issue #33). The pivot stays at the PRIMARY grip; the secondary hand steers pitch/yaw relative to the primary hand only — primary is "master", secondary is "facing". Rifles/foregrip = pitch/yaw-only steering. Pistols = the secondary hand just SNAPS to the gun (the palm case). This supersedes the old #15 midpoint rule FOR WEAPONS. Non-weapon grabs are one-handed unless specifically designed for two-handed later.

The plan already exists. The pivot-split build plan is in the rebuild doc §2d.5 (dead-air-rebuild-change-list.md). Agreed order: editor addon → pivot split → kit rig → Blender addon. The pivot split is the next build after the editor addon — this issue is where it lands.

Sequencing

H5 and H6 are independent — either can be built first. H5 is the measured cause of the visible broken curl, so it is the more urgent half; H6 is the known pivot gap with a plan already written. The per-finger pose API follows after both, per Zach's call in #40.

Open decisions

  • H5: which calibration approach — flex axis derived from bone geometry, or a wider axis set — is a plan decision, not settled here.
  • H6: the pivot-split plan in rebuild doc §2d.5 is the starting point; any deviation from it is a design call for merith.
  • Half-curl (amount *= 0.5, non-thumb) remains Zach's pending edit, separate from both parts.

Design direction from merith (comments 918, 920, 2026-11-11)

Refer to the last section of #40 as well for a moddable framework that we should try to support and build into the thing as part of the primary system rather than possibly overcomplicated hand IK logic. (That is the per-finger pose API appendix in #40 — per-finger curl 0–1, named base poses, thumb curl + opposition, additive per-joint escape hatch, GDScript-owned curves + left-hand mirroring, versioned schema.)

One idea (merith): "decouple" the hands from the controllers. Track them to the controllers the same way the gun is, so that when the gun drifts because its caught on physics, the hand sticks with it as well. If we do it this way, hands will exist "seperately" from the player in the world and as such, would be subject to in world physics. BUT ALSO this gives us greater control over posing weapons since then the hands wont be hard restricted to the controls. Its something to play around with and see if it works for us, it would help solve a handful of weirdness.

This can and likely would also tie into the grip-pose system where custom grips can be made when grabbing an object such as the slide on a handgun, or the foregrip of a rifle. And so on. Of course these values should be editor exposed for modding.

Decision (merith, comment 960, 2026-11-11): spike first

Small spike on a branch/PR named hand-ik-rework first, to see how it feels. In effect the hands should be tracked to the controller in the same way that the grabbed objects are, with a generic curl for grip (for now). The standing rule holds: if no grip pose is found for an object, default to generic curl.

Poses are to be moddable in the mod toolkit. Note from merith: the toolkit will likely go through yet another redesign eventually, once people who know how to make modding tools help with layout and designing — so the pose-modding surface should be built to survive a toolkit redesign, not baked into the current dock layout.

The H6 pivot split waits on what the spike shows. The spike decides nothing final about the decoupled model.

The hand-posing problem is two distinct defects with two distinct fixes, both measured numerically in the issue #40 §5 investigation — not one problem, and neither is a guess. This issue tracks both, in full, so either can be built from it alone. ## Where this comes from Zach's in-headset test of the generic pistol (2026-11-11, issue #40) reported problem 5: "Hand posing STILL BROKEN when holding a grip." The §5 investigation (commit `3bbec44`, on `editor-addon`, in PR #41) measured hypotheses H1–H6 numerically — pistol force-grabbed in the right hand, angles computed from bridge readouts, not eyeballed — and ruled four of them out. What remains is H5 (the visible broken curl) and H6 (the two-handed pivot). Both are their own plans; neither was bundled into the #40 build. Zach's call, 2026-11-11: the editor-addon branch as it stands is good enough for the framework work; the hands get their own separate issue next. This is that issue. ## Ruled out (so nobody re-diagnoses them) Measured in §5, all on the force-grabbed pistol, one-handed unless noted: - **H1 grip pitch — NOT the cause.** Barrel is level with the aim beam (0.00° apart, one-handed); barrel pitch is 0.00° when the grip is pitched +90° about X, the natural pistol-grip orientation. The −90° barrel seen with an identity grip is the unposed bridge hand, not a game bug. - **H2 hand correction — NOT the cause.** Post-correction finger direction 0.00° off target and post-correction palm 0.00° off target, both hands — computed from the correction basis vectors. (Note from the §5 work: an euler-based reconstruction of the correction was wrong in both XYZ and YXZ order — the euler does not round-trip. Any future check of the correction must use the basis vectors, not eulers.) - **H3 mirror — NOT the cause.** Left/right measured frames symmetric, thumb_dot / palm_flipped opposite as expected. - **H4 laser vs grip — NOT the cause.** Laser and barrel agree at 0.00° one-handed. ## Part 1 — H5: the glove curls the wrong way (the measured cause) **The measurement.** At full grip the fingertips move AWAY from the palm (dorsal, +X for the right hand) instead of toward it: every finger's fists-minus-open displacement has a negative dot with the palm normal (−0.018 to −0.077), while moving correctly toward the wrist (+Y — the finger shortens). The wrist/knuckle centres the hand debug snapshot already reported do not move with curl, so they cannot test curl direction; the fingertip is the indicator. **The calibration cannot find a palmar curl for this glove.** All six cardinal bone-local axis/sign combinations move the index tip dorsally or neutrally at full curl, and the best-scoring one (BACK/+1, chosen for its shortening term) still swings the tip dorsally at amount 1.0. **What was tried and reverted (do not retry as-is).** Two straightforward fixes were tried in §5 and reverted because neither changed the chosen axis/sign or the fingertip direction: `palm_side` via the correction target, and calibration amount 0.8 → 1.0. **What the fix needs.** A deeper calibration rework, its own plan: derive the flex axis from bone geometry, or test a wider axis set than the six cardinal bone-local combinations. The fix is NOT a sign flip or an amount tweak — those were tried and measured as no-ops. **Foundation already built (commit `3bbec44`, in PR #41).** The measurement surface the rework will use, additive and read-only, no behaviour change: - Bridge `grab_state` now carries the grip controller's full transform (`grip_transform`) per hand, and `_item_brief` carries the held item's full transform — so barrel, laser, and glove bases can be compared numerically. - `HandView.debug_snapshot` now carries live fingertip positions (`fingertips`, one entry per finger, last bone of each chain, grip space). **How to reproduce the measurement.** Force-grab the pistol in R through the debug bridge, read `grab_state` (grip transform) and `HandView.debug_snapshot` (fingertips) at open and full curl, compute fists-minus-open displacement per finger and dot it with the palm normal. Palmar curl = positive dot; the broken state is negative across all fingers. **Held out of this part.** The half-curl edit (non-thumb `amount *= 0.5`) stays Zach's pending call — do not apply it as part of the calibration rework. The per-finger pose API (curl 0–1 per finger, named base poses, thumb curl + opposition, additive per-joint escape hatch) is the LATER iteration after the basic core work — its full design is the appendix in issue #40, not this issue. ## Part 2 — H6: the two-handed pivot (confirmed effect, known gap) **The measurement.** With the left hand also holding the pistol the barrel pitches to −73.92° (from −90° one-handed) and laser/barrel disagree by 16.08°. That is the full-basis-alignment branch in `Grabbable._follow` (two-hand branch aligns the primary→secondary axis to the palm-to-palm line), running for ANY two-handed grab regardless of weapon type. **What Zach wants (settled design, issue #33).** The pivot stays at the PRIMARY grip; the secondary hand steers pitch/yaw relative to the primary hand only — primary is "master", secondary is "facing". Rifles/foregrip = pitch/yaw-only steering. Pistols = the secondary hand just SNAPS to the gun (the palm case). This supersedes the old #15 midpoint rule FOR WEAPONS. Non-weapon grabs are one-handed unless specifically designed for two-handed later. **The plan already exists.** The pivot-split build plan is in the rebuild doc §2d.5 (`dead-air-rebuild-change-list.md`). Agreed order: editor addon → pivot split → kit rig → Blender addon. The pivot split is the next build after the editor addon — this issue is where it lands. ## Sequencing H5 and H6 are independent — either can be built first. H5 is the measured cause of the visible broken curl, so it is the more urgent half; H6 is the known pivot gap with a plan already written. The per-finger pose API follows after both, per Zach's call in #40. ## Open decisions - H5: which calibration approach — flex axis derived from bone geometry, or a wider axis set — is a plan decision, not settled here. - H6: the pivot-split plan in rebuild doc §2d.5 is the starting point; any deviation from it is a design call for merith. - Half-curl (`amount *= 0.5`, non-thumb) remains Zach's pending edit, separate from both parts. ## Design direction from merith (comments 918, 920, 2026-11-11) Refer to the last section of #40 as well for a moddable framework that we should try to support and build into the thing as part of the primary system rather than possibly overcomplicated hand IK logic. (That is the per-finger pose API appendix in #40 — per-finger curl 0–1, named base poses, thumb curl + opposition, additive per-joint escape hatch, GDScript-owned curves + left-hand mirroring, versioned schema.) One idea (merith): "decouple" the hands from the controllers. Track them to the controllers the same way the gun is, so that when the gun drifts because its caught on physics, the hand sticks with it as well. If we do it this way, hands will exist "seperately" from the player in the world and as such, would be subject to in world physics. BUT ALSO this gives us greater control over posing weapons since then the hands wont be hard restricted to the controls. Its something to play around with and see if it works for us, it would help solve a handful of weirdness. This can and likely would also tie into the grip-pose system where custom grips can be made when grabbing an object such as the slide on a handgun, or the foregrip of a rifle. And so on. Of course these values should be editor exposed for modding. ## Decision (merith, comment 960, 2026-11-11): spike first Small spike on a branch/PR named `hand-ik-rework` first, to see how it feels. In effect the hands should be tracked to the controller in the same way that the grabbed objects are, with a generic curl for grip (for now). The standing rule holds: if no grip pose is found for an object, default to generic curl. Poses are to be moddable in the mod toolkit. Note from merith: the toolkit will likely go through yet *another* redesign eventually, once people who know how to make modding tools help with layout and designing — so the pose-modding surface should be built to survive a toolkit redesign, not baked into the current dock layout. The H6 pivot split waits on what the spike shows. The spike decides nothing final about the decoupled model.
Owner

Refer to the last section of #40 as well for a moddable framework that we should try to support and build into the thing as part of the primary system rather than possibly overcomplicated hand IK logic.

one idea I have is to "decouple" the hands from the controllers. track them to the controllers the same way the gun is, so that when the gun drifts because its caught on physics, the hand sticks with it as well. if we do it this way, hands will exist "seperately" from the player in the world and as such, would be subject to in world physics. BUT ALSO this gives us greater control over posing weapons since then the hands wont be hard restricted to the controls. its something to play around with and see if it works for us, it would help solve a handful of weirdness

Refer to the last section of #40 as well for a moddable framework that we should try to support and build into the thing as part of the primary system rather than possibly overcomplicated hand IK logic. one idea I have is to "decouple" the hands from the controllers. track them to the controllers the same way the gun is, so that when the gun drifts because its caught on physics, the hand sticks with it as well. if we do it this way, hands will exist "seperately" from the player in the world and as such, would be subject to in world physics. BUT ALSO this gives us greater control over posing weapons since then the hands wont be hard restricted to the controls. its something to play around with and see if it works for us, it would help solve a handful of weirdness
Owner

This can and likely would also tie into the grip-pose system where custom grips can be made when grabbing an object such as the slide on a handgun, or the foregrip of a rifle. and so on.

of course these values should be editor exposed for modding

This can and likely would also tie into the grip-pose system where custom grips can be made when grabbing an object such as the slide on a handgun, or the foregrip of a rifle. and so on. of course these values should be editor exposed for modding
Author
Member

Yeah, the decoupling idea is worth a spike before it becomes a direction — it inverts the current model in a useful way.

Right now the gun is the thing being driven (Grabbable._follow, and the H6 two-hand branch aligning the gun to the palm-to-palm line), and the hands are rigidly controller-driven. Decoupled, the gun is the physics object and the hands chase it — which directly answers the drift weirdness from §5: when the gun gets caught on physics and drifts, the hand stays with the gun instead of the gun tearing away from a rigidly-attached hand.

The costs I'd want the spike to measure, not assume:

  • Hands as spring-driven physics bodies need damping tuned per hand, and under-damped hands oscillate visibly while over-damped hands lag the controller and feel mushy. The feel question is empirical — a spike with a tunable spring is the way to find out, not a design doc.
  • Collision: hands need a layer that collides with the world and the gun but not with the player's own body, or each other in a way that fights the grab. And tracking loss needs a defined fallback (freeze? fade? snap back?) — rigid hands never had to answer that.
  • It interacts with the H6 pivot split: the split says the primary hand is master and the secondary steers pitch/yaw. If hands are decoupled, the gun's pose is the thing both hands chase, so the pivot logic moves from "align the gun to the hands" to "align the hands to the gun". Worth deciding which model wins before building the split, since they pull in opposite directions.

On the grip-pose tie-in: agreed, and I think the pose data belongs on the grip/item side — per-grip named poses, like the slide and foregrip cases you named — with the per-finger API from #40's appendix as the underlying vocabulary (curl per finger, named base poses, thumb opposition) and the editor exposing those values per grip so mods define poses rather than code. That keeps the hand system generic and the pose data moddable, which is the same shape as the rest of the framework.

One question on sequencing: do you want the decoupling tried as a small spike first (hands chase a grabbed gun on springs, measure feel/drift), with the pivot split waiting on what the spike shows — or is the split still the next build regardless?

Yeah, the decoupling idea is worth a spike before it becomes a direction — it inverts the current model in a useful way. Right now the gun is the thing being driven (`Grabbable._follow`, and the H6 two-hand branch aligning the gun to the palm-to-palm line), and the hands are rigidly controller-driven. Decoupled, the gun is the physics object and the hands chase it — which directly answers the drift weirdness from §5: when the gun gets caught on physics and drifts, the hand stays with the gun instead of the gun tearing away from a rigidly-attached hand. The costs I'd want the spike to measure, not assume: - Hands as spring-driven physics bodies need damping tuned per hand, and under-damped hands oscillate visibly while over-damped hands lag the controller and feel mushy. The feel question is empirical — a spike with a tunable spring is the way to find out, not a design doc. - Collision: hands need a layer that collides with the world and the gun but not with the player's own body, or each other in a way that fights the grab. And tracking loss needs a defined fallback (freeze? fade? snap back?) — rigid hands never had to answer that. - It interacts with the H6 pivot split: the split says the primary hand is master and the secondary steers pitch/yaw. If hands are decoupled, the gun's pose is the thing both hands chase, so the pivot logic moves from "align the gun to the hands" to "align the hands to the gun". Worth deciding which model wins before building the split, since they pull in opposite directions. On the grip-pose tie-in: agreed, and I think the pose data belongs on the grip/item side — per-grip named poses, like the slide and foregrip cases you named — with the per-finger API from #40's appendix as the underlying vocabulary (curl per finger, named base poses, thumb opposition) and the editor exposing those values per grip so mods define poses rather than code. That keeps the hand system generic and the pose data moddable, which is the same shape as the rest of the framework. One question on sequencing: do you want the decoupling tried as a small spike first (hands chase a grabbed gun on springs, measure feel/drift), with the pivot split waiting on what the spike shows — or is the split still the next build regardless?
Owner

Yeah lets do a small spike on a branch/pr named "hand-ik-rework" first to see how it feels,

In effect the hands should be tracked to the controller in the same way that the grabbed objects are, with a generic curl for grip (for now), we will still follow the generic "if no grip pose found for object, default to generic curl". I do want the poses to be moddable in the mod toolkit (which will likely go through yet another redesign eventually once I get some people who know how the fuck to make modding tools to help with layout and designing)

Yeah lets do a small spike on a branch/pr named "hand-ik-rework" first to see how it feels, In effect the hands should be tracked to the controller in the same way that the grabbed objects are, with a generic curl for grip (for now), we will still follow the generic "if no grip pose found for object, default to generic curl". I do want the poses to be moddable in the mod toolkit (which will likely go through yet *another* redesign eventually once I get some people who know how the fuck to make modding tools to help with layout and designing)
Author
Member

Spike first, split waits — locked in.

Scope as I read it: branch/PR hand-ik-rework, hands chased to the controllers the same way grabbed objects are, generic curl for now with the existing fallback (no grip pose found → generic curl), and poses moddable via the toolkit with the data living on the grip/item side.

The spike will measure feel and drift first — whether the hand stays with a gun that’s caught on physics — plus spring damping, collision, and tracking-loss fallback. If the chase model doesn’t feel right, the pivot split as planned in §2d.5 is still the fallback.

Spike first, split waits — locked in. Scope as I read it: branch/PR `hand-ik-rework`, hands chased to the controllers the same way grabbed objects are, generic curl for now with the existing fallback (no grip pose found → generic curl), and poses moddable via the toolkit with the data living on the grip/item side. The spike will measure feel and drift first — whether the hand stays with a gun that’s caught on physics — plus spring damping, collision, and tracking-loss fallback. If the chase model doesn’t feel right, the pivot split as planned in §2d.5 is still the fallback.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
dead-air/engine#42
No description provided.