3D场景图遍历问题

发布于 2024-11-23 19:24:01 字数 645 浏览 5 评论 0原文

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

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

I have implemented a small scene graph to be rendered by OpenGL, all the objects derive from a common Node class and during OpenGL frame rendering I just call the visit method of the root node and it traverses the graph recursively. The first matrix I pass when beginning traversal is the camera matrix.

The visit method looks like this:

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.
}

The problem I experience is, when I set rotation for a child node, the rotation happens relative to the parent node, not around the node itself. Can anyone spot what I'm doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深府石板幽径 2024-11-30 19:24:01

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

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

这将首先缩放和旋转顶点,然后将其翻译到父系统中,依此类推。

Assuming your matrix methods are doing the right thing, translation should be the first one in the list:

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

This will first scale and rotate the vertex, then translate it into the parents system and so on.

晚风撩人 2024-11-30 19:24:01

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

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

Matrix operations are not commutative, i.e. the order in which matrix multiplication happens does matter. Rotating something first, then translate it, is different to first translating and then rotate/orbit around the original center.

Instead of creating the transformation by successive application of various transformations I recommend building it directly. The upper left 3×3 is the rotation part, which you can copy directly from the rotation matrix. Scaling multiplies x,y,z factors to the 1st, 2nd and 3rd column of the matrix. Translation is the 4th column. The rotation is either stored as a 3×3 matrix or a quaternion. Don't use Euler angles, they are numerically instable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文