fix(weapons): orient the support hand by frame, not by arc plus a twist
The support hand was upside down on the handguard. Its rotation was built as a shortest arc from the hand's forearm line to the barrel, plus a constant 0.5 rad twist. A shortest arc is the MINIMAL rotation between two directions and says nothing at all about roll, so the entire roll of that hand came from the constant — and a constant is right only for the one rig it was tuned against. Orienting a hand onto something it grips is a frame-to-frame problem, and saying it that way leaves nothing free to guess. A hand wrapping a cylinder has its curl axis along that cylinder, or the fingers close across the handguard rather than around it; and its palm faces the cylinder, which for a hand supporting from underneath means up. The third axis falls out of the other two. Map the hand's rest anatomical frame onto that target and the roll is determined rather than chosen. The frame is the same one the finger curl already uses — along, palm, curl — now stored whole instead of just its curl axis. Verified by render on the mannequin (Rigify names, 0.524 m arm) and Kiyoko (VRoid names, 0.470 m): fingers wrap the handguard from below and over the top, stock at the shoulder, arms not crossing, consistent across idle, ADS and run. L_HAND_TWIST is deleted rather than retuned — it was the bug. Smoke 0 failures. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
daed7ab980
commit
2a6b321984
@@ -225,10 +225,33 @@ Blender-export `IndexFinger1_L`. Segments are ordered by DEPTH BELOW THE HAND,
|
||||
not by the number in the name — the numbering is not consistent between families,
|
||||
but the hierarchy always runs knuckle to fingertip.
|
||||
|
||||
**The support hand came out upside down**, because its orientation was built as
|
||||
a shortest arc plus a constant twist: align the hand's forearm line to the barrel
|
||||
(`Quaternion(fa_rest_dir, aim_dir)`), then add 0.5 rad of roll. A shortest arc
|
||||
says NOTHING about roll — it is the minimal rotation between two directions — so
|
||||
the entire roll came from that constant, and a constant is right only for the rig
|
||||
it was tuned on.
|
||||
|
||||
Orienting a hand onto something it grips is a FRAME-TO-FRAME problem, and framing
|
||||
it that way leaves nothing free to guess:
|
||||
|
||||
```
|
||||
curl axis must lie along the object's axis, or the fingers close ACROSS the
|
||||
handguard instead of around it
|
||||
palm must face the object — up, for a hand supporting from underneath
|
||||
along falls out of the other two (palm x curl)
|
||||
```
|
||||
|
||||
Map the hand's rest anatomical frame onto that target and the roll is determined,
|
||||
not chosen. Verified on both the Rigify-named mannequin and the VRoid-named
|
||||
Kiyoko: fingers wrap the handguard from below, over the top.
|
||||
|
||||
**Rule:** anything expressed as a constant in a rig's local frame — a mount
|
||||
rotation, a grip offset, a curl axis, a weapon size — is a guess about one
|
||||
skeleton. Derive it from the skeleton, or hand it to a solver that already knows
|
||||
the answer.
|
||||
rotation, a grip offset, a curl axis, a weapon size, a wrist twist — is a guess
|
||||
about one skeleton. Derive it from the skeleton, or hand it to a solver that
|
||||
already knows the answer. And when a rotation needs a specific ROLL, never build
|
||||
it from a shortest arc: that operator has no opinion about roll, so whatever you
|
||||
add afterwards is doing all the work.
|
||||
|
||||
## 6. Some sources are not salvageable, and the gate should say so
|
||||
|
||||
|
||||
Reference in New Issue
Block a user