Opengl 三维场景图遍历问题
我已经实现了一个由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帧渲染期间,我只调用根节点的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初始化四元数之后,一切正常。再次感谢您对转换顺序的建议。