Opengl 三维场景图遍历问题

Opengl 三维场景图遍历问题,opengl,3d,traversal,scenegraph,Opengl,3d,Traversal,Scenegraph,我已经实现了一个由OpenGL渲染的小场景图,所有对象都来自一个公共的节点类,在OpenGL帧渲染期间,我只调用根节点的visit方法,它递归地遍历该图。开始遍历时我传递的第一个矩阵是摄影机矩阵 visit方法如下所示: void Node::visit(const QMatrix4x4 &mv) { QMatrix4x4 m = mv; m.rotate(m_rot); m.translate(m_pos); m.scale(m_scale);

我已经实现了一个由OpenGL渲染的小场景图,所有对象都来自一个公共的
节点
类,在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.
}
void节点::访问(常量QMatrix4x4&mv){
QMatrix4x4 m=mv;
m、 旋转(旋转);
m、 翻译(m_pos);
m、 标度(m_标度);
m_有效mv=m;
对于(int i=0;i访问(m_有效MV);
}
draw();//绘制如果此节点有任何要绘制的内容,
//否则就只是转换。
}

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

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

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

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

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


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

我假设是这样的:一个人拿着枪,枪围绕着这个人旋转,而不是“转动”自己的原点。这是正确的吗?这样做似乎解决了旋转轴的问题,但它完全搞乱了我的相机位置。当我将相机放置在(0、0、8)中,并且根节点处于相同位置时,对象看起来仍然比相机位置高出8个单位。我在检查QMatrix4x4源代码()看它是否有什么不好的地方,但我看不出有什么奇怪的地方。你能以某种方式发布你的空间层次结构吗?很难说你那边发生了什么。我原来是个十足的傻瓜,意识到我在默认构造函数中将默认旋转构造为Q四元数(0,0,0,1),因为我不完全了解四元数是如何工作的。在使用QQuaternion::fromAxisAndAngle初始化四元数之后,一切正常。再次感谢您对转换顺序的建议。