将父对象的旋转反转应用于子对象,使得子对象在世界空间中呈现为未旋转状态。

6
在THREE.js场景中,我有一个围绕旋转的父对象。这个父对象有子对象应该被位置锁定到他们父对象的旋转上,但它们自己的旋转需要独立并且不继承自父对象。
一个简单的例子是让子对象始终面向相机。
我的尝试是在子对象中“反转”父对象的旋转。也就是说:
# render loop
render = ->
  requestAnimationFrame(render)

  # Rotate the parent
  @parent.rotation.x += 0.01
  @parent.rotation.z += 0.02

  # Attempt to invert rotation of the parent, and fail :(
  for child in @children
    child.rotation.x = -@parent.rotation.x
    child.rotation.z = -@parent.rotation.z

这种天真的尝试的结果在此处。小黄飞机是灰色立方体的子元素,以我意料之外的方式旋转...

http://jsfiddle.net/b6jgS/

我希望这些平面一直是完美的正方形,随着立方体的旋转移动,但它们的旋转被锁定在世界上,而不是父级上。
那么我该如何取消子级中父级的旋转?我错过了什么疯狂的数学知识?
我知道我可以在这个例子中使用点精灵,但最终我有更复杂的需求,点精灵就不行了。所以我需要弄清楚如何用真正的3D对象来实现这个问题。

编辑:这个方法对每个轴单独使用是有效的。如果父级只在X轴上旋转,我可以在子级的X轴旋转上反转它,就像我想要的那样。同样适用于仅Z轴。然而,如果我开始变化并反转X和Z两者,那么它就会变得混乱不堪。


如果您想让子对象面向相机,请查看http://stackoverflow.com/questions/15603111/three-js-rotate-objects-inside-of-moving-object3d-to-always-face-the-camera。 - gaitat
"Object.lookAt()如果该对象有被旋转的父级,则无法正常工作。" 这确实是当前的情况,所以这并没有太大帮助 :( - Alex Wayne
顺便提一下:这个说法已经不正确了。自r96以来,OrbitControls也支持旋转的父级元素。 - Mugen87
1个回答

10

总会有诀窍。:-)

您想要父对象的子元素相对于父元素定位,但其旋转独立于父元素。

最简单的方法是将虚拟Object3D对象作为父对象的子元素,然后将子元素添加到场景(而不是父对象),并使子元素从虚拟对象获取它们的世界位置。

parent                 scene
   |                     |
   --- object_1          --- child_1
   |                     |
   --- object_2          --- child_2

child_1.positionobject_1 的世界位置设置:

child.position.setFromMatrixPosition( parent.children[ idx ].matrixWorld )

作为替代方案,你可以使用THREE.Gyroscope,但这会更加消耗计算资源。


好的,我明白了。我得记住那个 getPositionFromMatrix 方法。谢谢! - Alex Wayne
1
当旋转子对象时,如果父对象也旋转了,那么如何找到子对象的新位置? - Rishanthakumar
这个解决方案非常漂亮和完美,你也一样。 (但真的,谢谢!) - Kai Curtis

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