在 Three.js 中,物体怎么围绕自身中心旋转,而不是世界坐标中心?

Number of views 30

场景中我有两个模型对象,一个Cube跟一只高跟鞋。两个模型都希望围绕自身的中心位置旋转。

Cube是可以的,但是高跟鞋貌似围绕着世界坐标中心旋转。

我的原始代码如下:

cube.rotation.y += 0.01;
shoe.rotation.y += 0.01;

我在网络上找到了一个解决方案,代码如下:

cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
pivot.add(shoe);
pivot.rotation.y += 0.01;

但这种方法不起作用。于是,我调整了鞋子的位置:

cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
shoe.position.set(-5, 0, 0); // 修改鞋子的位置
pivot.add(shoe);
pivot.rotation.y += 0.01;

这种方式比较 hack,而且只针对我特意调整的物体,有没有什么好办法?

2 Answers

要在Three.js中使物体围绕自身中心旋转,而不是围绕世界坐标中心旋转,可以使用Object3D作为“轴心点”或“转轴”。你提到的方法基本上是正确的,只是需要确保将物体添加到轴心点时,物体的位置已经设置为相对于轴心点的正确位置。

以下是一个更通用和正确的实现方法:

  1. 创建一个Object3D作为轴心点。
  2. 将物体添加到轴心点,并将其位置设置为相对于轴心点的原点(即物体的中心)。
  3. 最后将轴心点添加到场景中。

以下是示例代码:

// 创建场景、相机和渲染器等...

// 创建轴心点
const pivot = new THREE.Object3D();

// 添加立方体到轴心点
cube.position.set(0, 0, 0); // 确保立方体位置相对于轴心点是(0, 0, 0)
pivot.add(cube);

// 添加高跟鞋到轴心点
shoe.position.set(0, 0, 0); // 确保高跟鞋位置相对于轴心点是(0, 0, 0)
pivot.add(shoe);

// 将轴心点添加到场景
scene.add(pivot);

// 在动画循环中更新旋转
function animate() {
    requestAnimationFrame(animate);

    cube.rotation.y += 0.01;
    shoe.rotation.y += 0.01;

    renderer.render(scene, camera);
}
animate();

在这个示例中,我们创建了一个名为pivotObject3D,并将立方体和高跟鞋添加到这个轴心点。由于我们将它们的位置设置为相对于轴心点的原点(即(0, 0, 0)),所以它们会围绕自己的中心旋转。

注意,你需要确保在添加立方体和高跟鞋到轴心点之前,它们的位置已经被设置为相对于轴心点的原点。这样,它们就会围绕自己的中心旋转,而不是围绕世界坐标中心旋转。

如果你的网格(mesh)没有围绕自身中心旋转,那是因为几何体的顶点相对于原点存在偏移。

1.可以通过使用边界框(bounding box)来定义一个合理的中心,然后调整网格的位置,如下所示:

var box = new THREE.Box3().setFromObject(mesh);
box.getCenter(mesh.position); // 这会重新设置网格的位置
mesh.position.multiplyScalar(-1);

然后将网格添加到一个旋转中心对象(pivot object)中:

var pivot = new THREE.Group();
scene.add(pivot);
pivot.add(mesh);

在你的动画循环中,旋转该旋转中心对象:

pivot.rotation.y += 0.01;

2.另一种解决方案是平移几何体的顶点,使几何体位于或靠近原点:

geometry.translate(distX, distY, distZ);

或者,你也可以直接调用以下方法:

geometry.center();

此方法会根据几何体的边界框自动将几何体的顶点居中。