I’m loading a glTF model of a right hand, and then loading it again (later I’ll just clone the already-loaded one) and attempting to flip it in order to create a left hand.
I know a mesh/Object3D can be flipped via applyMatrix4()
, or by scaling one or more axes by -1. However this doesn’t flip the skeleton; also it makes the lighting really weird (maybe the normals need to be updated). SkinnedMesh.applyMatrix4() also does not flip both.
If I flip the skeleton alone by simply negating the z’s of the vertices (and leaving the rotations), I think I get what one would expect: the skinning pulls the thumb and other fingers to their opposite sides, which sort of twists the mesh. Code:
theHand.traverse((child) => {
if (child.isBone) {
child.position.z *= -1;
}
});
Result:
Here’s the right hand which looks normal, for comparison:
If I attempt to flip the mesh via theHand.applyMatrix4(new THREE.Matrix4().makeScale(1, 1, -1));
, it causes the fingers (which are set up with CCDIKSolver
) to flail all over, which I’m guessing indicates that the bones are not aligned with the mesh:
So then I try flipping the vertices manually:
theHand.traverse((child) => {
if (child.isBone) {
child.position.z *= -1;
} else if (child.isMesh) {
const vertices = child.geometry.attributes.position;
for (let i = 0; i < vertices.count; i += vertices.itemSize) {
vertices.array[i + 2] *= -1;
}
}
});
Result: The lower finger bones and the write seem in tact but the middle portions’ Z (left/right of the hand) seems to be way off:
I also tried various other things like flipping the rotation.x and rotation.y on each bone, but at this point I’m guessing. As another side note, going into Blender and doing “Mirror Global” on the model then exporting a separate left hand model, I get the flailing fingers.
(Also asked on StackOverflow, will sync updates from/to there: What is the proper way to Mirror a SkinnedMesh in three.js? - Stack Overflow )