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_MATH_H__
30 #define __MATH_MATH_H__
32 #if defined(MACOS_X) && defined(__powerpc__)
33 // for square root estimate instruction
34 #include <ppc_intrinsics.h>
39 ===============================================================================
43 ===============================================================================
54 #define DEG2RAD(a) ( (a) * idMath::M_DEG2RAD )
55 #define RAD2DEG(a) ( (a) * idMath::M_RAD2DEG )
57 #define SEC2MS(t) ( idMath::FtoiFast( (t) * idMath::M_SEC2MS ) )
58 #define MS2SEC(t) ( (t) * idMath::M_MS2SEC )
60 #define ANGLE2SHORT(x) ( idMath::FtoiFast( (x) * 65536.0f / 360.0f ) & 65535 )
61 #define SHORT2ANGLE(x) ( (x) * ( 360.0f / 65536.0f ) )
63 #define ANGLE2BYTE(x) ( idMath::FtoiFast( (x) * 256.0f / 360.0f ) & 255 )
64 #define BYTE2ANGLE(x) ( (x) * ( 360.0f / 256.0f ) )
66 #define FLOATSIGNBITSET(f) ((*(const unsigned long *)&(f)) >> 31)
67 #define FLOATSIGNBITNOTSET(f) ((~(*(const unsigned long *)&(f))) >> 31)
68 #define FLOATNOTZERO(f) ((*(const unsigned long *)&(f)) & ~(1<<31) )
69 #define INTSIGNBITSET(i) (((const unsigned long)(i)) >> 31)
70 #define INTSIGNBITNOTSET(i) ((~((const unsigned long)(i))) >> 31)
72 #define FLOAT_IS_NAN(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x7f800000)
73 #define FLOAT_IS_INF(x) (((*(const unsigned long *)&x) & 0x7fffffff) == 0x7f800000)
74 #define FLOAT_IS_IND(x) ((*(const unsigned long *)&x) == 0xffc00000)
75 #define FLOAT_IS_DENORMAL(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x00000000 && \
76 ((*(const unsigned long *)&x) & 0x007fffff) != 0x00000000 )
78 #define IEEE_FLT_MANTISSA_BITS 23
79 #define IEEE_FLT_EXPONENT_BITS 8
80 #define IEEE_FLT_EXPONENT_BIAS 127
81 #define IEEE_FLT_SIGN_BIT 31
83 #define IEEE_DBL_MANTISSA_BITS 52
84 #define IEEE_DBL_EXPONENT_BITS 11
85 #define IEEE_DBL_EXPONENT_BIAS 1023
86 #define IEEE_DBL_SIGN_BIT 63
88 #define IEEE_DBLE_MANTISSA_BITS 63
89 #define IEEE_DBLE_EXPONENT_BITS 15
90 #define IEEE_DBLE_EXPONENT_BIAS 0
91 #define IEEE_DBLE_SIGN_BIT 79
93 template<class T> ID_INLINE int MaxIndex( T x, T y ) { return ( x > y ) ? 0 : 1; }
94 template<class T> ID_INLINE int MinIndex( T x, T y ) { return ( x < y ) ? 0 : 1; }
96 template<class T> ID_INLINE T Max3( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? x : z ) : ( ( y > z ) ? y : z ); }
97 template<class T> ID_INLINE T Min3( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? x : z ) : ( ( y < z ) ? y : z ); }
98 template<class T> ID_INLINE int Max3Index( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? 0 : 2 ) : ( ( y > z ) ? 1 : 2 ); }
99 template<class T> ID_INLINE int Min3Index( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? 0 : 2 ) : ( ( y < z ) ? 1 : 2 ); }
101 template<class T> ID_INLINE T Sign( T f ) { return ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ); }
102 template<class T> ID_INLINE T Square( T x ) { return x * x; }
103 template<class T> ID_INLINE T Cube( T x ) { return x * x * x; }
109 static void Init( void );
111 static float RSqrt( float x ); // reciprocal square root, returns huge number when x == 0.0
113 static float InvSqrt( float x ); // inverse square root with 32 bits precision, returns huge number when x == 0.0
114 static float InvSqrt16( float x ); // inverse square root with 16 bits precision, returns huge number when x == 0.0
115 static double InvSqrt64( float x ); // inverse square root with 64 bits precision, returns huge number when x == 0.0
117 static float Sqrt( float x ); // square root with 32 bits precision
118 static float Sqrt16( float x ); // square root with 16 bits precision
119 static double Sqrt64( float x ); // square root with 64 bits precision
121 static float Sin( float a ); // sine with 32 bits precision
122 static float Sin16( float a ); // sine with 16 bits precision, maximum absolute error is 2.3082e-09
123 static double Sin64( float a ); // sine with 64 bits precision
125 static float Cos( float a ); // cosine with 32 bits precision
126 static float Cos16( float a ); // cosine with 16 bits precision, maximum absolute error is 2.3082e-09
127 static double Cos64( float a ); // cosine with 64 bits precision
129 static void SinCos( float a, float &s, float &c ); // sine and cosine with 32 bits precision
130 static void SinCos16( float a, float &s, float &c ); // sine and cosine with 16 bits precision
131 static void SinCos64( float a, double &s, double &c ); // sine and cosine with 64 bits precision
133 static float Tan( float a ); // tangent with 32 bits precision
134 static float Tan16( float a ); // tangent with 16 bits precision, maximum absolute error is 1.8897e-08
135 static double Tan64( float a ); // tangent with 64 bits precision
137 static float ASin( float a ); // arc sine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN
138 static float ASin16( float a ); // arc sine with 16 bits precision, maximum absolute error is 6.7626e-05
139 static double ASin64( float a ); // arc sine with 64 bits precision
141 static float ACos( float a ); // arc cosine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN
142 static float ACos16( float a ); // arc cosine with 16 bits precision, maximum absolute error is 6.7626e-05
143 static double ACos64( float a ); // arc cosine with 64 bits precision
145 static float ATan( float a ); // arc tangent with 32 bits precision
146 static float ATan16( float a ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08
147 static double ATan64( float a ); // arc tangent with 64 bits precision
149 static float ATan( float y, float x ); // arc tangent with 32 bits precision
150 static float ATan16( float y, float x ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08
151 static double ATan64( float y, float x ); // arc tangent with 64 bits precision
153 static float Pow( float x, float y ); // x raised to the power y with 32 bits precision
154 static float Pow16( float x, float y ); // x raised to the power y with 16 bits precision
155 static double Pow64( float x, float y ); // x raised to the power y with 64 bits precision
157 static float Exp( float f ); // e raised to the power f with 32 bits precision
158 static float Exp16( float f ); // e raised to the power f with 16 bits precision
159 static double Exp64( float f ); // e raised to the power f with 64 bits precision
161 static float Log( float f ); // natural logarithm with 32 bits precision
162 static float Log16( float f ); // natural logarithm with 16 bits precision
163 static double Log64( float f ); // natural logarithm with 64 bits precision
165 static int IPow( int x, int y ); // integral x raised to the power y
166 static int ILog2( float f ); // integral base-2 logarithm of the floating point value
167 static int ILog2( int i ); // integral base-2 logarithm of the integer value
169 static int BitsForFloat( float f ); // minumum number of bits required to represent ceil( f )
170 static int BitsForInteger( int i ); // minumum number of bits required to represent i
171 static int MaskForFloatSign( float f );// returns 0x00000000 if x >= 0.0f and returns 0xFFFFFFFF if x <= -0.0f
172 static int MaskForIntegerSign( int i );// returns 0x00000000 if x >= 0 and returns 0xFFFFFFFF if x < 0
173 static int FloorPowerOfTwo( int x ); // round x down to the nearest power of 2
174 static int CeilPowerOfTwo( int x ); // round x up to the nearest power of 2
175 static bool IsPowerOfTwo( int x ); // returns true if x is a power of 2
176 static int BitCount( int x ); // returns the number of 1 bits in x
177 static int BitReverse( int x ); // returns the bit reverse of x
179 static int Abs( int x ); // returns the absolute value of the integer value (for reference only)
180 static float Fabs( float f ); // returns the absolute value of the floating point value
181 static float Floor( float f ); // returns the largest integer that is less than or equal to the given value
182 static float Ceil( float f ); // returns the smallest integer that is greater than or equal to the given value
183 static float Rint( float f ); // returns the nearest integer
184 static int Ftoi( float f ); // float to int conversion
185 static int FtoiFast( float f ); // fast float to int conversion but uses current FPU round mode (default round nearest)
186 static unsigned long Ftol( float f ); // float to long conversion
187 static unsigned long FtolFast( float ); // fast float to long conversion but uses current FPU round mode (default round nearest)
189 static signed char ClampChar( int i );
190 static signed short ClampShort( int i );
191 static int ClampInt( int min, int max, int value );
192 static float ClampFloat( float min, float max, float value );
194 static float AngleNormalize360( float angle );
195 static float AngleNormalize180( float angle );
196 static float AngleDelta( float angle1, float angle2 );
198 static int FloatToBits( float f, int exponentBits, int mantissaBits );
199 static float BitsToFloat( int i, int exponentBits, int mantissaBits );
201 static int FloatHash( const float *array, const int numFloats );
203 static const float PI; // pi
204 static const float TWO_PI; // pi * 2
205 static const float HALF_PI; // pi / 2
206 static const float ONEFOURTH_PI; // pi / 4
207 static const float E; // e
208 static const float SQRT_TWO; // sqrt( 2 )
209 static const float SQRT_THREE; // sqrt( 3 )
210 static const float SQRT_1OVER2; // sqrt( 1 / 2 )
211 static const float SQRT_1OVER3; // sqrt( 1 / 3 )
212 static const float M_DEG2RAD; // degrees to radians multiplier
213 static const float M_RAD2DEG; // radians to degrees multiplier
214 static const float M_SEC2MS; // seconds to milliseconds multiplier
215 static const float M_MS2SEC; // milliseconds to seconds multiplier
216 static const float INFINITY; // huge number which should be larger than any valid number used
217 static const float FLT_EPSILON; // smallest positive number such that 1.0+FLT_EPSILON != 1.0
224 LOOKUP_POS = (EXP_POS-LOOKUP_BITS),
225 SEED_POS = (EXP_POS-8),
226 SQRT_TABLE_SIZE = (2<<LOOKUP_BITS),
227 LOOKUP_MASK = (SQRT_TABLE_SIZE-1)
235 static dword iSqrt[SQRT_TABLE_SIZE];
236 static bool initialized;
239 ID_INLINE float idMath::RSqrt( float x ) {
245 i = *reinterpret_cast<long *>( &x );
246 i = 0x5f3759df - ( i >> 1 );
247 r = *reinterpret_cast<float *>( &i );
248 r = r * ( 1.5f - r * r * y );
252 ID_INLINE float idMath::InvSqrt16( float x ) {
254 dword a = ((union _flint*)(&x))->i;
257 assert( initialized );
260 seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
262 r = r * ( 1.5f - r * r * y );
266 ID_INLINE float idMath::InvSqrt( float x ) {
268 dword a = ((union _flint*)(&x))->i;
271 assert( initialized );
274 seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
276 r = r * ( 1.5f - r * r * y );
277 r = r * ( 1.5f - r * r * y );
281 ID_INLINE double idMath::InvSqrt64( float x ) {
282 dword a = ((union _flint*)(&x))->i;
285 assert( initialized );
288 seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
290 r = r * ( 1.5f - r * r * y );
291 r = r * ( 1.5f - r * r * y );
292 r = r * ( 1.5f - r * r * y );
296 ID_INLINE float idMath::Sqrt16( float x ) {
297 return x * InvSqrt16( x );
300 ID_INLINE float idMath::Sqrt( float x ) {
301 return x * InvSqrt( x );
304 ID_INLINE double idMath::Sqrt64( float x ) {
305 return x * InvSqrt64( x );
308 ID_INLINE float idMath::Sin( float a ) {
312 ID_INLINE float idMath::Sin16( float a ) {
315 if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) {
316 a -= floorf( a / TWO_PI ) * TWO_PI;
324 if ( a > PI + HALF_PI ) {
332 if ( fabs( a ) >= HALF_PI ) {
333 a = ( ( a < 0.0f ) ? -PI : PI ) - a;
337 return a * ( ( ( ( ( -2.39e-08f * s + 2.7526e-06f ) * s - 1.98409e-04f ) * s + 8.3333315e-03f ) * s - 1.666666664e-01f ) * s + 1.0f );
340 ID_INLINE double idMath::Sin64( float a ) {
344 ID_INLINE float idMath::Cos( float a ) {
348 ID_INLINE float idMath::Cos16( float a ) {
351 if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) {
352 a -= floorf( a / TWO_PI ) * TWO_PI;
363 if ( a > PI + HALF_PI ) {
373 if ( fabs( a ) >= HALF_PI ) {
374 a = ( ( a < 0.0f ) ? -PI : PI ) - a;
381 return d * ( ( ( ( ( -2.605e-07f * s + 2.47609e-05f ) * s - 1.3888397e-03f ) * s + 4.16666418e-02f ) * s - 4.999999963e-01f ) * s + 1.0f );
384 ID_INLINE double idMath::Cos64( float a ) {
388 ID_INLINE void idMath::SinCos( float a, float &s, float &c ) {
404 ID_INLINE void idMath::SinCos16( float a, float &s, float &c ) {
407 if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) {
408 a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI;
419 if ( a > PI + HALF_PI ) {
429 if ( fabs( a ) >= HALF_PI ) {
430 a = ( ( a < 0.0f ) ? -PI : PI ) - a;
437 s = a * ( ( ( ( ( -2.39e-08f * t + 2.7526e-06f ) * t - 1.98409e-04f ) * t + 8.3333315e-03f ) * t - 1.666666664e-01f ) * t + 1.0f );
438 c = d * ( ( ( ( ( -2.605e-07f * t + 2.47609e-05f ) * t - 1.3888397e-03f ) * t + 4.16666418e-02f ) * t - 4.999999963e-01f ) * t + 1.0f );
441 ID_INLINE void idMath::SinCos64( float a, double &s, double &c ) {
457 ID_INLINE float idMath::Tan( float a ) {
461 ID_INLINE float idMath::Tan16( float a ) {
465 if ( ( a < 0.0f ) || ( a >= PI ) ) {
466 a -= floorf( a / PI ) * PI;
470 if ( a > ONEFOURTH_PI ) {
477 if ( a > HALF_PI + ONEFOURTH_PI ) {
487 if ( fabs( a ) >= ONEFOURTH_PI ) {
488 a = ( ( a < 0.0f ) ? -HALF_PI : HALF_PI ) - a;
495 s = a * ( ( ( ( ( ( 9.5168091e-03f * s + 2.900525e-03f ) * s + 2.45650893e-02f ) * s + 5.33740603e-02f ) * s + 1.333923995e-01f ) * s + 3.333314036e-01f ) * s + 1.0f );
503 ID_INLINE double idMath::Tan64( float a ) {
507 ID_INLINE float idMath::ASin( float a ) {
517 ID_INLINE float idMath::ASin16( float a ) {
518 if ( FLOATSIGNBITSET( a ) ) {
523 return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ) - HALF_PI;
528 return HALF_PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a );
532 ID_INLINE double idMath::ASin64( float a ) {
542 ID_INLINE float idMath::ACos( float a ) {
552 ID_INLINE float idMath::ACos16( float a ) {
553 if ( FLOATSIGNBITSET( a ) ) {
558 return PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a );
563 return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a );
567 ID_INLINE double idMath::ACos64( float a ) {
577 ID_INLINE float idMath::ATan( float a ) {
581 ID_INLINE float idMath::ATan16( float a ) {
584 if ( fabs( a ) > 1.0f ) {
587 s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
588 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
589 if ( FLOATSIGNBITSET( a ) ) {
596 return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
597 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
601 ID_INLINE double idMath::ATan64( float a ) {
605 ID_INLINE float idMath::ATan( float y, float x ) {
606 return atan2f( y, x );
609 ID_INLINE float idMath::ATan16( float y, float x ) {
612 if ( fabs( y ) > fabs( x ) ) {
615 s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
616 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
617 if ( FLOATSIGNBITSET( a ) ) {
625 return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
626 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
630 ID_INLINE double idMath::ATan64( float y, float x ) {
631 return atan2( y, x );
634 ID_INLINE float idMath::Pow( float x, float y ) {
638 ID_INLINE float idMath::Pow16( float x, float y ) {
639 return Exp16( y * Log16( x ) );
642 ID_INLINE double idMath::Pow64( float x, float y ) {
646 ID_INLINE float idMath::Exp( float f ) {
650 ID_INLINE float idMath::Exp16( float f ) {
651 int i, s, e, m, exponent;
652 float x, x2, y, p, q;
654 x = f * 1.44269504088896340f; // multiply with ( 1 / log( 2 ) )
656 i = *reinterpret_cast<int *>(&x);
657 s = ( i >> IEEE_FLT_SIGN_BIT );
658 e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
659 m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS );
660 i = ( ( m >> ( IEEE_FLT_MANTISSA_BITS - e ) ) & ~( e >> 31 ) ) ^ s;
667 exponent = ( i + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS;
668 y = *reinterpret_cast<float *>(&exponent);
672 y *= 1.4142135623730950488f; // multiply with sqrt( 2 )
675 p = x * ( 7.2152891511493f + x2 * 0.0576900723731f );
676 q = 20.8189237930062f + x2;
677 x = y * ( q + p ) / ( q - p );
681 ID_INLINE double idMath::Exp64( float f ) {
685 ID_INLINE float idMath::Log( float f ) {
689 ID_INLINE float idMath::Log16( float f ) {
693 i = *reinterpret_cast<int *>(&f);
694 exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
695 i -= ( exponent + 1 ) << IEEE_FLT_MANTISSA_BITS; // get value in the range [.5, 1>
696 y = *reinterpret_cast<float *>(&i);
697 y *= 1.4142135623730950488f; // multiply with sqrt( 2 )
698 y = ( y - 1.0f ) / ( y + 1.0f );
700 y = y * ( 2.000000000046727f + y2 * ( 0.666666635059382f + y2 * ( 0.4000059794795f + y2 * ( 0.28525381498f + y2 * 0.2376245609f ) ) ) );
701 y += 0.693147180559945f * ( (float)exponent + 0.5f );
705 ID_INLINE double idMath::Log64( float f ) {
709 ID_INLINE int idMath::IPow( int x, int y ) {
710 int r; for( r = x; y > 1; y-- ) { r *= x; } return r;
713 ID_INLINE int idMath::ILog2( float f ) {
714 return ( ( (*reinterpret_cast<int *>(&f)) >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
717 ID_INLINE int idMath::ILog2( int i ) {
718 return ILog2( (float)i );
721 ID_INLINE int idMath::BitsForFloat( float f ) {
722 return ILog2( f ) + 1;
725 ID_INLINE int idMath::BitsForInteger( int i ) {
726 return ILog2( (float)i ) + 1;
729 ID_INLINE int idMath::MaskForFloatSign( float f ) {
730 return ( (*reinterpret_cast<int *>(&f)) >> 31 );
733 ID_INLINE int idMath::MaskForIntegerSign( int i ) {
737 ID_INLINE int idMath::FloorPowerOfTwo( int x ) {
738 return CeilPowerOfTwo( x ) >> 1;
741 ID_INLINE int idMath::CeilPowerOfTwo( int x ) {
752 ID_INLINE bool idMath::IsPowerOfTwo( int x ) {
753 return ( x & ( x - 1 ) ) == 0 && x > 0;
756 ID_INLINE int idMath::BitCount( int x ) {
757 x -= ( ( x >> 1 ) & 0x55555555 );
758 x = ( ( ( x >> 2 ) & 0x33333333 ) + ( x & 0x33333333 ) );
759 x = ( ( ( x >> 4 ) + x ) & 0x0f0f0f0f );
761 return ( ( x + ( x >> 16 ) ) & 0x0000003f );
764 ID_INLINE int idMath::BitReverse( int x ) {
765 x = ( ( ( x >> 1 ) & 0x55555555 ) | ( ( x & 0x55555555 ) << 1 ) );
766 x = ( ( ( x >> 2 ) & 0x33333333 ) | ( ( x & 0x33333333 ) << 2 ) );
767 x = ( ( ( x >> 4 ) & 0x0f0f0f0f ) | ( ( x & 0x0f0f0f0f ) << 4 ) );
768 x = ( ( ( x >> 8 ) & 0x00ff00ff ) | ( ( x & 0x00ff00ff ) << 8 ) );
769 return ( ( x >> 16 ) | ( x << 16 ) );
772 ID_INLINE int idMath::Abs( int x ) {
774 return ( ( x ^ y ) - y );
777 ID_INLINE float idMath::Fabs( float f ) {
778 int tmp = *reinterpret_cast<int *>( &f );
780 return *reinterpret_cast<float *>( &tmp );
783 ID_INLINE float idMath::Floor( float f ) {
787 ID_INLINE float idMath::Ceil( float f ) {
791 ID_INLINE float idMath::Rint( float f ) {
792 return floorf( f + 0.5f );
795 ID_INLINE int idMath::Ftoi( float f ) {
799 ID_INLINE int idMath::FtoiFast( float f ) {
803 __asm fistp i // use default rouding mode (round nearest)
805 #elif 0 // round chop (C/C++ standard)
806 int i, s, e, m, shift;
807 i = *reinterpret_cast<int *>(&f);
808 s = i >> IEEE_FLT_SIGN_BIT;
809 e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
810 m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS );
811 shift = e - IEEE_FLT_MANTISSA_BITS;
812 return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s;
813 //#elif defined( __i386__ )
816 __asm__ __volatile__ (
827 ID_INLINE unsigned long idMath::Ftol( float f ) {
828 return (unsigned long) f;
831 ID_INLINE unsigned long idMath::FtolFast( float f ) {
833 // FIXME: this overflows on 31bits still .. same as FtoiFast
836 __asm fistp i // use default rouding mode (round nearest)
838 #elif 0 // round chop (C/C++ standard)
839 int i, s, e, m, shift;
840 i = *reinterpret_cast<int *>(&f);
841 s = i >> IEEE_FLT_SIGN_BIT;
842 e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
843 m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS );
844 shift = e - IEEE_FLT_MANTISSA_BITS;
845 return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s;
846 //#elif defined( __i386__ )
848 // for some reason, on gcc I need to make sure i == 0 before performing a fistp
850 __asm__ __volatile__ (
857 return (unsigned long) f;
861 ID_INLINE signed char idMath::ClampChar( int i ) {
871 ID_INLINE signed short idMath::ClampShort( int i ) {
881 ID_INLINE int idMath::ClampInt( int min, int max, int value ) {
891 ID_INLINE float idMath::ClampFloat( float min, float max, float value ) {
901 ID_INLINE float idMath::AngleNormalize360( float angle ) {
902 if ( ( angle >= 360.0f ) || ( angle < 0.0f ) ) {
903 angle -= floor( angle / 360.0f ) * 360.0f;
908 ID_INLINE float idMath::AngleNormalize180( float angle ) {
909 angle = AngleNormalize360( angle );
910 if ( angle > 180.0f ) {
916 ID_INLINE float idMath::AngleDelta( float angle1, float angle2 ) {
917 return AngleNormalize180( angle1 - angle2 );
920 ID_INLINE int idMath::FloatHash( const float *array, const int numFloats ) {
924 ptr = reinterpret_cast<const int *>( array );
925 for ( i = 0; i < numFloats; i++ ) {
931 #endif /* !__MATH_MATH_H__ */