2011-07-12 129 views
2

我已經實現了一個由OpenGL渲染的小場景圖,所有對象都來自一個普通的Node類,在OpenGL幀渲染期間,我只是調用了根節點的visit方法,並且它遍歷了圖遞歸。開始遍歷時,第一個矩陣是攝像機矩陣。3D場景圖遍歷問題

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

的問題,我的經驗是,當我一個子節點設置旋轉,旋轉恰好相對於父節點,而不是周圍的節點本身。任何人都可以發現我在這裏做錯了嗎?

+0

我認爲這是這樣的:一個男人拿着槍,槍圍繞着男人轉動,而不是在自己的起源「轉向」。它是否正確? – ssell

+0

是的,就是這樣。 – rgngl

回答

5

假設你的矩陣方法做正確的事,翻譯應該是在列表中的第一個:

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

這將第一縮放和旋轉頂點,然後等翻譯成家長制。

+0

這樣做似乎可以修復旋轉軸問題,但隨後它完全混亂了我的相機位置。當我已經將相機放入(0,0,8)並且根節點處於相同位置時,它仍然看起來像物體在相機位置前8個單位。我正在檢查QMatrix4x4源代碼(http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/math3d/qmatrix4x4.cpp),看看它是否做了任何討厭的事情,但我沒有發現任何東西奇怪的。 – rgngl

+0

你能以某種方式發佈你的空間層次嗎?很難說出你的結局是怎麼回事。 – kvark

+0

我原來是一個總noob,並意識到我構造默認構造函數中的默認旋轉爲QQuaternion(0,0,0,1),因爲我沒有完全知道四元數是如何工作的。在使用QQuaternion :: fromAxisAndAngle初始化四元數後,一切正常。並再次感謝有關轉換順序的建議。 – rgngl

3

矩陣運算是不可交換的,即矩陣乘法發生的順序很重要。首先旋轉某個東西,然後翻譯它,不同於先旋轉然後圍繞原始中心旋轉/旋轉。

而不是通過連續應用各種轉換創建轉換,我建議直接構建它。左上角的3×3是旋轉部分,可以直接從旋轉矩陣中複製。縮放將x,y,z因子乘以矩陣的第1列,第2列和第3列。翻譯是第四列。旋轉或者存儲爲3×3矩陣或者四元數。不要使用歐拉角,它們在數值上不穩定。