three.js object3d操作顺序

时间:2018-03-31 09:15:22

标签: javascript three.js

我正在尝试使用three.js构建一个旋转木马。我加载了我的马模型并希望将其克隆8次并将其以相等的间隔放置在一个圆圈中。我知道我可以使用数学,sin和cos函数来做到这一点,但我想尝试一些不同的东西而且我无法使它工作。

基本上我想做的是将马放在一个地方,旋转旋转木马物体,然后将下一匹马放在同一个地方。我想如果我这样做,因为旋转木马旋转,它会将每匹马放在旋转木马的不同位置。

根据我的理解,最终发生的事情是,首先它会添加所有的马(并让它们重叠),然后它会完成所有的旋转。因此我只看到一匹马。这真的发生了吗?什么可以解释这个?我该如何解决这个问题?

这是我的代码:

for(var i = 0; i < NUM_HORSES; i++){
  merryGoRound.rotateY(-2*Math.PI/NUM_HORSES);
  var horseCopy = horse.clone();
  horseCopy.translateZ(MERRY_GO_ROUND_RADIUS);
  merryGoRound.add(horseCopy);
}
scene.add(merryGoRound);
render();
马,因此horseCopy是THREE.Object3D。我试过让merryGoRound成为THREE.Object3D或THREE.Group但它们都给出了相同的结果。

非常感谢任何帮助

1 个答案:

答案 0 :(得分:1)

如果将对象a添加到另一个对象b(THREE.Group或任何其他THREE.Object3D),则a的位置始终被解释为相对于对象b的原点和变换。这是具有这种层次结构的重点(否则当旋转时对象不能与父对象一起旋转,你的旋转木马会很无聊)。

你想要的是在世界空间中指定坐标(“这是我想要那匹马的确切位置,无论旋转木马如何旋转”)并将此位置重新解释为相对于旋转木马。您可以使用worldToLocal - 函数在three.js中执行此操作。

所以在你的例子中:

var position = new THREE.Vector3(0,0,MERRY_GO_ROUND_RADIUS);
for(var i = 0; i < NUM_HORSES; i++){
  var horseCopy = horse.clone();

  merryGoRound.rotateY(-2 * Math.PI / NUM_HORSES);
  merryGoRound.updateMatrixWorld();

  // set the position in worldspace-coordinates
  horseCopy.position.copy(position);
  // convert from worldspace to objectspace
  merryGoRound.worldToLocal(horseCopy.position);
  merryGoRound.add(horseCopy);
}
scene.add(merryGoRound);