0

所以,这里有一道向量、矩阵、旋转、四元数的题供three.js高手们答疑解惑!

我有一个父对象position(0,0,275)with direction(0,0,-1), +y up 和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 的基础上对四元数进行分析。但是,当我将滚动添加到父对象或目标旋转到八分圆之外时(+, +, +),子旋转(或四元数)计算会崩溃,从而导致疯狂旋转。

对于子 Object3D 的跟踪算法的任何方向将不胜感激。我即将进行的项目中将引用您的努力。

感谢您的时间!

4

2 回答 2

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

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

于 2013-03-28T14:04:21.283 回答
1

lookAt也许和方法的某种组合worldToLocal会起作用?由于需要将目标物体的位置转换为炮塔的局部坐标,然后相应地改变炮塔的旋转,这样如何:

turret.lookAt(  turret.worldToLocal( target.position.clone() )  )
于 2013-03-28T04:07:22.870 回答