所以,这里是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的跟踪算法的任何指示都将非常受欢迎。您的努力将在我即将开展的项目中引用。
感谢您的时间!
答案 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)
也许lookAt
和worldToLocal
方法的某种组合可行?由于你需要将目标物体的位置转换为炮塔的局部坐标,然后相应地改变炮塔的旋转,这个怎么样:
turret.lookAt( turret.worldToLocal( target.position.clone() ) )