2009-08-01 42 views
2

我一直在空間模擬一段時間了。 起初我使用我自己的3D引擎與軟件光柵器。旋轉太空模擬器/遊戲太空船模型

但是,當實施紋理的時間到期時,我放棄了。 現在我在某段時間後重新開始,現在我正在使用Opengl(使用SDL)來渲染3D模型。

但現在我打了另一堵磚牆。

我無法弄清楚如何進行適當的旋轉。 作爲一個空間模擬器我想類似的控制使用

glRotatef(angleX, 1.0f, 0.0f, 0.0f); 
glRotatef(angleY, 0.0f, 1.0f, 0.0f); 
glRotatef(angleZ, 0.0f, 0.0f, 1.0f); 

或相似,
不正確,如果我旋轉模型(飛船)第90度工作向左,然後flighsim

旋轉它「向上」。 它會滾動。

下面是一個圖像,說明我的問題。

Image Link

我試了幾個招數,試圖解決這個,但不知何故,我覺得我失去了一些東西。 它不能幫助模擬器樣式旋轉的例子幾乎不可能找到。

因此,我正在尋找示例,鏈接和旋轉3d模型(如飛船,飛機)的理論。

我是否應該使用3個向量(左,上,前)作爲方向,因爲我還必須計算諸如推力器的加速度以及隨着旋轉(方向?)和模型透視點像火箭發動機這樣的方向。

我不是很好的數學和努力可視化解決方案只給出頭痛

+0

我終於破解了! 我使用描述模型方向的矩陣。 當我按下向上鍵時,一個函數調用創建一個旋轉矩陣的函數,我旋轉x所需的量,然後將其乘以模型方向矩陣。 – kvasan 2009-08-06 03:54:10

回答

2

你會想在這裏使用什麼是四元。它們消除了你正在經歷的奇怪行爲。將它們想象成具有類似功能的類固醇的矩陣。通過使用任何OpenGL功能,您可以更好地使用矩陣(在上面的代碼中),使您可以在特定的旋轉軸矢量上創建旋轉矩陣,但是四元數會將您的旋轉存儲爲未來的修改。例如,您從身份四元數開始,並將其旋轉到特定的軸向量上。四元數然後被轉換爲你的對象的世界矩陣,但是你保持四元數存儲在你的對象中。下次需要執行旋轉時,只需進一步修改該四元數,而不必嘗試跟蹤X,Y和Z軸的旋轉角度等。

我的經驗是在directx中(對不起,沒有OpenGL在這裏體驗),儘管當我試圖旋轉在他們遇到地板,牆壁和彼此時旋轉的房間&旋轉的沙灘球時,我曾遇到過您的問題。

谷歌有一堆的「OpenGL的四元」的選項,但是這一點,特別是,似乎是一個很好的來源:

http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation

正如您現在可能已經猜到了,四元數是偉大的在您的環境中處理相機。這裏有一個很好的教程:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class

4

我不知道我完全理解的情況,但它聽起來像是你可能會描述gimbal lock。你可能想看看使用quaternions來代表你的旋轉。

+0

我一直在嘗試四元數,但再次嘗試。 好吧,它似乎使旋轉更正確,但是現在當我旋轉它時,盒子會變得有點扭曲。 – kvasan 2009-08-02 19:46:52

4

獲得這個權利當然是一個挑戰。我認爲你面臨的問題是你正在使用相同的變換矩陣進行旋轉,而不管'船'是如何定位的。但是你不想旋轉你的飛船,當它面向前方時它將會轉動,你想根據它現在面對的方式旋轉。要做到這一點,你應該像轉換你的船一樣轉換你的控制轉矩陣。例如,假設我們有三個矩陣,每個矩陣代表我們想要做的轉動。

float theta = 10.0*(pi/180.0) 

matrix<float> roll = [[ cos(theta), sin(theta), 0] 
         [ -sin(theta), cos(theta), 0] 
         [ 0, 0, 1] 

matrix<float> pitch = [[ cos(theta), 0, sin(theta)] 
         [ 0, 1, 0] 
         [ -sin(theta), 0, cos(theta)] 

matrix<float> yaw = [[1, 0, 0] 
        [0, cos(theta), sin(theta)] 
        [0, -sin(theta), cos(theta)]] 

matrix<float> orientation = [[1, 0, 0] 
          [0, 1, 0] 
          [0, 0, 1]] 

每個代表三個飛行姿態軸中每一個的10度旋轉。此外,我們還爲您的船舶定位提供矩陣,最初只是向前邁進。您將通過該方向矩陣變換您的船的頂點以顯示它。

然後到後一個轉身讓你的方向,你需要做的只是有點小聰明的,第一變換姿態控制矩陣轉換成玩家的座標,然後應用到定向得到一個新的方向:像

function do_roll(float amount): 
    matrix<float> local_roll = amount * (roll * orientation) 
    orientation = orientation * local_roll 

function do_pitch(float amount): 
    matrix<float> local_pitch = amount * (pitch * orientation) 
    orientation = orientation * pitch_roll 

function do_yaw(float amount): 
    matrix<float> local_yaw = amount * (yaw * orientation) 
    orientation = orientation * local_yaw 

這樣每次你想以某種方式旋轉時,你只需調用其中一個函數。

1

四元數可能有幫助,但更簡單的解決方案可能是觀察旋轉的嚴格順序。這聽起來像你圍繞y旋轉,然後圍繞x旋轉。您必須始終先旋轉x,然後y,然後z。並不是說這個順序有什麼特別之處,只是如果你這樣做的話,旋轉往往會更接近你期望它們的工作方式。

編輯:爲了澄清一點,你也不應該在遊戲中橫跨時間累積旋轉。每個框架都應該以標識位置啓動模型,然後將x,y和z旋轉到該框架的新位置。

+0

damnit我只能爲此投票 – 2009-08-10 21:03:43

1

一般的旋轉很困難。物理學家傾向於使用一些所謂的Euler angles來描述它們。在這種方法中,一般的旋轉通過固定連續的三個軸線所描述的三個角度來描述。但三軸不是原始框架的X軸,Y軸和Z軸。它們通常是原始幀的Z軸,Y軸和Z軸(是的,它實際上是完全一般的),或者是來自原始幀的兩個軸,隨後是中間幀中的軸。許多選擇都是可用的,並確保您一直遵循相同的慣例可能是一件麻煩事。

2

您應該學習3D數學,以便您可以更深入地瞭解如何控制旋轉。如果你不知道理論,甚至難以正確複製和粘貼。具體的文本,如3D數學入門(Amazon)和相關網站如http://gamemath.com將大大幫助您在您的項目(和所有未來的項目)。

我明白你現在可能不喜歡數學,但學習相關的算術將是你的問題的最佳解決方案。

+0

我已經有了3D數學入門書,並且在我開始時幫助了很多。 有時候我看了一下它,好像我需要再讀一遍。 – kvasan 2009-08-02 19:36:00