Three.js: 重新连接骨骼后如何rebind/reconnect网格化骨架?
Three.js: How to rebind/reconnect mesh skeleton after reconnecting bone?
基本上,我试图在全局轴上独立地旋转我装配的手部网格上的骨骼,并使用我用来计算它们方向的方向向量。我想出了这个代码来做到这一点:
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)
}
在手腕和食指上调用此代码会产生我 want/would 期望的手指姿势:
// 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() 后,它都会断开与网格的连接,正如您从骨架助手中看到的那样,blue/green 骨架线不再连接我在其上调用 boneLookAtWorld() 的腕骨和食指骨。
因此,此解决方案一直有效,直到我想更改已调用 boneLookAtWorld() 的骨骼的方向。因此,如果我在之前的调用之后再次调用手腕上的 boneLookAtWorld():
// 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))
这会旋转手腕,但会留下其余的手指:
有谁知道我如何在我的函数 boneLookAtWorld() 中将骨骼重新连接到其父级后如何将骨骼重新绑定到 mesh/skeleton 来解决这个问题?
如果这对任何人都有帮助,则无需执行任何类型的重新网格划分。
发生这种情况的原因是因为:
function boneLookAtWorld(bone, v) {
scene.attach(bone)
boneLookAtLocal(bone, v)
bone.parent.attach(bone)
}
当我们将骨骼附加到场景时,场景成为骨骼的新父级。因此,在我们通过 boneLookAtLocal() 执行旋转并重新附加骨骼之后,我们并没有将骨骼重新附加到原始父级!骨骼刚刚重新附加到它已经附加到的场景。
这可以通过将 boneLookAtWorld() 更改为:
来解决
function boneLookAtWorld(bone, v) {
const parent = bone.parent;
scene.attach(bone)
boneLookAtLocal(bone, v)
parent.attach(bone)
}
基本上,我试图在全局轴上独立地旋转我装配的手部网格上的骨骼,并使用我用来计算它们方向的方向向量。我想出了这个代码来做到这一点:
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)
}
在手腕和食指上调用此代码会产生我 want/would 期望的手指姿势:
// 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() 后,它都会断开与网格的连接,正如您从骨架助手中看到的那样,blue/green 骨架线不再连接我在其上调用 boneLookAtWorld() 的腕骨和食指骨。
因此,此解决方案一直有效,直到我想更改已调用 boneLookAtWorld() 的骨骼的方向。因此,如果我在之前的调用之后再次调用手腕上的 boneLookAtWorld():
// 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))
这会旋转手腕,但会留下其余的手指:
有谁知道我如何在我的函数 boneLookAtWorld() 中将骨骼重新连接到其父级后如何将骨骼重新绑定到 mesh/skeleton 来解决这个问题?
如果这对任何人都有帮助,则无需执行任何类型的重新网格划分。
发生这种情况的原因是因为:
function boneLookAtWorld(bone, v) {
scene.attach(bone)
boneLookAtLocal(bone, v)
bone.parent.attach(bone)
}
当我们将骨骼附加到场景时,场景成为骨骼的新父级。因此,在我们通过 boneLookAtLocal() 执行旋转并重新附加骨骼之后,我们并没有将骨骼重新附加到原始父级!骨骼刚刚重新附加到它已经附加到的场景。
这可以通过将 boneLookAtWorld() 更改为:
来解决function boneLookAtWorld(bone, v) {
const parent = bone.parent;
scene.attach(bone)
boneLookAtLocal(bone, v)
parent.attach(bone)
}