记录一下
Camera::CalculateView函数,下面代码:
(Muli3D是类似Dx的方式进行坐标变换的,矩阵是行为主)
void CCamera::CalculateView()
{
matrix44 matRotation, matTranslation;
matMatrix44Translation( matTranslation, -m_vPosition );
matMatrix44RotationQuaternion( matRotation, m_qOrientation );
m_matView = matTranslation * matRotation;
// Update camera axis -----------------------------------------------------
matMatrix44Transpose( matRotation, matRotation );
m_vDir.x = matRotation._31;
m_vDir.y = matRotation._32;
m_vDir.z = matRotation._33;
m_vUp.x = matRotation._21;
m_vUp.y = matRotation._22;
m_vUp.z = matRotation._23;
m_vRight.x = matRotation._11;
m_vRight.y = matRotation._12;
m_vRight.z = matRotation._13;
// Re-Build Frustum -------------------------------------------------------
BuildFrustum();
}
matMatrix44RotationQuaternion 函数
matrix44 &matMatrix44RotationQuaternion( matrix44 &o_matMatOut, const struct quaternion &i_qQuat )
{
// transposed version from http://www.gamedev.net/reference/articles/article1199.asp
const float32 fSquaredX = i_qQuat.x * i_qQuat.x;
const float32 fSquaredY = i_qQuat.y * i_qQuat.y;
const float32 fSquaredZ = i_qQuat.z * i_qQuat.z;
const float32 fSquaredW = i_qQuat.w * i_qQuat.w;
o_matMatOut._11 = fSquaredW + fSquaredX - fSquaredY - fSquaredZ;
o_matMatOut._12 = 2.0f * ( i_qQuat.x * i_qQuat.y - i_qQuat.w * i_qQuat.z );
o_matMatOut._13 = 2.0f * ( i_qQuat.x * i_qQuat.z + i_qQuat.w * i_qQuat.y );
o_matMatOut._14 = 0.0f;
o_matMatOut._21 = 2.0f * ( i_qQuat.x * i_qQuat.y + i_qQuat.w * i_qQuat.z );
o_matMatOut._22 = fSquaredW - fSquaredX + fSquaredY - fSquaredZ;
o_matMatOut._23 = 2.0f * ( i_qQuat.y * i_qQuat.z - i_qQuat.w * i_qQuat.x );
o_matMatOut._24 = 0.0f;
o_matMatOut._31 = 2.0f * ( i_qQuat.x * i_qQuat.z - i_qQuat.w * i_qQuat.y );
o_matMatOut._32 = 2.0f * ( i_qQuat.y * i_qQuat.z + i_qQuat.w * i_qQuat.x );
o_matMatOut._33 = fSquaredW - fSquaredX - fSquaredY + fSquaredZ;
o_matMatOut._34 = 0.0f;
o_matMatOut._41 = 0.0f; o_matMatOut._42 = 0.0f; o_matMatOut._43 = 0.0f;
o_matMatOut._44 = fSquaredW + fSquaredX + fSquaredY + fSquaredZ;
return o_matMatOut;
}
四元数 变为 一个矩阵 的公式:
(矩阵行为主)
由于:
四元数 q = (x,y,z,w), 表示旋转的 p' = q * p * q^-1 的前提是,q为单位四元数,所以得到
x^2 + y ^ 2 + z ^ 2 + w ^2 = 1
所以:
以上的矩阵可以表示为
这个时候,对比 matMatrix44RotationQuaternion 函数代码,发现,代码是公式的转置,所以,从matMatrix44RotationQuaternion 得到矩阵是正确矩阵的转置。
所以代码
matMatrix44Translation( matTranslation, -m_vPosition );
matMatrix44RotationQuaternion( matRotation, m_qOrientation );
m_matView = matTranslation * matRotation;
计算出来的 相机变换矩阵才与 下面的保持一致。
matrix44 &matMatrix44LookAtLH( matrix44 &o_matMatOut, const vector3 &i_vEye, const vector3 &i_vAt, const vector3 &i_vUp )
{
const vector3 vZAxis = (i_vAt - i_vEye).normalize();
vector3 vXAxis; vVector3Cross( vXAxis, i_vUp, vZAxis ).normalize();
vector3 vYAxis; vVector3Cross( vYAxis, vZAxis, vXAxis );
o_matMatOut._11 = vXAxis.x; o_matMatOut._12 = vYAxis.x; o_matMatOut._13 = vZAxis.x; o_matMatOut._14 = 0.0f;
o_matMatOut._21 = vXAxis.y; o_matMatOut._22 = vYAxis.y; o_matMatOut._23 = vZAxis.y; o_matMatOut._24 = 0.0f;
o_matMatOut._31 = vXAxis.z; o_matMatOut._32 = vYAxis.z; o_matMatOut._33 = vZAxis.z; o_matMatOut._34 = 0.0f;
o_matMatOut._41 = -fVector3Dot( vXAxis, i_vEye ); o_matMatOut._42 = -fVector3Dot( vYAxis, i_vEye); o_matMatOut._43 = -fVector3Dot( vZAxis, i_vEye ); o_matMatOut._44 = 1.0f;
return o_matMatOut;
}