Three.JS,改变子3D对象的世界位置

10

基本上,我有一个在Object3D组中的子对象3D,虽然子对象的[x,y,z]坐标相对于父对象的对象空间显示,但我想改变子对象在3D空间中的位置。所以,首先我会获取子对象相对于世界空间的位置。

var wrld_pos = childobject.matrixWorld.multiplyVector3(new THREE.Vector3);

这将返回一个三元素向量,表示子对象在世界空间中的位置。现在我希望自己设置位置,因此我创建了一个三元素向量。

var new_pos = THREE.Vector3();
new_pos.x = 1;
new_pos.y = 2;
new_pos.z = 3;

childobject.matrixWorld.setPosition(new_pos);

给出了setPosition函数的定义,它本质上是将对象的世界矩阵的最后三个元素设置为传递的向量的值,从而改变了对象在世界空间中的位置。为了确保矩阵在这些更改后更新,我调用以下函数。

childobject.matrixWorldNeedsUpdate = true;
childobject.updateMatrixWorld();

现在,在检查对象的新世界矩阵时,我注意到setPosition函数什么也没做,完全没有作用。

为什么?如果需要真实的代码示例,我可以提供。但是以上内容应该非常准确地代表了我使用的应用程序域和语法。

3个回答

14

编辑:回答已更新。


你想要改变一个子对象的世界坐标。

假设场景没有应用任何变换,实现你所需的方法可以采用以下模式:

scene.attach( child ); // detach from parent and add to scene

child.position.set( x, y, z );

parent.attach( child ); // reattach to original parent

Object3D.attach( child ) 方法会添加子对象,并保持子对象的世界变换。

three.js r.132


3
这就解释了为什么新的位置值没有被存储。但是这并不能解决问题,即改变对象的世界空间位置。 - sbadams
例如,我们有两个组对象,它们都是由10个立方体组成的环,并且我们想要从一个环中选择一个立方体与另一个环中的立方体交换位置,我们可以通过将原始立方体的位置设置为第二个立方体的位置来轻松实现这一点。不幸的是,由于立方体的位置是相对于父对象的原点并且受到在该对象上进行的任何旋转和更改的影响,将其本地坐标设置为其他环的坐标将只会将立方体发送到随机位置。 - sbadams
你想设置子对象的位置,以便在应用父对象的旋转矩阵后,子对象的新位置最终位于你指定的位置吗? - WestLangley
5
这不是一个答案。 - zwcloud
是的,那是一个旧答案。已更新答案。 - WestLangley

1

这个答案可能会对这个情况有所帮助。将子元素从父元素中移除,更改普通位置,然后重新附加。


0

如果在动画循环中使用attach来设置移动对象的位置,可能会导致对象抖动。

对我来说,最好的解决方案是:

let newPosition = new THREE.Vector3(1,2,3);
let parentPosition = new THREE.Vector3();
childobject.parent.getWorldPosition(parentPosition);
childobject.position.set(
    newPosition.x-parentPosition.x,
    newPosition.y-parentPosition.y,
    newPosition.z-parentPosition.z
);

如果您需要位置和旋转,attach 是唯一的方法。

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