旋转THREE.Group()后更新网格的位置

时间:2017-06-29 22:42:53

标签: three.js

我使用一个透视组来旋转我的飞行几何体,而不是单独旋转每一个。旋转枢轴组对象后,我想找到每个子/ planegeometry-mesh的新位置,以对应于相对于实际世界位置的位置。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

简单方法

就像Craig提到的那样,getWorldPositionObject3D(场景中几乎所有东西的基类)的函数,它返回对象世界位置的新Vector3。 / p>

var childPlaneWorldPosition = childPlane.getWorldPosition();

更难的方式:

有两种方法可以在本地和世界位置之间进行转换:localToWorldworldToLocal

这些也是Object3D上的功能,并带有Vector3。然后将该矢量(破坏性地)转换为所需的坐标系。只知道知道你给它的矢量是否已经在正确的坐标系中是不够聪明的 - 你需要跟踪它。

因此,要将子平面的位置从本地坐标转换为世界坐标,您可以这样做:

// clone because localToWorld changes the vector passed to it
var childPlanePosition = childPlane.position.clone();
childPlane.parent.localToWorld(childPlanePosition);

请注意,localToWorld的父级会调用childPlane。这是因为childPlane是其父级的本地,因此它的位置是其父级坐标系的本地位置。

难以理解的方式:

每个childPlane不仅存储其局部变换矩阵(childPlane.matrix),还存储其世界变换矩阵(childPlane.matrixWorld)。当然,您可以直接从matrixWorld属性获得世界排名。

var childWorldPosition = new THREE.Vector3(
  childPlane.matrixWorld.elements[12],
  childPlane.matrixWorld.elements[13],
  childPlane.matrixWorld.elements[14]
);

编辑以回答一些问题

如果我理解正确,我可以在pivot-group子数组中找到网格的”真实“位置吗?

是。如果你打电话:

pivotGroup.add(childPlane);

然后childPlane将列在pivotGroup.children数组中,您可以使用该数组迭代所有childPlane个对象

并将这些克隆到每个网格的位置对象?

如果您希望平面处于世界坐标(在场景中),但您使用上面的代码将它们添加到组中,那么它们不再是场景的直接子项。您需要将它们重新添加到场景中:

scene.add(childPlane);

然后应用他们计算的世界位置。那就是说,为什么不把它们留在小组中呢?

(你没有问过这个)“你如何将飞机作为场景的直接孩子,但将它们作为一组旋转?

嗯,你不会。但是,three.js通过将矩阵相乘来为每个平面得出最终的世界矩阵来进行该组旋转。因此,您可以通过创建旋转矩阵并将其应用于所有平面来手动执行相同的操作。

var rotMat = new THREE.Matrix4().makeRotationMatrix(x, y, z);
for(var i = 0; i < planesArray.length; ++i){ // I guess this would loop over your 3D array
  planesArray.applyMatrix(rotMat);
}

答案 1 :(得分:-1)

使用plane_mesh.getWorldPosition()