3D相对于绝对变换

时间:2011-11-06 21:35:02

标签: matrix hierarchy transformation scenegraph

我正在尝试为我的3D游戏创建一个场景图,其中每个对象的变换都是相对于它的父级。图的每个节点都有一个旋转,缩放和平移向量。

组合相对转换矩阵以获得对象的绝对转换的正确方法是什么?如果你能解释一下你的解决方案,我会很高兴。


这是一个做错的例子:
这实际上是解决方案:

Matrix GetAbsoluteTransformation()
{
    if (!this.IsRoot())
    {
        return this.Transformation * this.Parent.GetAbsoluteTransformation();
    }
    else
    {
        return this.Transformation;
    }
}

在这种情况下,当父节点被旋转,缩放或移动时,子节点被转换为相同的量,这是正确的行为! 但是孩子只会围绕自己的原点旋转而不会绕着父母的原点移动。


应用:

有一个带四个轮子的车型。车轮相对定位在汽车原点周围。车轮可以像真正的车轮一样旋转。如果我现在旋转汽车,车轮应始终保持与之相连。在这种情况下,汽车是根,轮子是子节点。

另一个例子是太阳系的模型。行星围绕自己的轴旋转,围绕太阳移动,卫星围绕行星移动。

3 个答案:

答案 0 :(得分:3)

关于你的“如何做错”,我讨厌打破它,但这没有错;相反,它是不完整的。您需要独立于父子关系进行这些工作。

以下是一个例子:车轮就像你提到的那样连在车上。如果您翻译或旋转汽车,则无需触摸车轮 - 它们位于相对于汽车的位置。但是,当您尝试在“真实世界”中获取轮子的新位置时,您必须遍历树,随后应用矩阵变换。这一切都有效,对吧?

旋转对象时,它会围绕其OWN原点旋转。因此,轮子应该围绕其y轴旋转,并围绕其z轴旋转行星。但是现在,如果你需要“围绕太阳”移动行星,那么你正在做一些完全不同的事情。这必须单独计算。这并不是说通过使用你已经拥有的一些相同的匹配不会减轻它(虽然我不能肯定地说没有自己做数学),但它完全不同。

您正在考虑实际更改对象的状态。这就是场景图的美妙!如果你没有场景图,你必须找出所有各种值,一直到主场景,然后进行各种数学运算。在这里,你只需要做一点三角和代数来绕行星移动(你可以谷歌天体力学)并相对于它的恒星移动行星。下一次主场景询问行星在哪里时,它将沿着场景图形向下移动! :-D

答案 1 :(得分:1)

我认为这是正确的行为。

我不认为围绕父母的原点旋转是可以用简单的矩阵堆栈完成的。我想你只能从父母那里传播给孩子们。

您可以尝试根据父亲的绝对原点的偏移来设置相对旋转和变换,尽管这比简单地推入矩阵堆栈要多得多。

这是一个类似的问题:Getting absolute position and rotation from inside a scene graph?

答案 2 :(得分:1)

这取决于您使用的是OpenGL还是Direct3D。在OpenGL中,变换从右到左应用,而在Direct3D中,它们从左到右应用。它们都是设计变换系统的完美有效的方法,但这意味着你必须以不同的方式思考它们。

我发现在OpenGL的系统中思考最简单,但相反。当从右到左应用变换时,我不会考虑对象的顶点如何移动,我想象对象的坐标系是按从左到右的顺序变换的。每个变换都相对于新的局部坐标系应用,而不是相对于世界。

对于汽车上的车轮,涉及三种变换:汽车在空间中的位置,车轮相对于汽车的原点,以及车轮相对于其中立位置的方向。只需按从左到右的顺序应用这些(或反之亦然,适用于Direct3D)。要绘制四个轮子,首先应用汽车的变换,然后记住当前的变换,然后依次应用位置和方向变换,在每个变换后返回到记忆的汽车变换。