我成功實現了相機的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似乎正常工作。
然而,當我將二者結合起來(即移動的lookAt點,從而X和Y不0.0F),一些Z旋轉被施加,這不應該發生,因爲UP x DIRECTION應該總是導致RIGHT.y()爲0.0f。 Z軸旋轉將使用toZRadians
(尚未實施)應用。
而且我發現,如果我再移動的lookAt點向下Y軸,模型依然沿用了的lookAt點,但它實際上圍繞全局X軸旋轉(或equivilant到至少)。
現在,當的lookAt點移動至-Z,該模型具有正確的Y軸旋轉,但它的X軸旋轉反轉。我在這一點檢查了我的向量,發現UP.y()是負數,這是不可能的(它可以是0.0f,但不是負數),因爲DIRECTION和RIGHT總是以相同方式纏繞向右)。 UP.y()可能是負數的唯一方法是如果RIGHT實際上是左邊的。
模型仍然圍繞全局X軸旋轉,因爲它在的lookAt點爲+ Z一樣。
截圖:Global X rotation (lookAt -Z)
正如我所說,這很可能是對矩陣的工作方式的誤解,但它可能是別的東西。我環顧了好幾天,我似乎只能找到基於相機的lookAt功能。任何解釋矩陣中包含的軸的源代碼都會導致本文中介紹的代碼。