2011-11-06 69 views
5

我想爲我的3D遊戲創建一個場景圖,其中每個對象的變換都是相對於它的父元素的。圖形的每個節點都有一個旋轉,縮放和平移矢量。3D相對於絕對變換

將相對變換矩陣組合以獲得對象的絕對變換的正確方法是什麼?如果您也可以解釋您的解決方案,我會很高興。


這裏是做一個例子是錯誤的:
這實際上原來是溶液:

Matrix GetAbsoluteTransformation() 
{ 
    if (!this.IsRoot()) 
    { 
     return this.Transformation * this.Parent.GetAbsoluteTransformation(); 
    } 
    else 
    { 
     return this.Transformation; 
    } 
} 

在這種情況下,當父節點旋轉,縮放或移動,孩子變成了相同的數量,這是一個正確的行爲! 但是,孩子只會圍繞自己的原點旋轉,不會圍繞父母的原點移動。


應用:

有一個汽車模型有四個輪子。車輪相對位於汽車的原點周圍。車輪可以像真實車輪一樣旋轉。如果我現在旋轉汽車,車輪應始終保持與其連接。在這種情況下,汽車是根,車輪是兒童節點。

另一個例子是太陽系的模型。行星圍繞自己的軸旋轉,圍繞太陽移動,並且衛星在行星周圍移動。

+0

原來,我的第一個想法是如何做到這一點,然後我認爲不適合,實際上是解決方案!我花了幾個小時試圖解決這個問題。 * facepalm * 感謝大家的快速和準確的幫助! – Lucius

回答

3

至於你的「怎樣做不對」,我不想打破它給你,但它沒有錯;相反,它不完整。你需要做這些獨立於父母子女關係的工作。

下面是一個例子:車輪就像你剛纔提到的那樣附着在車上。如果您翻譯或旋轉汽車,則無需觸碰車輪 - 它們位於相對於汽車的相同位置。但是,當您嘗試在「現實世界」中獲取車輪的新位置時,必須沿着樹遍歷,隨時應用矩陣變換。這一切正常,對嗎?

當您旋轉一個對象時,它圍繞它自己的原點旋轉。所以一個車輪應該繞着它的y軸旋轉,並且一個行星繞着它的z軸旋轉。但是現在如果你需要在「太陽周圍」移動一個星球,那麼你正在做一些完全不同的事情。這必須單獨計算。這並不是說通過使用已有的相同比賽不會緩解這種情況(儘管我自己不能肯定地說沒有做數學),但它完全不同。

您正在查看實際更改對象的狀態。這就是場景圖的美麗!如果你沒有一個場景圖,你將不得不找出所有不同的值,直到回到主場景,然後進行各種數學運算。在這裏,你只需要做一點觸發和代數就可以在地球上移動(你可以谷歌天體力學),並將行星相對於它的恆星移動。主場景下一次詢問這個星球在哪裏時,它將會下降到場景圖上! :-D

+0

我認爲這是最好的答案。我原來的做法是正確的,我現在不知道爲什麼我認爲它是錯的(太簡單了嗎?:D)你對行星旋轉也是正確的:我現在包括一個處理太陽周圍旋轉的附加節點。非常感謝你! – Lucius

+0

如果太陽轉動,行星將隨着這個矩陣代數而旋轉。正向運動學。 – stefan

+0

@Stefan顯然,太陽應該簡單地成爲太陽系的一個孩子,就像行星一樣,並且以原點爲中心。 – corsiKa

1

我認爲這是正確的行爲。

我不認爲圍繞父母的起源旋轉是可以用簡單的矩陣堆棧來實現的。我認爲你只能從父母傳播給孩子。

您可以嘗試改爲設置相對旋轉和基於父母絕對原點的偏移量的轉換,儘管這比單純推入矩陣堆棧的計算多得多。

這裏有一個類似的問題:Getting absolute position and rotation from inside a scene graph?

+0

謝謝!也正確! :) – Lucius

1

這取決於您使用的是OpenGL還是Direct3D。在OpenGL中,變換從右到左應用,而在Direct3D中,它們應用從左到右。它們都是設計變換系統的完美有效方式,但它意味着你必須以不同的方式思考它們。

我覺得最容易想到在OpenGL的體系,但在相反的。我想象的是從左到右順序變換對象的座標系,而不是思考如何從左到右應用變換時對象的頂點如何移動。每個變換都相對於新的局部座標系應用,而不是相對於世界。

在汽車上的車輪的情況下,有三個轉換涉及:汽車在空間中的位置,一個車輪相對於汽車的起源,和車輪的相對中間位置的方向。只需按照從左到右的順序應用這些(或者Direct3D反之亦然)。要繪製四個輪子,首先應用汽車的變換,然後記住當前的變換,然後依次應用位置和方向變換,然後在每個變換之後回到記憶的汽車變換。

+0

我不確定這個答案是否完全符合我的問題。但是,我仍然不知道這種差異,所以謝謝! :) – Lucius

+0

我相信這些是默認設置,如果需要,您可以將它們翻轉。至少我確定你可以在OpenGL中使用。 –

+0

@用戶從Marcelos的回答中得到的最好結果是,有大量的開發人員正在使用大量的框架,並且您應該考慮使用其中的一個來完成繁重的工作你的系統。它們不僅可以節省您數小時的調試時間(請注意,您可以花更多的時間來製作自己的小時數),而且您的簡歷中還會有一個非常適合市場且有利可圖的技能! – corsiKa