Some code from my quaternion camera. Most of it taken from various tutorials on the internet and then plugged in to my existing system. Don't ask me how quaternions work b/c the math behind them is complex. I just know properties of them and various operations that can be performed on them. So this is one of those things in my book that 'just works'.
Code:
void X3DCamera::Pitch(float angle)
{
D3DXQUATERNION quat = m_qRot;
D3DXQuaternionRotationAxis(&quat,TransformVector(&m_qRot,
&D3DXVECTOR3(1.0f, 0.0f, 0.0f)),
angle);
m_qRot *= quat;
D3DXQuaternionNormalize(&m_qRot,&m_qRot);
m_inTransition = true;
}
void X3DCamera::Yaw(float angle)
{
m_yaw += angle;
D3DXMATRIX matRot;
D3DXQUATERNION quat;
D3DXMatrixRotationY(&matRot,m_yaw);
D3DXQuaternionRotationMatrix(&quat,&matRot);
D3DXQuaternionRotationAxis(&quat,TransformVector(&quat,
&D3DXVECTOR3(0.0f, 1.0f, 0.0f)),
angle);
m_qRot *= quat;
D3DXQuaternionNormalize(&m_qRot,&m_qRot);
m_inTransition = true;
}
void X3DCamera::Roll(float angle)
{
D3DXQUATERNION quat = m_qRot;
D3DXQuaternionRotationAxis(&quat,TransformVector(&m_qRot,
&D3DXVECTOR3(0.0f, 0.0f, 1.0f)),
angle);
m_qRot *= quat;
D3DXQuaternionNormalize(&m_qRot , &m_qRot);
m_inTransition = true;
}
D3DXVECTOR3* X3DCamera::TransformVector(D3DXQUATERNION *pOrientation, D3DXVECTOR3 *pAxis)
{
D3DVECTOR vNewAxis;
D3DXMATRIX matRotation;
// Build a matrix from the quaternion.
D3DXMatrixRotationQuaternion(&matRotation, pOrientation);
// Transform the queried axis vector by the matrix.
vNewAxis.x = pAxis->x * matRotation._11 + pAxis->y * matRotation._21 + pAxis->z *
matRotation._31 + matRotation._41;
vNewAxis.y = pAxis->x * matRotation._12 + pAxis->y * matRotation._22 + pAxis->z *
matRotation._32 + matRotation._42;
vNewAxis.z = pAxis->x * matRotation._13 + pAxis->y * matRotation._23 + pAxis->z *
matRotation._33 + matRotation._43;
memcpy(pAxis, &vNewAxis, sizeof(vNewAxis)); // Copy axis.
return(pAxis);
}
void X3DCamera::GetViewMatrix(D3DXMATRIX *outMatrix)
{
D3DXMATRIX matRot;
D3DXQuaternionNormalize(&m_qRot,&m_qRot);
D3DXMatrixRotationQuaternion(&matRot,&D3DXQUATERNION(-m_qRot.x,-m_qRot.y,-m_qRot.z,m_qRot.w));
D3DXVECTOR3 vecLook(matRot._13,matRot._23,matRot._33);
D3DXVECTOR3 vecOrbitPos = m_vecTargetPos + vecLook * -m_fCamDist;
D3DXMATRIX matOrbit;
D3DXMatrixTranslation(&matOrbit,-vecOrbitPos.x,-vecOrbitPos.y,-vecOrbitPos.z);
D3DXMATRIX matTrans;
D3DXMatrixTranslation(&matTrans,-Pos.x,-Pos.y,-Pos.z);
m_matView = matOrbit * matRot * matTrans;
*outMatrix = m_matView;
}