如何以相同的顺序将父变换应用于子元素?

时间:2016-12-07 16:08:58

标签: javascript three.js

在我的应用程序中,用户可以在工作平面上选择3d对象,以便使用"转换"来缩放,移动或旋转这些元素。容器,即Object3D,它对所有转换进行分组并将这些转换应用于所有子项。取消选择子元素时,父容器的转换应该转移到所有子节点,而子节点又从变换容器中移除并添加回主场景对象。

然而,当变换容器中的变换被应用于容器而不是元素本身时,子元素被不同地变换。当一个比例变换应用于具有局部旋转的子容器时,它看起来首先应用局部旋转,然后是容器的比例变换。
将父级转换应用于child.applyMatrix(parent.matrixWorld)的所有子项并将子项放回场景容器时,转换顺序将反转。

  1. container [scale] {child [rotation]} - >顺序:旋转,缩放
  2. child.applyMatrix(parent.matrixWorld)
  3. child [scale,rotation] {} - >顺序:缩放,旋转
  4. 我需要对子元素做什么才能获得相同的转换顺序和外观结果?

    更新
    我想出了如何正确地将父母的变换应用于孩子。我使用了来自Object3D.applyMatrix()的相同代码:
    child.matrix.multiplyMatrices(parent_old.matrixWorld, child.matrix);但也设置了child.matrixAutoUpdate = false;并遗漏了child.matrix.decompose(child.position, child.quaternion, child.scale);

    因此,matrixAutoUpdate = true不起作用。在设置Matrix4.decompose()positionscale之前,quaternion以某种方式更改了矩阵值,因此在我的示例中,通过父级缩放变换应用内部子项的剪切变换重置。

    对我来说,这看起来不一致,因为在使用嵌套对象转换时允许并显示这种转换。此外,使用child.applyMatrix(parent.matrixWorld)将父变换应用于子对象(我经常读作为此目的的解决方案)将是不正确的。我不知道这是否是three.js的预期行为。如果是这样,有人可以解释原因吗?

1 个答案:

答案 0 :(得分:1)

感谢@WestLangley和提供的THREE.js postSO answer我为我找到了解决方案。我遇到的问题是由于THREE.js的设计理念

  

representing an object's transform with a position, quaternion/rotation, and scale -- applied in the order S-R-T.

简单地说,当在对象的父级上应用非均匀缩放时,此顺序会更改,并且无法从对象的变换矩阵映射回方便的positionscale和{{1} } properties。

我的解决方案是

  

represent the object transform with a matrix only.

这意味着我设置了我的3d对象'quaternion,并且不再使用上面提到的位置,比例,四元数属性。相反,我只使用matrixAutoUpdate = false方法直接在对象的矩阵上设置任何变换。