I am facing a challenge where I need to independently rotate bones on a rigged hand mesh along the global axis using direction vectors to calculate their orientation. To tackle this, I have developed the following code:
function boneLookAtLocal(bone, position) {
bone.updateMatrixWorld()
let direction = position.clone().normalize()
let pitch = Math.asin(-direction.y)
let yaw = Math.atan2(direction.x, direction.z);
let roll = Math.PI;
bone.rotation.set(roll, yaw, pitch);
}
function boneLookAtWorld(bone, v) {
scene.attach(bone)
boneLookAtLocal(bone, v)
bone.parent.attach(bone)
}
When I apply this code to the wrist and index finger, it produces the desired finger pose:
// hand.wrist and hand.index[0:3] represent bones
boneLookAtWorld(hand.wrist, new THREE.Vector3(1, 1, 1))
boneLookAtWorld(hand.index[0], new THREE.Vector3(1, 1, 1))
boneLookAtWorld(hand.index[1], new THREE.Vector3(1, 0, 1))
boneLookAtWorld(hand.index[2], new THREE.Vector3(0, -1, 0))
https://i.sstatic.net/JFUD2.png
The issue arises when I call boneLookAtWorld() on a bone more than once, as it breaks the connection to the mesh. This results in the skeleton lines appearing disconnected for the wrist and index bones.
For example, if I try to change the orientation of the wrist bone after previous calls:
// hand.wrist and hand.index[0:3] are bones
boneLookAtWorld(hand.wrist, new THREE.Vector3(1, 1, 1))
boneLookAtWorld(hand.index[0], new THREE.Vector3(1, 1, 1))
boneLookAtWorld(hand.index[1], new THREE.Vector3(1, 0, 1))
boneLookAtWorld(hand.index[2], new THREE.Vector3(0, -1, 0))
...
boneLookAtWorld(hand.wrist, new THREE.Vector3(0, 0, 1))
This rotation affects the wrist but leaves the rest of the finger behind:
https://i.sstatic.net/j5wcM.png
I am looking for a way to rebind the bone to the mesh/skeleton after reattaching it to its parent in my function boneLookAtWorld() to resolve this issue. Any suggestions?