我试图将我的四元数转换为方向向量,以便我可以沿着它面对的方向移动我的相机。我读到可以先将四元数转换为旋转矩阵,然后获取方向。因此我尝试了这种方法。
inline Matrix4<float> ToRotationMatrix() {
Vector3<float> forward = Vector3<float>( 2.0f * ( GetX() * GetZ() - GetW() * GetY() ), 2.0f * ( GetY() * GetZ() + GetW() * GetX() ), 1.0f - 2.0f * ( GetX() * GetX() + GetY() * GetY() ) );
Vector3<float> up = Vector3<float>( 2.0f * ( GetX() * GetY() + GetW() * GetZ() ), 1.0f - 2.0f * ( GetX() * GetX() + GetZ() * GetZ() ), 2.0f * ( GetY() * GetZ() - GetW() * GetX() ) );
Vector3<float> right = Vector3<float>( 1.0f - 2.0f * ( GetY() * GetY() + GetZ() * GetZ() ), 2.0f * ( GetX() * GetY() - GetW() * GetZ() ), 2.0f * ( GetX() * GetZ() + GetW() * GetY() ) );
return Matrix4<float>().InitRotationFromVectors( forward, up, right );
}
inline Matrix4<T> InitRotationFromVectors( const Vector3<T> &n, const Vector3<T> &v, const Vector3<T> &u ) {
Matrix4<T> ret = Matrix4<T>().InitIdentity();
ret[ 0 ][ 0 ] = u.GetX();
ret[ 1 ][ 0 ] = u.GetY();
ret[ 2 ][ 0 ] = u.GetZ();
ret[ 0 ][ 1 ] = v.GetX();
ret[ 1 ][ 1 ] = v.GetY();
ret[ 2 ][ 1 ] = v.GetZ();
ret[ 0 ][ 2 ] = n.GetX();
ret[ 1 ][ 2 ] = n.GetY();
ret[ 2 ][ 2 ] = n.GetZ();
return ret;
}
inline Vector3<float> GetForward( const Matrix4<float> &rotation ) const {
return Vector3<float>( rotation[ 2 ][ 0 ], rotation[ 2 ][ 1 ], rotation[ 2 ][ 2 ] );
}
当我的相机面向前方时,它朝着正确的方向移动,但当我转动相机时,相机开始朝着错误的方向移动。相机会像这样旋转。
void Camera::Rotate( const Vector3<float> &axis, float angle ) {
Rotate( Quaternion( axis, angle ) );
}
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( quaternion * m_rotation ).Normalized() );
}
要将那些四元数相乘......
inline Quaternion operator*( const Quaternion &quat ) const {
Quaternion ret;
ret[ 3 ] = ( ( *this )[ 3 ] * quat[ 3 ] ) - ( ( *this )[ 0 ] * quat[ 0 ] ) - ( ( *this )[ 1 ] * quat[ 1 ] ) - ( ( *this )[ 2 ] * quat[ 2 ] );
ret[ 0 ] = ( ( *this )[ 3 ] * quat[ 0 ] ) + ( ( *this )[ 0 ] * quat[ 3 ] ) + ( ( *this )[ 1 ] * quat[ 2 ] ) - ( ( *this )[ 2 ] * quat[ 1 ] );
ret[ 1 ] = ( ( *this )[ 3 ] * quat[ 1 ] ) + ( ( *this )[ 1 ] * quat[ 3 ] ) + ( ( *this )[ 2 ] * quat[ 0 ] ) - ( ( *this )[ 0 ] * quat[ 2 ] );
ret[ 2 ] = ( ( *this )[ 3 ] * quat[ 2 ] ) + ( ( *this )[ 2 ] * quat[ 3 ] ) + ( ( *this )[ 0 ] * quat[ 1 ] ) - ( ( *this )[ 1 ] * quat[ 0 ] );
return ret;
}
注意:Quaternion [ 0 ] 表示 x,Quaternion [ 1 ] 表示 y,Quaternion [ 2 ] 表示 z,Quaternion [ 3 ] 表示 w。
我已经苦苦挣扎了几个星期,但无法理解出错的原因。如果有人有任何想法或建议,可以让它正常工作或使用其他方法实现,将不胜感激。谢谢!