【问题标题】:Calculating matrix for bone to look at object in Three.js计算骨骼矩阵以查看 Three.js 中的对象
【发布时间】:2014-11-21 04:02:05
【问题描述】:

我在计算骨骼以“查看”对象时遇到问题。首先,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 的 worldMatrix:

 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 轴将其向左或向右移动到相机)但是当我尝试组合这 2 个旋转时,当我在两侧时,事情会变得混乱角色的头部开始旋转。

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

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

【问题讨论】:

    标签: javascript matrix three.js


    【解决方案1】:

    我得到了一个可以接受的答案。我找到了一种让骨骼看起来任意点的方法。也许这可以扩展并包含在 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 2014-12-15
      • 2017-05-05
      • 2013-10-02
      • 2015-04-03
      • 2016-07-31
      • 2014-10-16
      • 1970-01-01
      • 2012-02-24
      相关资源
      最近更新 更多