Básicamente, estoy tratando de rotar huesos en mi malla de mano manipulada de forma independiente en el eje global con vectores de dirección que uso para calcular su orientación. Se me ocurrió este código para hacerlo:
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) }llamar a este código en la muñeca y el dedo índice produce la pose del dedo que quiero/esperaría:
// 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))El problema es que, cada vez que llamo a boneLookAtWorld() en un hueso, se interrumpe la conexión con la malla, como puede ver en el asistente de esqueleto, las líneas de esqueleto azul/verde ya no están conectadas en los huesos de la muñeca y el índice que yo llamado boneLookAtWorld() en.
Entonces, como resultado, esta solución funciona hasta que quiero cambiar la orientación de un hueso al que ya llamé boneLookAtWorld(). Entonces, si vuelvo a llamar a boneLookAtWorld() en la muñeca después de las llamadas anteriores:
// 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))Esto gira la muñeca pero deja atrás el resto del dedo:
¿Alguien sabe cómo puedo volver a unir el hueso a la malla/esqueleto después de volver a unirlo a su elemento principal en mi función boneLookAtWorld() para solucionar esto?
En caso de que esto ayude a alguien, no hay necesidad de realizar ningún tipo de remallado.
La razón por la que esto sucede es porque en:
function boneLookAtWorld(bone, v) { scene.attach(bone) boneLookAtLocal(bone, v) bone.parent.attach(bone) }cuando adjuntamos el hueso a la escena, la escena se convierte en el nuevo padre del hueso. Entonces, después de realizar la rotación a través de boneLookAtLocal() y volver a unir el hueso, ¡no estamos volviendo a unir el hueso al padre original! El hueso se está volviendo a unir a la escena a la que ya está conectado.
Esto se resuelve cambiando boneLookAtWorld() a:
function boneLookAtWorld(bone, v) { const parent = bone.parent; scene.attach(bone) boneLookAtLocal(bone, v) parent.attach(bone) }