我在计算骨骼时遇到“查看”对象的问题。首先,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);
但是这仍然无法正确跟踪相机。请注意,应用其中一个确实有效。
答案 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);
}