three.js父子目标跟踪

时间:2013-03-27 16:43:35

标签: matrix rotation three.js tracking quaternions

所以,这里是three.js大师的向量,矩阵,旋转,四元数问题!

我的position(0,0,275)父对象有direction(0,0,-1),+ y和rotation(0,0,0)

附加到父级是具有关系的子对象:

 rel_position(.5, 0, 0)
 rel_rotation(0, 0, 0)

我在场景中也有一个目标:

 position(0, 100, 0)

考虑具有俯仰,偏航和俯仰的船(父母)。它有一个有俯仰和偏航的炮塔(儿童)。炮塔需要以给定的转速(rad / s)跟踪目标。

我花了5天试图获得正确的跟踪算法。我能做的最好的是删除父和子手动更新矩阵的matrixAutoUpdate功能。然后使用child.matrixWorld为当前子旋转创建旋转矩阵或四元数。然后我可以创建一个辅助Object3D,它从子位置查看目标。我可以在子节点和辅助Object3D之间取差异,并以rad / s为基础对四元数进行slerp。但是,当我向父项添加滚动或者目标在八分圆(+, +, +)之外旋转时,子旋转(或四元数)计算崩溃会导致旋转。

对于儿童Object3D的跟踪算法的任何指示都将非常受欢迎。您的努力将在我即将开展的项目中引用。

感谢您的时间!

2 个答案:

答案 0 :(得分:3)

所以这就是答案! @Stemkoski,谢谢你的指导。我采取了类似的方法来解决昨天曝光的最终解决方案。由于反转矩阵,计算能力有点昂贵,但效果很好。首先,按如下方式创建一个新矩阵:

var m = new THREE.Matrix4().getInverse(parent.matrix).multiply(target.matrix);  

这基于父对象的旋转将XYZ轴的参考系旋转到新坐标X'Y'Z'。结果是X'Y'Z'的参考系中的目标的Object3D矩阵。现在,通过从矩阵“m”创建一个新的Vector3,我们可以使用以下方法获得相对位置:

var rel_pos = new THREE.Vector3().getPositionFromMatrix(m, 'XYZ');

现在创建一个Faux对象,从孩子的位置直接看目标(炮塔)

var child_faux = new THREE.Object3D();  //can be created outside the loop
child_faux.position.copy(child.position);   //copy the child local position
child_faux.lookAt(rel_pos);     //look at the target 
child_faux.updateMatrix();     //Update the Matrix4 element for use in a second

最后,通过将child_fuax设置为lookAt对象,我们自动设置了child_faux.rotation。我们可以使用以下命令获取当前child.rotation和child_faux.rotation之间的相对旋转:

var diff = turret_target.rotation.sub(turret.rotation);

从这里我们可以设置一个简单的算法来旋转炮塔(+或 - )(x和y),直到diff(x和y)变为0。

var trackrate = .2 * delta;
var diff = turret_target.rotation.sub(turret.rotation);
turret.rotation.x += diff.x/Math.abs(diff.x) * trackrate;
turret.rotation.y += diff.y / Math.abs(diff.y) * trackrate;
turret.updateMatrix();

我们有它...在父组中旋转的子对象的目标跟踪算法!谢谢你的阅读!

答案 1 :(得分:1)

也许lookAtworldToLocal方法的某种组合可行?由于你需要将目标物体的位置转换为炮塔的局部坐标,然后相应地改变炮塔的旋转,这个怎么样:

turret.lookAt(  turret.worldToLocal( target.position.clone() )  )