2012-02-02 46 views
5

當我嘗試改變方向時,我的相機圍繞一個點旋轉。如果我旋轉我的相機,例如說,在Y軸上旋轉30度,而不是相機朝右看30度,相機將旋轉它正在看的點。爲什麼我的相機用這個數學旋轉一點?

o is the camera, A and B are 3D models. The lines show line-of-sight. 
This is what I expect: 
    A B 
    | >/
    |/
    |/
    |/ 
    o 

This is what actually happens: 
    A B 
    |\ 
    | \ 
    | \ 
    | > \ 
      o 

現在,根據我的理解,爲了移動相機,我必須以相反的量移動世界。所以如果我想在Z軸上移動+1,我會在Z軸上翻譯世界-1。由於我使用四元數來表示方位,因此我使用相機四元數的倒數(因爲方向總是單位四元數,我使用共軛進行優化,而不是計算倒數)以適當的量旋轉世界。

這裏是我怎麼轉換四元數矩陣,其中q是倒四元數:

[1 - 2 * (q.y * q.y + q.z * q.z) 2 * (q.x * q.y - q.w * q.z)  2 * (q.x * q.z + q.w * q.y)   0] 
|2 * (q.x * q.y + q.w * q.z)  1 - 2 * (q.x * q.x + q.z * q.z) 2 * (q.y * q.z - q.w * q.x)   0| 
|2 * (q.x * q.z - q.w * q.y)  2 * (q.y * q.z + q.w * q.z)  1 - 2 * (q.x * q.x + q.y * q.y)  0| 
[0         0         0         1] 

在那之後,我設置的矩陣的平移分量:

[... ... ... -x] 
|... ... ... -y| 
|... ... ... -z| 
[0  0  0  1] 

最後我將它乘到模型視圖矩陣堆棧上,然後渲染所有對象。 我很確定這個數學是正確的,但它不會產生我期待的結果。顯然,向前和向右的向量是問題,所以我唯一的問題是爲什麼他們錯了,如果我想要得到我期待的結果,應該如何設置它們。謝謝。編號: 我從this guy's quaternion camera class找到解決方案。首先我構造一個旋轉矩陣,就像我之前做的那樣,但是我從第一,第二和第三列(分別爲xa,ya和za)獲取矩陣的列向量。然後,我這樣設置矩陣的平移分量:

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

然後將所得矩陣可乘以到模型視圖矩陣堆棧,它完美。

+0

使您的編輯解決方案,並接受它。這就是我們如何標記在這裏解決的問題。我想你應該得到一些解釋。我會爲此寫一個答案。 – datenwolf 2012-02-02 08:41:10

回答

1

編輯:我已經找到了這個人的四元數相機類的解決方案。首先我構造一個像我之前做的旋轉矩陣,但是接下來我從第一列,第二列和第三列(分別是xa, ya和za)獲得矩陣的列向量。然後我設置的平移分量的 這樣的矩陣:

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

然後將所得矩陣可乘以到模型視圖矩陣 棧,它完美。

是的,這正是我所建議的,只是有點不同。你必須明白,OpenGL沒有攝像頭,但是你只需要向相反的方向移動世界,所以你需要找到逆變換矩陣。

相機只是旋轉和移動。這使事情變得非常簡單。平移的正反面只是具有相反符號的相同向量,而旋轉矩陣的反面是它的轉置(交換了列和行)。現在看看均質變換矩陣狀的OpenGL使用它們:

R t 
0 1 

左上方的3×3是旋轉部分,最右邊的列是平移向量。我想其餘的你已經知道了。

0

說實話,試圖找到一個矩陣乘以模塊視圖矩陣是非常複雜和非常容易出錯的。有很多混亂和特殊情況。例如,如果您正在仰視90度,則兩個軸會變得相同。一個合乎邏輯的問題是:如果你正在回頭,所以你通過最高點,你的向上的向量應該倒置,對吧?但是如果你錯過了0.0001度呢?那麼你應該圍繞這一點轉動頭腦,這樣你的向上的向量仍然存在。

在我看來,最好的方法是從另一個角度來看問題。讓我們假設兩種情況:

  • 倒掛是不可能的:
    • 保持一個點爲您的相機的位置和經/緯度方向。用 簡單的正弦/餘弦運算可以得到方向矢量。你向上向量是(0,1,0)
    • 車削只不過是修改的緯度和經度
  • 倒掛可能:
    • 除了攝像頭位置,保持向上和目標的載體。
    • 轉向時,計算右=目標x向上,然後將目標更改爲x *向右+ y *向上
    • 然後,您需要對目標向量進行歸一化並計算新向上。儘管如此,Lot的案件仍然可以處理 。

所有這些之後,你只需撥打gluLookAt

+0

「說實話,試圖找到一個與模塊視圖矩陣相乘的矩陣非常複雜,並且非常容易出錯。」不,這不對。矩陣是考慮相對座標方向最直接的方式。前3列中的每一列都是變換座標系的基矢量之一。第四欄是相對翻譯。從視圖向量和目標向量中寫下相機矩陣,然後用所有三角函數寫出它們要容易得多。 – datenwolf 2012-02-02 11:36:46

+0

我知道。我所說的是,例如,如果你有三種不同的動作(比如移動,扭轉和滾動)直到下一幀,那麼在位置/緯度/經度上這樣做最容易,最後將其轉換爲矩陣,而不是嘗試將每個操作應用到前一個的矩陣中。 – Shahbaz 2012-02-02 12:54:08