2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #ifndef __MATH_QUAT_H__
30 #define __MATH_QUAT_H__
33 ===============================================================================
37 ===============================================================================
56 idQuat( float x, float y, float z, float w );
58 void Set( float x, float y, float z, float w );
60 float operator[]( int index ) const;
61 float & operator[]( int index );
62 idQuat operator-() const;
63 idQuat & operator=( const idQuat &a );
64 idQuat operator+( const idQuat &a ) const;
65 idQuat & operator+=( const idQuat &a );
66 idQuat operator-( const idQuat &a ) const;
67 idQuat & operator-=( const idQuat &a );
68 idQuat operator*( const idQuat &a ) const;
69 idVec3 operator*( const idVec3 &a ) const;
70 idQuat operator*( float a ) const;
71 idQuat & operator*=( const idQuat &a );
72 idQuat & operator*=( float a );
74 friend idQuat operator*( const float a, const idQuat &b );
75 friend idVec3 operator*( const idVec3 &a, const idQuat &b );
77 bool Compare( const idQuat &a ) const; // exact compare, no epsilon
78 bool Compare( const idQuat &a, const float epsilon ) const; // compare with epsilon
79 bool operator==( const idQuat &a ) const; // exact compare, no epsilon
80 bool operator!=( const idQuat &a ) const; // exact compare, no epsilon
82 idQuat Inverse( void ) const;
83 float Length( void ) const;
84 idQuat & Normalize( void );
86 float CalcW( void ) const;
87 int GetDimension( void ) const;
89 idAngles ToAngles( void ) const;
90 idRotation ToRotation( void ) const;
91 idMat3 ToMat3( void ) const;
92 idMat4 ToMat4( void ) const;
93 idCQuat ToCQuat( void ) const;
94 idVec3 ToAngularVelocity( void ) const;
95 const float * ToFloatPtr( void ) const;
96 float * ToFloatPtr( void );
97 const char * ToString( int precision = 2 ) const;
99 idQuat & Slerp( const idQuat &from, const idQuat &to, float t );
102 ID_INLINE idQuat::idQuat( void ) {
105 ID_INLINE idQuat::idQuat( float x, float y, float z, float w ) {
112 ID_INLINE float idQuat::operator[]( int index ) const {
113 assert( ( index >= 0 ) && ( index < 4 ) );
114 return ( &x )[ index ];
117 ID_INLINE float& idQuat::operator[]( int index ) {
118 assert( ( index >= 0 ) && ( index < 4 ) );
119 return ( &x )[ index ];
122 ID_INLINE idQuat idQuat::operator-() const {
123 return idQuat( -x, -y, -z, -w );
126 ID_INLINE idQuat &idQuat::operator=( const idQuat &a ) {
135 ID_INLINE idQuat idQuat::operator+( const idQuat &a ) const {
136 return idQuat( x + a.x, y + a.y, z + a.z, w + a.w );
139 ID_INLINE idQuat& idQuat::operator+=( const idQuat &a ) {
148 ID_INLINE idQuat idQuat::operator-( const idQuat &a ) const {
149 return idQuat( x - a.x, y - a.y, z - a.z, w - a.w );
152 ID_INLINE idQuat& idQuat::operator-=( const idQuat &a ) {
161 ID_INLINE idQuat idQuat::operator*( const idQuat &a ) const {
162 return idQuat( w*a.x + x*a.w + y*a.z - z*a.y,
163 w*a.y + y*a.w + z*a.x - x*a.z,
164 w*a.z + z*a.w + x*a.y - y*a.x,
165 w*a.w - x*a.x - y*a.y - z*a.z );
168 ID_INLINE idVec3 idQuat::operator*( const idVec3 &a ) const {
170 // it's faster to do the conversion to a 3x3 matrix and multiply the vector by this 3x3 matrix
171 return ( ToMat3() * a );
173 // result = this->Inverse() * idQuat( a.x, a.y, a.z, 0.0f ) * (*this)
174 float xxzz = x*x - z*z;
175 float wwyy = w*w - y*y;
177 float xw2 = x*w*2.0f;
178 float xy2 = x*y*2.0f;
179 float xz2 = x*z*2.0f;
180 float yw2 = y*w*2.0f;
181 float yz2 = y*z*2.0f;
182 float zw2 = z*w*2.0f;
185 (xxzz + wwyy)*a.x + (xy2 + zw2)*a.y + (xz2 - yw2)*a.z,
186 (xy2 - zw2)*a.x + (y*y+w*w-x*x-z*z)*a.y + (yz2 + xw2)*a.z,
187 (xz2 + yw2)*a.x + (yz2 - xw2)*a.y + (wwyy - xxzz)*a.z
192 ID_INLINE idQuat idQuat::operator*( float a ) const {
193 return idQuat( x * a, y * a, z * a, w * a );
196 ID_INLINE idQuat operator*( const float a, const idQuat &b ) {
200 ID_INLINE idVec3 operator*( const idVec3 &a, const idQuat &b ) {
204 ID_INLINE idQuat& idQuat::operator*=( const idQuat &a ) {
210 ID_INLINE idQuat& idQuat::operator*=( float a ) {
219 ID_INLINE bool idQuat::Compare( const idQuat &a ) const {
220 return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) && ( w == a.w ) );
223 ID_INLINE bool idQuat::Compare( const idQuat &a, const float epsilon ) const {
224 if ( idMath::Fabs( x - a.x ) > epsilon ) {
227 if ( idMath::Fabs( y - a.y ) > epsilon ) {
230 if ( idMath::Fabs( z - a.z ) > epsilon ) {
233 if ( idMath::Fabs( w - a.w ) > epsilon ) {
239 ID_INLINE bool idQuat::operator==( const idQuat &a ) const {
243 ID_INLINE bool idQuat::operator!=( const idQuat &a ) const {
244 return !Compare( a );
247 ID_INLINE void idQuat::Set( float x, float y, float z, float w ) {
254 ID_INLINE idQuat idQuat::Inverse( void ) const {
255 return idQuat( -x, -y, -z, w );
258 ID_INLINE float idQuat::Length( void ) const {
261 len = x * x + y * y + z * z + w * w;
262 return idMath::Sqrt( len );
265 ID_INLINE idQuat& idQuat::Normalize( void ) {
269 len = this->Length();
280 ID_INLINE float idQuat::CalcW( void ) const {
281 // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1
282 return sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) );
285 ID_INLINE int idQuat::GetDimension( void ) const {
289 ID_INLINE const float *idQuat::ToFloatPtr( void ) const {
293 ID_INLINE float *idQuat::ToFloatPtr( void ) {
299 ===============================================================================
301 Compressed quaternion
303 ===============================================================================
313 idCQuat( float x, float y, float z );
315 void Set( float x, float y, float z );
317 float operator[]( int index ) const;
318 float & operator[]( int index );
320 bool Compare( const idCQuat &a ) const; // exact compare, no epsilon
321 bool Compare( const idCQuat &a, const float epsilon ) const; // compare with epsilon
322 bool operator==( const idCQuat &a ) const; // exact compare, no epsilon
323 bool operator!=( const idCQuat &a ) const; // exact compare, no epsilon
325 int GetDimension( void ) const;
327 idAngles ToAngles( void ) const;
328 idRotation ToRotation( void ) const;
329 idMat3 ToMat3( void ) const;
330 idMat4 ToMat4( void ) const;
331 idQuat ToQuat( void ) const;
332 const float * ToFloatPtr( void ) const;
333 float * ToFloatPtr( void );
334 const char * ToString( int precision = 2 ) const;
337 ID_INLINE idCQuat::idCQuat( void ) {
340 ID_INLINE idCQuat::idCQuat( float x, float y, float z ) {
346 ID_INLINE void idCQuat::Set( float x, float y, float z ) {
352 ID_INLINE float idCQuat::operator[]( int index ) const {
353 assert( ( index >= 0 ) && ( index < 3 ) );
354 return ( &x )[ index ];
357 ID_INLINE float& idCQuat::operator[]( int index ) {
358 assert( ( index >= 0 ) && ( index < 3 ) );
359 return ( &x )[ index ];
362 ID_INLINE bool idCQuat::Compare( const idCQuat &a ) const {
363 return ( ( x == a.x ) && ( y == a.y ) && ( z == a.z ) );
366 ID_INLINE bool idCQuat::Compare( const idCQuat &a, const float epsilon ) const {
367 if ( idMath::Fabs( x - a.x ) > epsilon ) {
370 if ( idMath::Fabs( y - a.y ) > epsilon ) {
373 if ( idMath::Fabs( z - a.z ) > epsilon ) {
379 ID_INLINE bool idCQuat::operator==( const idCQuat &a ) const {
383 ID_INLINE bool idCQuat::operator!=( const idCQuat &a ) const {
384 return !Compare( a );
387 ID_INLINE int idCQuat::GetDimension( void ) const {
391 ID_INLINE idQuat idCQuat::ToQuat( void ) const {
392 // take the absolute value because floating point rounding may cause the dot of x,y,z to be larger than 1
393 return idQuat( x, y, z, sqrt( fabs( 1.0f - ( x * x + y * y + z * z ) ) ) );
396 ID_INLINE const float *idCQuat::ToFloatPtr( void ) const {
400 ID_INLINE float *idCQuat::ToFloatPtr( void ) {
404 #endif /* !__MATH_QUAT_H__ */