2

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

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

4

2 回答 2

6

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

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

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

于 2011-07-12T21:14:46.603 回答
4

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

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

于 2011-07-12T21:29:27.960 回答