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

时间:2014-11-18 19:51:57

标签: javascript matrix three.js

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

以下是我的目标。它将头部从左向右旋转,但是我还没有计算出来。我应该补充一点,目前它不能很好地运作:(

    //local looking forawrd vector
    var v1 = new THREE.Vector3(0, 0, 1);
    //vector represting camera in local space?
    var v2 = new THREE.Vector3(
        camera.position.x - headBone.matrixWorld.elements[12], 
        0, 
        camera.position.z - headBone.matrixWorld.elements[14]
    );
    v2.normalize();
    //seem to need this to determine whether to rotate left or right
    var mult = 1.0;
    if(camera.position.x - headBone.matrixWorld.elements[12] < 0.0000) {
        mult = -1.0;
    }
    var fAng = v1.angleTo(v2) * mult;
    //var headUD = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0), 0.0);
    headBone.quaternion.setFromAxisAngle(new THREE.Vector3(0,0,-1), fAng);
    //headBone.quaternion.multiply(headUD);

关于如何正确地做到这一点的建议将是非常明确的,因为我现在无法弄清楚数学。与此同时,我将继续做一些感觉就像乱砍的事情......

如果有帮助,下面是headBone静止的世界矩阵:

 0.9950730800628662,      -0.02474924363195896,   0.09600517153739929,   0
-0.09914379566907883,     -0.2472541183233261,    0.9638656973838806,    0
-0.00011727288801921532,  -0.9686352014541626,   -0.24848966300487518,   0
 0.5000047087669373,       1.5461946725845337,   -0.01913299970328808,   1

更新

我已更新了我的代码。当我在1轴上旋转时(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))
    );

} 

我可以像这样分离出四元数:

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

但是这仍然无法正确跟踪相机。请注意,应用其中一个确实有效。

1 个答案:

答案 0 :(得分:0)

我已经达成了可接受的答案。我找到了一种让骨骼看起来任意一点的方法。也许这可以扩展并包含在THREE.js中。

这仍然存在问题,似乎并不是100%准确。例如,我将它放在我的头骨上,当我指向角色后面时,它会颠倒过来。有谁知道它是如何改进的?请评论!

另请注意,我指向骨骼的Z轴THREE.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);
}