2013-04-06 110 views
1

我正在嘗試使用gluLookAt方法設置3D相機。所以我得到了一個10x10x10的立方體,現在我想移動該立方體內的相機。我有類似的東西:OpenGL 3D相機gluLookAt

gluLookAt(camera->x,camera->y,camera->z, camera->eyeX, camera->eyeY, camera->eyeZ, 0, 1, 0); 

現在我前進/後退:

if(GetKeyState(VK_UP) <0) 
       {  
        camera->x += sin(camera->angleX)*0.1f; 
        camera->eyeX += sin(camera->angleX)*0.1f;    
        camera->z -= cos(camera->angleX)*0.1f; 
        camera->eyeZ -= cos(camera->angleX)*0.1f; 
      } 

現在我轉左/右:

if(GetKeyState(VK_LEFT) <0) 
      { 
       camera->angleX -=0.1f; 
       camera->eyeX = sin(camera->angleX) +camera->x; 
       camera->eyeZ = -cos(camera->angleX) + camera->z; 
      } 

讓所有的作品完美但現在我想按住SHIFT鍵的同時向上/向下旋轉。所以我有這樣的事情:

if(GetKeyState(VK_SHIFT) <0) 
      { 
       if(GetKeyState(VK_UP)<0) 
       { 
        camera->angleY +=0.1f;     
        camera->eyeY = sin(camera->angleY) +camera->y;     
       } 

實際上有些奇怪的事情發生。相機一直在上下搖擺,然後慢慢前進。另外,我想補充一點,當我擡頭向前移動時,相機實際上就是在那裏看起來的。所以基本上,情況如下:我是一個被困在10x10x10立方體中的鬼魂,可以隨意走動。我想移動到右上角?我只是去那裏。所以...任何想法我應該改變/添加?

回答

3

編輯:我從頭開始我的回覆,因爲我可能已經認爲這個主題太過於熟悉。

您面臨的問題是您的公式基本上不正確:在「向上」向量(向上指向相機的向量)始終爲[0 1 0] ...如果您還想要向上/向下旋轉,則不是這種情況。而你的旋轉向下的公式是不正確的,因爲它只修改Y分量,旋轉不能這樣工作。

來處理正確的方法是:

  • 存儲3個變量表示攝像機位置(像你一樣)。我們稱它們爲Px,Py,,Pz
  • 來存儲代表攝像機視角方向的3個變量(而不是您的eyeX/Y/Z編碼攝像機正在查看的點)。我們稱之爲Vx,Vy,Vz
  • 用於存儲代表相機右矢量(或向上矢量,如您所願)的3個變量。讓我們採取正確的矢量,並將其稱爲Rx,Ry,Rz

或者,您可以有一個很好的「Vector」類,它代表向量,而不是每次存儲3個變量。這是一個細節。

現在,你向前移動相機拍攝方法只是變成:

Px += Vx; 
Py += Vy; 
Pz += Vz; 

可以使用,例如,Rodrigues式旋轉(希望沒有人會在您推出的「四元數」神奇的詞來表達自己聰明;))。那麼一般自包含的代碼,以繞任意軸將是:

// rotate the vector (vx, vy, vz) around (ax, ay, az) by an angle "angle" 

void rotate(double &vx, double &vy, double &vz, double ax, double ay, double az, double angle) { 
    double ca = cos(angle); 
    double sa = sin(angle); 
    double crossx = -vy*az + vz*ay; 
    double crossy = -vz*ax + vx*az; 
    double crossz = -vx*ay + vy*ax; 
    double dot = ax*vx + ay*vy + az*vz; 
    double rx = vx*ca + crossx*sa + dot*ax*(1-ca); 
    double ry = vy*ca + crossy*sa + dot*ay*(1-ca); 
    double rz = vz*ca + crossz*sa + dot*az*(1-ca); 
    vx = rx; 
    vy = ry; 
    vz = rz; 
} 

而且一定要保持標準座標爲您的相機的載體。

現在,特別是旋轉你的相機上/下,當你按下一個按鈕:

// rotate up: 
rotate(Vx, Vy, Vz, Rx, Ry, Rz, some_CONSTANT_angle); 
// rotate down: 
rotate(Vx, Vy, Vz, Rx, Ry, Rz, - some_CONSTANT_angle); 

要旋轉左/右,你首先需要計算「向上」矢量並不需要是存儲(除非你想,但它是多餘的),並且旋轉兩個視圖方向,右載體:

// find up vector using a cross product: 
    double Ux = Ry*Vz - Rz*Vy; 
    double Uy = Rz*Vx - Rx*Vz; 
    double Uz = Rx*Vy - Ry*Vx; 

//rotate left 
    rotate(Rx, Ry, Rz, Ux, Uy, Uz, some_CONSTANT_angle); 
    rotate(Vx, Vy, Vz, Ux, Uy, Uz, some_CONSTANT_angle); 
// rotate right 
    rotate(Rx, Ry, Rz, Ux, Uy, Uz, - some_CONSTANT_angle); 
    rotate(Vx, Vy, Vz, Ux, Uy, Uz, - some_CONSTANT_angle); 

設置相機矩陣現在變成:

gluLookAt(Px, Py, Pz, Px+Vx, Py+Vy, Pz+Vz, Rx, Ry, Rz); // or is it Ux, Uy, Uz at the end? don't remember. 

當然,我沒有測試任何這些代碼,現在就寫出來。希望它有效!

+0

我試圖用向上的方式做點什麼,但我不認爲這是問題...我想說我錯過了像camera-> y = 和camera-> eyeY = 任何其他想法我可能會添加/更改什麼? – L3M0L 2013-04-07 10:05:06

+0

我其實改爲:camera-> eyeY = tan(camera-> angleY)+ camera-> y;它不再彈起來,但現在我想朝這個方向前進。有任何想法嗎? – L3M0L 2013-04-07 10:47:39

+0

哦,是的......我編輯了我的答案;請讓我知道如果解決這個問題。 – WhitAngl 2013-04-07 16:46:53