Javascript 在Three.js中计算骨骼查看对象的矩阵

Javascript 在Three.js中计算骨骼查看对象的矩阵,javascript,matrix,three.js,Javascript,Matrix,Three.js,我在计算骨骼“看”对象时遇到问题。首先,lookAt函数不适合我。我可以理解这一点,因为骨骼的矩阵是一个单位矩阵,在局部空间中,所以它不会开箱即用。(注视会产生奇怪的结果) 以下是我迄今为止所做的努力。它将头部从左向右旋转,但上下我还没有计算。我要补充一点,目前它的工作效果不太好:( 更新 我已经更新了我的代码。当我在一个轴上旋转(x轴向相机上下移动头部或z轴向相机左右移动头部)时,它确实起作用,但当我尝试组合这两个旋转时,当我在角色的侧面时,头部开始旋转 function lookAt() {

我在计算骨骼“看”对象时遇到问题。首先,lookAt函数不适合我。我可以理解这一点,因为骨骼的矩阵是一个单位矩阵,在局部空间中,所以它不会开箱即用。(注视会产生奇怪的结果)

以下是我迄今为止所做的努力。它将头部从左向右旋转,但上下我还没有计算。我要补充一点,目前它的工作效果不太好:(

更新

我已经更新了我的代码。当我在一个轴上旋转(x轴向相机上下移动头部或z轴向相机左右移动头部)时,它确实起作用,但当我尝试组合这两个旋转时,当我在角色的侧面时,头部开始旋转

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);
}