2

OpenGLによってレンダリングされる小さなシーングラフを実装しました。すべてのオブジェクトは共通のクラスから派生し、NodeOpenGLフレームのレンダリング中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番目の列に乗算します。翻訳は4列目です。回転は、3×3行列またはクォータニオンとして保存されます。オイラー角は使用しないでください。数値的に不安定です。

于 2011-07-12T21:29:27.960 に答える