2013-04-17 37 views
0

我正在研究OpenGL中的投光燈變換系統。衆所周知,投光燈具有默認位置和錐體方向。但在我的實現中,它也必須具有旋轉和方向。在這種情況下,旋轉 - 光錐的本地旋轉,而方向 - 在應用了局部旋轉後的圓錐的世界旋轉。投光燈錐體方向旋轉和方向反轉

在這項工作中,我得到了所有類型的軸翻轉問題,部分原因是glm :: lookAt方法顛倒了輸出矩陣的「眼睛」向量這一事實。現在除了必須將最終方向向量y並且爲了獲得點光錐臉不是相反方向Z部分:

  lookatMatr[2].y =- lookatMatr[2].y; 
    lookatMatr[2].z =- lookatMatr[2].z; 

我無法弄清楚兩件事情:

1。如何能做到這一點,這樣我就不需要最後做倒置。 2。爲什麼反轉只需要Y和Z軸。

這裏是改造的全碼:

glm::vec4 worldPos = WorldMatr * _pos ; 
    glm::vec4 worldDir = WorldMatr * glm::vec4(_lightDir,1) ; 
    glm::vec4 worldUp = WorldMatr * glm::vec4(Y_AXIS,1) ; 


    //first construct lookat matrix to get direction vector 
    glm::mat4 lookatMatr = glm::lookAt(glm::vec3(worldPos),glm::vec3(worldDir),glm::vec3(worldUp)) ; 

      //rotate locally : 
    lookatMatr = glm::rotate(lookatMatr,30.0f,X_AXIS) ; 
    lookatMatr = glm::rotate(lookatMatr,0.0f,Y_AXIS) ; 
    lookatMatr = glm::rotate(lookatMatr,0.0f,Z_AXIS) ; 

      //Orient : 
    lookatMatr = Transform().GetOrientationMatrix() * (lookatMatr); 

    _posOut= worldPos ; 
// lookatMatr[2].x =- lookatMatr[2].x;//why only Y and Z to be inverted? 
    lookatMatr[2].y =- lookatMatr[2].y; 
    lookatMatr[2].z =- lookatMatr[2].z; 
    _dirOut= (lookatMatr[2]) ; 

UPDATE:

好吧,正如下面的建議,我設置_lightDir w的部分是零,現在這樣做:

_dirOut=World * Transform().GetOrientationMatrix() * rotMatr * glm::vec4(_lightDir,0); 

它正確顯示光錐,但其方向現在在X軸上翻轉。

回答

1

你必須記住的一件事是lookAt產生一個倒置的矩陣。這個矩陣是將矢量從世界空間轉換到相機空間的系統變換。這相當於將相機從世界空間位置移動到原點的模型轉換。反之亦然。

描述方向的向量在其w分量中必須有0。這導致跳過矩陣的翻譯部分。糾正您的定義worldDirworldUp

但是,你真的不需要lookAt矩陣。相反,你應該採取worldDir並對這個向量執行轉換。所以總體方向將是:

_dirOut = 
    WorldMatr * OrientationMatrix * LocalRotationMatrix * glm::vec4(_lightDir, 0); 

您可以預乘矩陣,然後執行載體的一個轉變,也可以(與LocalRotationMatrix先等等)轉化載體三次。

+0

您的解決方案無法正常工作。在這種情況下,局部旋轉不是局部的。例如,如果我圍繞Z軸旋轉(局部),錐體方向不會改變。但是按照您指定的方法,它會改變。 –

+0

好的,我使用四元數進行局部旋轉計算,並且它不能正常工作。現在改爲常規旋轉並且它可以。但它在X軸上翻轉。因此,如果我翻轉「_dirOut.x」,它將面向正確的方向。有任何想法嗎? –

+0

好吧,可能它是正確的行爲,因爲我的模擬源是左手座標系。謝謝。 –