2012-01-16 151 views
4

我成功實現了相機的lookAt矩陣,因爲有很多來源描述它。模型lookAt矩陣 - C++,OpenGL

我一直在試圖從相機lookAt翻譯到模型lookAt。我似乎無法讓它起作用,並且我假設我對矩陣的構建方式有輕微的誤解。我假設我不需要改變模型的翻譯來看待某一點,因爲它的位置應該保持不變。

首先,這裏是相關的代碼。 lookAtRadians函數應該查看同一個參照框架中指定的點,因爲它是平移的(即在 - 位置=方向)。但是,有一些問題,我將在屏幕截圖中展示。它不檢查direction.y()是1.0f還是-1.0f,但這是微不足道的。

void TransformMatrix3D::lookAtRadians(float atX, float atY, float atZ, float toZRadians) 
{ 
    Vector3D direction(atX - x(), atY - y(), atZ - z()); 
    direction.normalize(); 

    Vector3D up(0.0f, 1.0f, 0.0f); 

    Vector3D right(direction.crossProduct(up)); 
    right.normalize(); 
    up = direction.crossProduct(right); 

    mMatrix[0] = right.x(); 
    mMatrix[4] = right.y(); 
    mMatrix[8] = right.z(); 
    mMatrix[1] = up.x(); 
    mMatrix[5] = up.y(); 
    mMatrix[9] = up.z(); 
    mMatrix[2] = direction.x(); 
    mMatrix[6] = direction.y(); 
    mMatrix[10] = direction.z(); 
} 

這裏是交叉乘積和規範化函數,以防它們不正確。

Vector3D Vector3D::crossProduct(const Vector3D& rightVector) const 
{ 
    const float NEW_X(y() * rightVector.z() - z() * rightVector.y()); 
    const float NEW_Y(z() * rightVector.x() - x() * rightVector.z()); 
    const float NEW_Z(x() * rightVector.y() - y() * rightVector.x()); 

    return Vector3D(NEW_X, NEW_Y, NEW_Z); 
} 


void Vector3D::normalize() 
{ 
    float length(x() * x() + y() * y() + z() * z()); 

    if(fabs(length) == 1.0f) 
     return; 

    length = 1.0f/sqrt(length); 
    moveTo(x() * length, y() * length, z() * length); 
} 

下面是一些截圖來描述我的問題。白色球體表示lookAt點。

我創建翻譯-10.0f向下Z軸的立方體(這將設置mMatrix[12]mMatrix[13]mMatrix[14]爲0.0f,0.0F,-10.0f分別矩陣的其餘部分的身份。我已檢查這是這樣的),我將用它來展示問題。

截圖:No rotation

如果我移動的lookAt點僅沿X軸和Y軸的的lookAt似乎正常工作。

截圖:X axis (Y rotation)

截圖:Y axis (X rotation)

然而,當我將二者結合起來(即移動的lookAt點,從而X和Y不0.0F),一些Z旋轉被施加,這不應該發生,因爲UP x DIRECTION應該總是導致RIGHT.y()爲0.0f。 Z軸旋轉將使用toZRadians(尚未實施)應用。

截圖:Added Z rotation

而且我發現,如果我再移動的lookAt點向下Y軸,模型依然沿用了的lookAt點,但它實際上圍繞全局X軸旋轉(或equivilant到至少)。

截圖:Global X rotation

現在,當的lookAt點移動至-Z,該模型具有正確的Y軸旋轉,但它的X軸旋轉反轉。我在這一點檢查了我的向量,發現UP.y()是負數,這是不可能的(它可以是0.0f,但不是負數),因爲DIRECTION和RIGHT總是以相同方式纏繞向右)。 UP.y()可能是負數的唯一方法是如果RIGHT實際上是左邊的。

截圖:Inverted X rotation

模型仍然圍繞全局X軸旋轉,因爲它在的lookAt點爲+ Z一樣。

截圖:Global X rotation (lookAt -Z)

正如我所說,這很可能是對矩陣的工作方式的誤解,但它可能是別的東西。我環顧了好幾天,我似乎只能找到基於相機的lookAt功能。任何解釋矩陣中包含的軸的源代碼都會導致本文中介紹的代碼。

回答

5

啊,我發現了這個問題。很簡單,我忽略了它。

我的矩陣:

mMatrix[0] = right.x(); 
mMatrix[4] = right.y(); 
mMatrix[8] = right.z(); 
mMatrix[1] = up.x(); 
mMatrix[5] = up.y(); 
mMatrix[9] = up.z(); 
mMatrix[2] = direction.x(); 
mMatrix[6] = direction.y(); 
mMatrix[10] = direction.z(); 

定義列主要在內存中。它應該是:

mMatrix[0] = right.x(); 
mMatrix[1] = right.y(); 
mMatrix[2] = right.z(); 
mMatrix[4] = up.x(); 
mMatrix[5] = up.y(); 
mMatrix[6] = up.z(); 
mMatrix[8] = direction.x(); 
mMatrix[9] = direction.y(); 
mMatrix[10] = direction.z(); 

而且工作完美。非常愚蠢的錯誤,我甚至沒有想過要檢查。這也解釋了軸上奇怪的反轉。