我在几个网站上看了很多四元数的例子,包括这个,但是没有找到答案,所以这里有......
我想围绕一个大球体围绕我的相机进行轨道运动,让相机始终指向球体的中心。为了简单起见,球体位于世界{0,0,0}处。我正在使用四元数来进行相机定位,并使用相机位置的矢量。问题是摄像机位置完全按照应有的方式绕球运行,但总是直接向前看一个恒定方向,而不是在轨道运行时调整到指向中心。
这一定很简单,但我是四元数的新手......我错过了什么?
我正在使用C ++,DirectX9。这是我的代码:
// Note: g_camRotAngleYawDir and g_camRotAnglePitchDir are set to either 1.0f, -1.0f according to keypresses, otherwise equal 0.0f
// Also, g_camOrientationQuat is just an identity quat to begin with.
float theta = 0.05f;
D3DXQUATERNION g_deltaQuat( 0.0f, 0.0f, 0.0f, 1.0f );
D3DXQuaternionRotationYawPitchRoll(&g_deltaQuat, g_camRotAngleYawDir * theta, g_camRotAnglePitchDir * theta, g_camRotAngleRollDir * theta);
D3DXQUATERNION tempQuat = g_camOrientationQuat;
D3DXQuaternionMultiply(&g_camOrientationQuat, &tempQuat, &g_deltaQuat);
D3DXMatrixRotationQuaternion(&g_viewMatrix, &g_camOrientationQuat);
g_viewMatrix._41 = g_camPosition.x;
g_viewMatrix._42 = g_camPosition.y;
g_viewMatrix._43 = g_camPosition.z;
g_direct3DDevice9->SetTransform( D3DTS_VIEW, &g_viewMatrix );
[编辑 - 2012年2月13日]
好的,到目前为止我的理解是这样的:
每帧使用角度增量移动相机。 获取从中心到相机位置的矢量。 使用面向z的单位向量和目标向量调用quaternionRotationBetweenVectors。 然后使用该函数的结果作为视图矩阵的方向,摄像机位置进入视图矩阵的平移部分。
这是新代码(称为每帧)...
// This part orbits the position around the sphere according to deltas for yaw, pitch, roll
D3DXQuaternionRotationYawPitchRoll(&deltaQuat, yawDelta, pitchDelta, rollDelta);
D3DXMatrixRotationQuaternion(&mat1, &deltaQuat);
D3DXVec3Transform(&g_camPosition, &g_camPosition, &mat1);
//此部分调整相机的方向以指向球体的中心
dir1 = normalize(vec3(0.0f, 0.0f, 0.0f) - g_camPosition);
QuaternionRotationBetweenVectors(&g_camOrientationQuat, vec3(0.0f, 0.0f, 1.0f), &dir1);
D3DXMatrixRotationQuaternion(&g_viewMatrix, &g_camOrientationQuat);
g_viewMatrix._41 = g_camPosition.x;
g_viewMatrix._42 = g_camPosition.y;
g_viewMatrix._43 = g_camPosition.z;
g_direct3DDevice9->SetTransform( D3DTS_VIEW, &g_viewMatrix );
......我尝试了解决方案,没有成功。我做错了什么?
答案 0 :(得分:1)
每当您更新位置时(假设相机指向z轴),它应该像执行以下操作一样简单:
direction = normalize(center - position)
orientation = quaternionRotationBetweenVectors(vec3(0,0,1), direction)
很容易找到如何实施quaternionRotationBetweenVectors
的示例。您可以从问题“Finding quaternion representing the rotation from one vector to another”开始。
这是使用DirectX9 API的实现未经测试的草图:
D3DXQUATERNION* quaternionRotationBetweenVectors(__inout D3DXQUATERNION* result, __in const D3DXVECTOR3* v1, __in const D3DXVECTOR3* v2)
{
D3DXVECTOR3 axis;
D3DXVec3Cross(&axis, v1, v2);
D3DXVec3Normalize(&axis, &axis);
float angle = acos(D3DXVec3Dot(v1, v2));
D3DXQuaternionRotationAxis(result, &axis, angle);
return result;
}
此实现需要对v1, v2
进行规范化。
答案 1 :(得分:0)
您需要显示如何计算角度。您有没有使用D3DXMatrixLookAtLH的原因?