2009-04-25 38 views
3

昨天我問:How could simply calling Pitch and Yaw cause the camera to roll?有人可以解釋我如何使用Quanternions來使用鼠標像FPS一樣環顧四周?

基本上,我發現是因爲「Gimbal Lock」,如果你的俯仰+偏航你將不可避免地產生滾動效果。欲瞭解更多信息,你可以閱讀這個問題。

我試圖阻止這種情況發生。當你在一個普通的FPS射手環顧四周,你沒有讓你的相機在所有地方滾動!

這是我目前的被動鼠標FUNC:

int windowWidth = 640; 
int windowHeight = 480; 

int oldMouseX = -1; 
int oldMouseY = -1; 

void mousePassiveHandler(int x, int y) 
{ 
    int snapThreshold = 50; 

    if (oldMouseX != -1 && oldMouseY != -1) 
    { 
     cam.yaw((x - oldMouseX)/10.0); 
     cam.pitch((y - oldMouseY)/10.0); 


     oldMouseX = x; 
     oldMouseY = y; 

     if ((fabs(x - (windowWidth/2)) > snapThreshold) || (fabs(y - (windowHeight/2)) > snapThreshold)) 
     { 
      oldMouseX = windowWidth/2; 
      oldMouseY = windowHeight/2; 
      glutWarpPointer(windowWidth/2, windowHeight/2); 
     } 
    } 
    else 
    { 
     oldMouseX = windowWidth/2; 
     oldMouseY = windowHeight/2; 
     glutWarpPointer(windowWidth/2, windowHeight/2); 
    } 


    glutPostRedisplay(); 

} 

導致相機俯仰/偏航基於鼠標移動(同時保持在中心光標)。我還發布了我的原始相機類here

該線程中的某個人建議我使用Quaternion來防止這種情況的發生,但在閱讀wikipedia page之後,我根本就不理會它們。

如何在我的OpenGL/Glut應用程序中創建一個四元數,這樣我就可以正確地讓我的「相機」環顧四周而不會產生不必要的滾動?

+0

這不是導致相機滾動的萬向節鎖。萬向節鎖僅在特定情況下發生。通常,在許多舊式FPS中(大多數新式FPS都沒有這個問題),您不能用90°角度觀察天空,以避免會導致玩家只看到天空的萬向節鎖如果你的球員的脖子被阻擋。 查看維基百科文章獲得更多信息。 – rockeye 2009-05-29 12:43:45

回答

0

你並不真的需要四元數爲簡單的情況下,你需要的是輸入你的航向和俯仰成三維矩陣計算:

  1. 用您的標題值與Y可旋轉軸以計算MY

  2. 用你的音調值與X軸的旋轉來計算MX

  3. 對於每個點P,計算R = MX * MY * P

計算可以用兩種方法進行:

  1. T = MY * P,則R = MX * T

  2. T = MX * MY,則R = T * P

第一種方式是速度較慢,但​​在第一易於編碼,第二個是快,但你需要編寫一個矩陣,矩陣乘法功能。

ps。見http://en.wikipedia.org/wiki/Rotation_matrix#Dimension_three爲矩陣

1

保持你的增量改變低,以避免(即< 45度)

只需計算與旋轉針對每個幀一個小的「增量」矩陣,摺疊成照相機矩陣中的每個幀中,該。(我的意思是:凸輪=凸輪*三角洲)

如果您運行了很長時間,您可能會收到一些數字錯誤,所以您需要重新正交它。 (看起來如果似乎發生)

這是最簡單的方法,當玩弄東西時避免萬向節鎖。一旦你變得更精通,你就會明白其餘的。

至於四​​元數,只需找到一個好的庫,可以將它們轉換爲旋轉矩陣,然後使用相同的技術(計算增量四元數,乘以主要四元數)。

相關問題