📝 Originally published (in Japanese) at forge.workstyle.tech.
I rigged the fingers and made them curl into a fist, but the fingertips bent backward toward the back of the hand instead of curling toward the palm. A rig moves a mesh—a collection of vertices that forms a shape—based on bone movement. I confirmed that the vertices were moving and said, “It was set up correctly.” But when I checked the finger movement in the viewer, the joints were out of place. In this article, I’ll explain the double transformation that caused the misalignment and the checks I added after fixing it.
Conclusion first
The reason the fingertips flipped toward the back of the hand when I made a fist was that the same transform was applied twice: once to the tail of a parent bone and again to the head of its connected child. The arm correction logic kept transforming coordinates that had already been moved instead of using the original coordinates. After saving the coordinates before processing and checking both joint positions and fist movement, I found that the fingertips moved 58–72 mm toward the wrist.
Does Moving the Vertices Mean the Finger Rig Is Correct?
“Are the fingers rigged correctly? Does each of the five fingers move as it should?”
I answered, “They were rigged correctly,” but that answer was wrong. I had only checked the vertex assignments, not how the fingers themselves moved. There were 30 finger bones in total, and when I tested them by bending each bone one at a time, the vertices assigned to each bone moved.
The vertex counts were 129/129 for the thumb, 130/133 for the index finger, 121/121 for the middle finger, 126/129 for the ring finger, and 119/124 for the little finger. Looking at these results, I concluded that the finger rig was correct.
This test only showed that the vertices moved when I bent a bone. It did not tell me whether the fingers would bend naturally at the joints when making a fist. The question was, “Does each of the five fingers move as it should?” But I had not run a test that could answer it.
Where the Viewer Showed Misaligned Bones and Finger Joints
When I checked the left index finger in the viewer, the mesh joints were at these positions:
0.634–0.660 / 0.660–0.673 / 0.674–0.691
After the arm correction, however, the bones were positioned like this:
0.635→0.615 / 0.615→0.624 / 0.624→0.681
The first bone pointed toward the wrist, and the rotation centers of the second and third joints were set 1–2 cm inside the palm. At the previous stage, the position was 0.684→0.7125, which was correct.
When I measured fingertip movement, the fingers moved 37–50 mm when lightly clenched. With a tight clench, they moved 68–109 mm and flipped over toward the back of the hand; the thumb also moved 95 mm. I had confirmed that the vertices followed the bones, but the joint positions and the movement when clenching were still problematic.
Why Did Connected Bones Get Transformed Twice?
Tracing the cause led me to the arm correction logic, which transformed each bone’s head (start point) and tail (end point):
b.head, b.tail = tf(b.head), tf(b.tail)
This applies the transform separately to the bone’s head and tail. However, Intermediate and Distal had use_connect=True (connected to their parent bones). When bones are connected, moving the parent’s tail also moves the child’s head.
As a result, after transforming the parent’s tail, the code transformed the child’s head too, applying tf (the coordinate transform) twice to the same position.
I thought I was transforming each bone’s coordinates independently. But connected bones don’t have independent positions. I transformed the child’s head again without accounting for how moving the parent also affects the child.
The same issue occurred in another section, where a 0.924Ă— transform was applied twice. This bug had persisted in every build since the arm correction.
How I Fixed the Double Transform and Checked Finger Movement
Before applying the transform, I saved the original head and tail values, then applied the transform to those saved values. In other words, I passed the original coordinates to tf(orig) instead of coordinates that had already been transformed.
I also added finger checks. I verified that the dot product—a value indicating how closely the bone directions align—was greater than 0.5; the minimum was 0.56. Joints were placed within 3 mm of the corresponding bone segments, and the root bones were allowed up to 6 mm.
After the fix, making a fist moved the fingertips 58–72 mm toward the wrist and 21–26 mm downward. The thumb moved 51 mm. In the 16-pose out-of-bounds check, the hand values went from 177–182 down to 21–22, and there were no NaNs (values that cannot be treated as numbers).
No before-and-after comparison images were saved. The comparisons here are based on the recorded coordinates and measurements.
Why I Corrected My “It’s Set Up Correctly” Answer
At 06:05, I said, “It was set up correctly.” Ten minutes later, a viewer check revealed that the finger bones and joints were misaligned.
“I told you earlier that it was set up correctly, but that was wrong.”
I had only checked the vertex assignments. Bending each bone individually to see whether the vertices move can confirm the assignments. But it doesn’t show that the joints bend in the right places when the whole hand goes through the process.
The cause was treating connected bones as separate points and applying the same transformation to the parent’s tail and the child’s head. To fix it, I saved the original coordinates before transforming them, and added checks for joint positions and fingertip movement.
Whether vertices are assigned to bones and whether those bones make the fingers move as intended are two separate things to verify. I checked only the first and mistakenly said the second was correct too.
If You Run Into the Same Problem
- Curl the finger and check whether the fingertip moves toward the palm or the back of the hand.
- In the viewer, compare the mesh joints with the bone positions.
- Check that the original head and tail are saved before the conversion process passes them to
tf(orig). - In addition to bending each bone one at a time, check the joint positions and how the fingertips move when the hand is curled.
Top comments (0)