Muli3D <2> matMatrix44RotationQuaternion 函数 (四元数转矩阵)

本文详细介绍了3D相机视图变换的过程,包括位置平移与四元数旋转的具体实现,并通过代码示例展示了如何构建正确的视图矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录一下 

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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值