Javascript 在Three.js中计算骨骼查看对象的矩阵
我在计算骨骼“看”对象时遇到问题。首先,lookAt函数不适合我。我可以理解这一点,因为骨骼的矩阵是一个单位矩阵,在局部空间中,所以它不会开箱即用。(注视会产生奇怪的结果) 以下是我迄今为止所做的努力。它将头部从左向右旋转,但上下我还没有计算。我要补充一点,目前它的工作效果不太好:( 更新 我已经更新了我的代码。当我在一个轴上旋转(x轴向相机上下移动头部或z轴向相机左右移动头部)时,它确实起作用,但当我尝试组合这两个旋转时,当我在角色的侧面时,头部开始旋转Javascript 在Three.js中计算骨骼查看对象的矩阵,javascript,matrix,three.js,Javascript,Matrix,Three.js,我在计算骨骼“看”对象时遇到问题。首先,lookAt函数不适合我。我可以理解这一点,因为骨骼的矩阵是一个单位矩阵,在局部空间中,所以它不会开箱即用。(注视会产生奇怪的结果) 以下是我迄今为止所做的努力。它将头部从左向右旋转,但上下我还没有计算。我要补充一点,目前它的工作效果不太好:( 更新 我已经更新了我的代码。当我在一个轴上旋转(x轴向相机上下移动头部或z轴向相机左右移动头部)时,它确实起作用,但当我尝试组合这两个旋转时,当我在角色的侧面时,头部开始旋转 function lookAt() {
function lookAt() {
var v1 = new THREE.Vector3(0, 0, 1);
var v2 = new THREE.Vector3(
camera.position.x - headBone.matrixWorld.elements[12],
0,
camera.position.z - headBone.matrixWorld.elements[14]
).normalize();
var mult = 1.0;
if(camera.position.x - headBone.matrixWorld.elements[12] < 0.0000) {
mult = -1.0;
}
var fAng = v2.angleTo(v1) * mult;
v2 = new THREE.Vector3(
0,
camera.position.y - headBone.matrixWorld.elements[13],
camera.position.z - headBone.matrixWorld.elements[14]
);
mult = 1.0;
if(camera.position.y - headBone.matrixWorld.elements[13] > 0.0000) {
mult = -1.0;
}
fAng2 = v2.angleTo(v1) * mult;
headBone.rotation.set(
Math.max(-0.5, Math.min(fAng2, 0.1)),
0,
-Math.max(-1.0, Math.min(fAng, 1.0))
);
}
但这仍然无法正确跟踪摄影机。请注意,应用其中一种方法确实有效。我已经找到了一个可以接受的答案。我找到了一种方法,可以使骨骼看起来位于任意点。也许可以在THREE.js中扩展并包括这一点 这仍然存在问题,而且似乎不是100%准确。例如,我把它放在我的头骨上,当我指向角色后面时,它会倒转。有人知道如何改进吗?请评论 还请注意,我将骨骼的Z轴指向三个。Vector3(0,0,1);。它可以移动到一个参数
function boneLookAt(bone, position) {
var target = new THREE.Vector3(
position.x - bone.matrixWorld.elements[12],
position.y - bone.matrixWorld.elements[13],
position.z - bone.matrixWorld.elements[14]
).normalize();
var v = new THREE.Vector3(0,0,1);
var q = new THREE.Quaternion().setFromUnitVectors( v, target );
var tmp = q.z;
q.z = -q.y;
q.y = tmp;
bone.quaternion.copy(q);
}
function lookAt() {
var v1 = new THREE.Vector3(0, 0, 1);
var v2 = new THREE.Vector3(
camera.position.x - headBone.matrixWorld.elements[12],
0,
camera.position.z - headBone.matrixWorld.elements[14]
).normalize();
var mult = 1.0;
if(camera.position.x - headBone.matrixWorld.elements[12] < 0.0000) {
mult = -1.0;
}
var fAng = v2.angleTo(v1) * mult;
v2 = new THREE.Vector3(
0,
camera.position.y - headBone.matrixWorld.elements[13],
camera.position.z - headBone.matrixWorld.elements[14]
);
mult = 1.0;
if(camera.position.y - headBone.matrixWorld.elements[13] > 0.0000) {
mult = -1.0;
}
fAng2 = v2.angleTo(v1) * mult;
headBone.rotation.set(
Math.max(-0.5, Math.min(fAng2, 0.1)),
0,
-Math.max(-1.0, Math.min(fAng, 1.0))
);
}
//head left and right to match camera
var Q1 = new THREE.Quaternion().setFromEuler( new THREE.Euler(0,0,-fAng), false );
//head up and down to match camera
var Q2 = new THREE.Quaternion().setFromEuler( new THREE.Euler(fAng2,0,0), false );
Q2.multiply(Q1);
headBone.quaternion.copy(Q2);
function boneLookAt(bone, position) {
var target = new THREE.Vector3(
position.x - bone.matrixWorld.elements[12],
position.y - bone.matrixWorld.elements[13],
position.z - bone.matrixWorld.elements[14]
).normalize();
var v = new THREE.Vector3(0,0,1);
var q = new THREE.Quaternion().setFromUnitVectors( v, target );
var tmp = q.z;
q.z = -q.y;
q.y = tmp;
bone.quaternion.copy(q);
}