【问题标题】:3D Scene graph traversing problem3D场景图遍历问题
【发布时间】:2011-07-12 20:50:14
【问题描述】:

我已经实现了一个由 OpenGL 渲染的小场景图,所有对象都派生自一个公共的 Node 类,在 OpenGL 帧渲染期间,我只调用根节点的 visit 方法,它递归地遍历图形.开始遍历时我传递的第一个矩阵是相机矩阵。

visit 方法如下所示:

void Node::visit(const QMatrix4x4 &mv) {
    QMatrix4x4 m = mv;
    m.rotate(m_rot);
    m.translate(m_pos);
    m.scale(m_scale);

    m_effectiveMV = m;

    for (int i = 0; i < m_children.size(); i++) {
        m_children[i]->visit(m_effectiveMV);
    }

    draw(); // draws if this node has anything to draw,
            // otherwise just transformation.
}

我遇到的问题是,当我为子节点设置旋转时,旋转是相对于父节点发生的,而不是围绕节点本身。谁能发现我在这里做错了什么?

【问题讨论】:

  • 我假设它是这样的:一个人拿着枪,枪围绕着这个人旋转,而不是在它自己的原点上“转动”。这是正确的吗?

标签: opengl 3d traversal scenegraph


【解决方案1】:

假设你的矩阵方法做对了,翻译应该是列表中的第一个:

m.translate(m_pos);
m.rotate(m_rot);
m.scale(m_scale);

这将首先缩放和旋转顶点,然后将其转换为父系统等等。

【讨论】:

  • 这样做似乎可以解决旋转轴问题,但它完全搞砸了我的相机位置。当我将相机放入 (0, 0, 8) 并且根节点位于相同位置时,看起来对象仍然比相机位置提前 8 个单位。我正在检查 QMatrix4x4 源代码 (qt.gitorious.org/qt/qt/blobs/4.7/src/gui/math3d/qmatrix4x4.cpp) 看它是否在做任何令人讨厌的事情,但我没有发现任何奇怪的东西。
  • 您能以某种方式发布您的空间层次结构吗?很难说你到底发生了什么。
  • 我原来是个菜鸟,并意识到我正在将默认构造函数中的默认旋转构造为 QQuaternion(0, 0, 0, 1) 因为我没有完全了解四元数工作。使用 QQuaternion::fromAxisAndAngle 初始化四元数后,一切正常。再次感谢关于转换顺序的建议。
【解决方案2】:

矩阵运算不可交换,即矩阵乘法发生的顺序很重要。先旋转,再平移,不同于先平移,然后围绕原始中心旋转/环绕。

我建议直接构建它,而不是通过连续应用各种转换来创建转换。左上角的3×3是旋转部分,可以直接从旋转矩阵中复制过来。缩放将 x、y、z 因子乘以矩阵的第 1、第 2 和第 3 列。翻译是第四栏。旋转存储为 3×3 矩阵或四元数。不要使用欧拉角,它们在数值上是不稳定的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2019-01-12
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多