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]>