3D场景图遍历问题

时间:2011-07-12 20:50:14

标签: opengl 3d traversal scenegraph

我实现了一个由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.
}

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

2 个答案:

答案 0 :(得分:5)

假设您的矩阵方法做得正确,翻译应该是列表中的第一个:

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

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

答案 1 :(得分:3)

矩阵运算不是可交换的,即矩阵乘法发生的顺序很重要。首先旋转某些东西,然后进行平移,与首先进行平移然后围绕原始中心旋转/轨道不同。

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