在Three.js中,使用lookAt()和worldToLocal()方法使子对象朝向摄像机旋转。

4

我在使用three.js中的lookAt()方法时遇到了问题。我的对象结构是这样的:

var obj1 = new THREE.Object3D();
obj1.position.x=200;
obj1.rotation.x=0.1;
scene.add(obj1);

var obj2 = new THREE.Object3D();
obj2.position.y=-400;
obj2.rotation.y=0.21;
obj1.add(obj2);

var obj3 = new THREE.Object3D();
obj3.position.z=-200;
obj3.rotation.x=0.1;
obj3.rotation.y=-0.1;
obj2.add(obj3);

当我调用时
obj1.lookAt(camera.position);

它的运行正常,但当我从子对象中调用该方法时,比如

obj3.lookAt(camera.position);

旋转方向错误。

由于父对象的旋转似乎是问题所在,我考虑将相机的世界位置转换为对象的本地位置,但我没有正确地得到它工作。

var vector = new THREE.Vector3();
vector.setFromMatrixPosition( camera.matrixWorld );
obj3.lookAt( obj3.worldToLocal( vector ) );

任何帮助都将是非常棒的。

Object3D.lookAt() 不支持具有旋转和/或平移父级的对象。可能会有一些解决方法。你的任何对象是否具有非均匀缩放(例如,object.scale.set(1, 2, 3))? - WestLangley
应用的对象没有比例尺。 - user3271566
我不能给你一个“答案”,因为以下方法并不总是正确的,但这里有个概念:THREE.SceneUtils.detach( child, parent, scene ); child.lookAt( world_space_target.position ); THREE.SceneUtils.attach( child, scene, parent ); 通过使用调试器逐步执行,您可以清楚地了解所涉及的问题。 - WestLangley
1个回答

0

只需添加这些原型,然后用 .lookAtWorld(vector) 替换 .lookAt(vector)

THREE.Object3D.prototype.worldToLocal = function ( vector ) {
    if ( !this.__inverseMatrixWorld ) this.__inverseMatrixWorld = new THREE.Matrix4();
    return  vector.applyMatrix4( this.__inverseMatrixWorld.getInverse( this.matrixWorld ));
};


THREE.Object3D.prototype.lookAtWorld = function( vector ) {
   vector = vector.clone();
   this.parent.worldToLocal( vector );
   this.lookAt( vector );
};

1
(1) lookAt() 使用 'up' 属性来确保对象保持竖直。你的方法没有做到这一点。 (2) 避免使用 clone(),因为它调用了 new。如果必须使用,请改用闭包。 - WestLangley
@WestLangley,您会推荐哪个解决方案? - Rylan Schaeffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接