doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Math.h
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
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.
13 
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.
18 
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/>.
21 
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.
23 
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.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __MATH_MATH_H__
30 #define __MATH_MATH_H__
31 
32 #ifdef MACOS_X
33 // for square root estimate instruction
34 #ifdef PPC_INTRINSICS
35 #include <ppc_intrinsics.h>
36 #endif
37 // for FLT_MIN
38 #include <float.h>
39 #endif
40 /*
41 ===============================================================================
42 
43  Math
44 
45 ===============================================================================
46 */
47 
48 #ifdef INFINITY
49 #undef INFINITY
50 #endif
51 
52 #ifdef FLT_EPSILON
53 #undef FLT_EPSILON
54 #endif
55 
56 #define DEG2RAD(a) ( (a) * idMath::M_DEG2RAD )
57 #define RAD2DEG(a) ( (a) * idMath::M_RAD2DEG )
58 
59 #define SEC2MS(t) ( idMath::FtoiFast( (t) * idMath::M_SEC2MS ) )
60 #define MS2SEC(t) ( (t) * idMath::M_MS2SEC )
61 
62 #define ANGLE2SHORT(x) ( idMath::FtoiFast( (x) * 65536.0f / 360.0f ) & 65535 )
63 #define SHORT2ANGLE(x) ( (x) * ( 360.0f / 65536.0f ) )
64 
65 #define ANGLE2BYTE(x) ( idMath::FtoiFast( (x) * 256.0f / 360.0f ) & 255 )
66 #define BYTE2ANGLE(x) ( (x) * ( 360.0f / 256.0f ) )
67 
68 #define FLOATSIGNBITSET(f) ((*(const unsigned long *)&(f)) >> 31)
69 #define FLOATSIGNBITNOTSET(f) ((~(*(const unsigned long *)&(f))) >> 31)
70 #define FLOATNOTZERO(f) ((*(const unsigned long *)&(f)) & ~(1<<31) )
71 #define INTSIGNBITSET(i) (((const unsigned long)(i)) >> 31)
72 #define INTSIGNBITNOTSET(i) ((~((const unsigned long)(i))) >> 31)
73 
74 #define FLOAT_IS_NAN(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x7f800000)
75 #define FLOAT_IS_INF(x) (((*(const unsigned long *)&x) & 0x7fffffff) == 0x7f800000)
76 #define FLOAT_IS_IND(x) ((*(const unsigned long *)&x) == 0xffc00000)
77 #define FLOAT_IS_DENORMAL(x) (((*(const unsigned long *)&x) & 0x7f800000) == 0x00000000 && \
78  ((*(const unsigned long *)&x) & 0x007fffff) != 0x00000000 )
79 
80 #define IEEE_FLT_MANTISSA_BITS 23
81 #define IEEE_FLT_EXPONENT_BITS 8
82 #define IEEE_FLT_EXPONENT_BIAS 127
83 #define IEEE_FLT_SIGN_BIT 31
84 
85 #define IEEE_DBL_MANTISSA_BITS 52
86 #define IEEE_DBL_EXPONENT_BITS 11
87 #define IEEE_DBL_EXPONENT_BIAS 1023
88 #define IEEE_DBL_SIGN_BIT 63
89 
90 #define IEEE_DBLE_MANTISSA_BITS 63
91 #define IEEE_DBLE_EXPONENT_BITS 15
92 #define IEEE_DBLE_EXPONENT_BIAS 0
93 #define IEEE_DBLE_SIGN_BIT 79
94 
95 template<class T> ID_INLINE int MaxIndex( T x, T y ) { return ( x > y ) ? 0 : 1; }
96 template<class T> ID_INLINE int MinIndex( T x, T y ) { return ( x < y ) ? 0 : 1; }
97 
98 template<class T> ID_INLINE T Max3( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? x : z ) : ( ( y > z ) ? y : z ); }
99 template<class T> ID_INLINE T Min3( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? x : z ) : ( ( y < z ) ? y : z ); }
100 template<class T> ID_INLINE int Max3Index( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? 0 : 2 ) : ( ( y > z ) ? 1 : 2 ); }
101 template<class T> ID_INLINE int Min3Index( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? 0 : 2 ) : ( ( y < z ) ? 1 : 2 ); }
102 
103 template<class T> ID_INLINE T Sign( T f ) { return ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ); }
104 template<class T> ID_INLINE T Square( T x ) { return x * x; }
105 template<class T> ID_INLINE T Cube( T x ) { return x * x * x; }
106 
107 
108 class idMath {
109 public:
110 
111  static void Init( void );
112 
113  static float RSqrt( float x ); // reciprocal square root, returns huge number when x == 0.0
114 
115  static float InvSqrt( float x ); // inverse square root with 32 bits precision, returns huge number when x == 0.0
116  static float InvSqrt16( float x ); // inverse square root with 16 bits precision, returns huge number when x == 0.0
117  static double InvSqrt64( float x ); // inverse square root with 64 bits precision, returns huge number when x == 0.0
118 
119  static float Sqrt( float x ); // square root with 32 bits precision
120  static float Sqrt16( float x ); // square root with 16 bits precision
121  static double Sqrt64( float x ); // square root with 64 bits precision
122 
123  static float Sin( float a ); // sine with 32 bits precision
124  static float Sin16( float a ); // sine with 16 bits precision, maximum absolute error is 2.3082e-09
125  static double Sin64( float a ); // sine with 64 bits precision
126 
127  static float Cos( float a ); // cosine with 32 bits precision
128  static float Cos16( float a ); // cosine with 16 bits precision, maximum absolute error is 2.3082e-09
129  static double Cos64( float a ); // cosine with 64 bits precision
130 
131  static void SinCos( float a, float &s, float &c ); // sine and cosine with 32 bits precision
132  static void SinCos16( float a, float &s, float &c ); // sine and cosine with 16 bits precision
133  static void SinCos64( float a, double &s, double &c ); // sine and cosine with 64 bits precision
134 
135  static float Tan( float a ); // tangent with 32 bits precision
136  static float Tan16( float a ); // tangent with 16 bits precision, maximum absolute error is 1.8897e-08
137  static double Tan64( float a ); // tangent with 64 bits precision
138 
139  static float ASin( float a ); // arc sine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN
140  static float ASin16( float a ); // arc sine with 16 bits precision, maximum absolute error is 6.7626e-05
141  static double ASin64( float a ); // arc sine with 64 bits precision
142 
143  static float ACos( float a ); // arc cosine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN
144  static float ACos16( float a ); // arc cosine with 16 bits precision, maximum absolute error is 6.7626e-05
145  static double ACos64( float a ); // arc cosine with 64 bits precision
146 
147  static float ATan( float a ); // arc tangent with 32 bits precision
148  static float ATan16( float a ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08
149  static double ATan64( float a ); // arc tangent with 64 bits precision
150 
151  static float ATan( float y, float x ); // arc tangent with 32 bits precision
152  static float ATan16( float y, float x ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08
153  static double ATan64( float y, float x ); // arc tangent with 64 bits precision
154 
155  static float Pow( float x, float y ); // x raised to the power y with 32 bits precision
156  static float Pow16( float x, float y ); // x raised to the power y with 16 bits precision
157  static double Pow64( float x, float y ); // x raised to the power y with 64 bits precision
158 
159  static float Exp( float f ); // e raised to the power f with 32 bits precision
160  static float Exp16( float f ); // e raised to the power f with 16 bits precision
161  static double Exp64( float f ); // e raised to the power f with 64 bits precision
162 
163  static float Log( float f ); // natural logarithm with 32 bits precision
164  static float Log16( float f ); // natural logarithm with 16 bits precision
165  static double Log64( float f ); // natural logarithm with 64 bits precision
166 
167  static int IPow( int x, int y ); // integral x raised to the power y
168  static int ILog2( float f ); // integral base-2 logarithm of the floating point value
169  static int ILog2( int i ); // integral base-2 logarithm of the integer value
170 
171  static int BitsForFloat( float f ); // minumum number of bits required to represent ceil( f )
172  static int BitsForInteger( int i ); // minumum number of bits required to represent i
173  static int MaskForFloatSign( float f );// returns 0x00000000 if x >= 0.0f and returns 0xFFFFFFFF if x <= -0.0f
174  static int MaskForIntegerSign( int i );// returns 0x00000000 if x >= 0 and returns 0xFFFFFFFF if x < 0
175  static int FloorPowerOfTwo( int x ); // round x down to the nearest power of 2
176  static int CeilPowerOfTwo( int x ); // round x up to the nearest power of 2
177  static bool IsPowerOfTwo( int x ); // returns true if x is a power of 2
178  static int BitCount( int x ); // returns the number of 1 bits in x
179  static int BitReverse( int x ); // returns the bit reverse of x
180 
181  static int Abs( int x ); // returns the absolute value of the integer value (for reference only)
182  static float Fabs( float f ); // returns the absolute value of the floating point value
183  static float Floor( float f ); // returns the largest integer that is less than or equal to the given value
184  static float Ceil( float f ); // returns the smallest integer that is greater than or equal to the given value
185  static float Rint( float f ); // returns the nearest integer
186  static int Ftoi( float f ); // float to int conversion
187  static int FtoiFast( float f ); // fast float to int conversion but uses current FPU round mode (default round nearest)
188  static unsigned long Ftol( float f ); // float to long conversion
189  static unsigned long FtolFast( float ); // fast float to long conversion but uses current FPU round mode (default round nearest)
190 
191  static signed char ClampChar( int i );
192  static signed short ClampShort( int i );
193  static int ClampInt( int min, int max, int value );
194  static float ClampFloat( float min, float max, float value );
195 
196  static float AngleNormalize360( float angle );
197  static float AngleNormalize180( float angle );
198  static float AngleDelta( float angle1, float angle2 );
199 
200  static int FloatToBits( float f, int exponentBits, int mantissaBits );
201  static float BitsToFloat( int i, int exponentBits, int mantissaBits );
202 
203  static int FloatHash( const float *array, const int numFloats );
204 
205  static const float PI; // pi
206  static const float TWO_PI; // pi * 2
207  static const float HALF_PI; // pi / 2
208  static const float ONEFOURTH_PI; // pi / 4
209  static const float E; // e
210  static const float SQRT_TWO; // sqrt( 2 )
211  static const float SQRT_THREE; // sqrt( 3 )
212  static const float SQRT_1OVER2; // sqrt( 1 / 2 )
213  static const float SQRT_1OVER3; // sqrt( 1 / 3 )
214  static const float M_DEG2RAD; // degrees to radians multiplier
215  static const float M_RAD2DEG; // radians to degrees multiplier
216  static const float M_SEC2MS; // seconds to milliseconds multiplier
217  static const float M_MS2SEC; // milliseconds to seconds multiplier
218  static const float INFINITY; // huge number which should be larger than any valid number used
219  static const float FLT_EPSILON; // smallest positive number such that 1.0+FLT_EPSILON != 1.0
220 
221 private:
222  enum {
224  EXP_POS = 23,
225  EXP_BIAS = 127,
230  };
231 
232  union _flint {
234  float f;
235  };
236 
238  static bool initialized;
239 };
240 
241 ID_INLINE float idMath::RSqrt( float x ) {
242 
243  long i;
244  float y, r;
245 
246  y = x * 0.5f;
247  i = *reinterpret_cast<long *>( &x );
248  i = 0x5f3759df - ( i >> 1 );
249  r = *reinterpret_cast<float *>( &i );
250  r = r * ( 1.5f - r * r * y );
251  return r;
252 }
253 
254 ID_INLINE float idMath::InvSqrt16( float x ) {
255 
256  dword a = ((union _flint*)(&x))->i;
257  union _flint seed;
258 
259  assert( initialized );
260 
261  double y = x * 0.5f;
262  seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
263  double r = seed.f;
264  r = r * ( 1.5f - r * r * y );
265  return (float) r;
266 }
267 
268 ID_INLINE float idMath::InvSqrt( float x ) {
269 
270  dword a = ((union _flint*)(&x))->i;
271  union _flint seed;
272 
273  assert( initialized );
274 
275  double y = x * 0.5f;
276  seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
277  double r = seed.f;
278  r = r * ( 1.5f - r * r * y );
279  r = r * ( 1.5f - r * r * y );
280  return (float) r;
281 }
282 
283 ID_INLINE double idMath::InvSqrt64( float x ) {
284  dword a = ((union _flint*)(&x))->i;
285  union _flint seed;
286 
287  assert( initialized );
288 
289  double y = x * 0.5f;
290  seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
291  double r = seed.f;
292  r = r * ( 1.5f - r * r * y );
293  r = r * ( 1.5f - r * r * y );
294  r = r * ( 1.5f - r * r * y );
295  return r;
296 }
297 
298 ID_INLINE float idMath::Sqrt16( float x ) {
299  return x * InvSqrt16( x );
300 }
301 
302 ID_INLINE float idMath::Sqrt( float x ) {
303  return x * InvSqrt( x );
304 }
305 
306 ID_INLINE double idMath::Sqrt64( float x ) {
307  return x * InvSqrt64( x );
308 }
309 
310 ID_INLINE float idMath::Sin( float a ) {
311  return sinf( a );
312 }
313 
314 ID_INLINE float idMath::Sin16( float a ) {
315  float s;
316 
317  if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) {
318  a -= floorf( a / TWO_PI ) * TWO_PI;
319  }
320 #if 1
321  if ( a < PI ) {
322  if ( a > HALF_PI ) {
323  a = PI - a;
324  }
325  } else {
326  if ( a > PI + HALF_PI ) {
327  a = a - TWO_PI;
328  } else {
329  a = PI - a;
330  }
331  }
332 #else
333  a = PI - a;
334  if ( fabs( a ) >= HALF_PI ) {
335  a = ( ( a < 0.0f ) ? -PI : PI ) - a;
336  }
337 #endif
338  s = a * a;
339  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 }
341 
342 ID_INLINE double idMath::Sin64( float a ) {
343  return sin( a );
344 }
345 
346 ID_INLINE float idMath::Cos( float a ) {
347  return cosf( a );
348 }
349 
350 ID_INLINE float idMath::Cos16( float a ) {
351  float s, d;
352 
353  if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) {
354  a -= floorf( a / TWO_PI ) * TWO_PI;
355  }
356 #if 1
357  if ( a < PI ) {
358  if ( a > HALF_PI ) {
359  a = PI - a;
360  d = -1.0f;
361  } else {
362  d = 1.0f;
363  }
364  } else {
365  if ( a > PI + HALF_PI ) {
366  a = a - TWO_PI;
367  d = 1.0f;
368  } else {
369  a = PI - a;
370  d = -1.0f;
371  }
372  }
373 #else
374  a = PI - a;
375  if ( fabs( a ) >= HALF_PI ) {
376  a = ( ( a < 0.0f ) ? -PI : PI ) - a;
377  d = 1.0f;
378  } else {
379  d = -1.0f;
380  }
381 #endif
382  s = a * a;
383  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 }
385 
386 ID_INLINE double idMath::Cos64( float a ) {
387  return cos( a );
388 }
389 
390 ID_INLINE void idMath::SinCos( float a, float &s, float &c ) {
391 #ifdef _WIN32
392  _asm {
393  fld a
394  fsincos
395  mov ecx, c
396  mov edx, s
397  fstp dword ptr [ecx]
398  fstp dword ptr [edx]
399  }
400 #else
401  s = sinf( a );
402  c = cosf( a );
403 #endif
404 }
405 
406 ID_INLINE void idMath::SinCos16( float a, float &s, float &c ) {
407  float t, d;
408 
409  if ( ( a < 0.0f ) || ( a >= idMath::TWO_PI ) ) {
410  a -= floorf( a / idMath::TWO_PI ) * idMath::TWO_PI;
411  }
412 #if 1
413  if ( a < PI ) {
414  if ( a > HALF_PI ) {
415  a = PI - a;
416  d = -1.0f;
417  } else {
418  d = 1.0f;
419  }
420  } else {
421  if ( a > PI + HALF_PI ) {
422  a = a - TWO_PI;
423  d = 1.0f;
424  } else {
425  a = PI - a;
426  d = -1.0f;
427  }
428  }
429 #else
430  a = PI - a;
431  if ( fabs( a ) >= HALF_PI ) {
432  a = ( ( a < 0.0f ) ? -PI : PI ) - a;
433  d = 1.0f;
434  } else {
435  d = -1.0f;
436  }
437 #endif
438  t = a * a;
439  s = a * ( ( ( ( ( -2.39e-08f * t + 2.7526e-06f ) * t - 1.98409e-04f ) * t + 8.3333315e-03f ) * t - 1.666666664e-01f ) * t + 1.0f );
440  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 }
442 
443 ID_INLINE void idMath::SinCos64( float a, double &s, double &c ) {
444 #ifdef _WIN32
445  _asm {
446  fld a
447  fsincos
448  mov ecx, c
449  mov edx, s
450  fstp qword ptr [ecx]
451  fstp qword ptr [edx]
452  }
453 #else
454  s = sin( a );
455  c = cos( a );
456 #endif
457 }
458 
459 ID_INLINE float idMath::Tan( float a ) {
460  return tanf( a );
461 }
462 
463 ID_INLINE float idMath::Tan16( float a ) {
464  float s;
465  bool reciprocal;
466 
467  if ( ( a < 0.0f ) || ( a >= PI ) ) {
468  a -= floorf( a / PI ) * PI;
469  }
470 #if 1
471  if ( a < HALF_PI ) {
472  if ( a > ONEFOURTH_PI ) {
473  a = HALF_PI - a;
474  reciprocal = true;
475  } else {
476  reciprocal = false;
477  }
478  } else {
479  if ( a > HALF_PI + ONEFOURTH_PI ) {
480  a = a - PI;
481  reciprocal = false;
482  } else {
483  a = HALF_PI - a;
484  reciprocal = true;
485  }
486  }
487 #else
488  a = HALF_PI - a;
489  if ( fabs( a ) >= ONEFOURTH_PI ) {
490  a = ( ( a < 0.0f ) ? -HALF_PI : HALF_PI ) - a;
491  reciprocal = false;
492  } else {
493  reciprocal = true;
494  }
495 #endif
496  s = a * a;
497  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 );
498  if ( reciprocal ) {
499  return 1.0f / s;
500  } else {
501  return s;
502  }
503 }
504 
505 ID_INLINE double idMath::Tan64( float a ) {
506  return tan( a );
507 }
508 
509 ID_INLINE float idMath::ASin( float a ) {
510  if ( a <= -1.0f ) {
511  return -HALF_PI;
512  }
513  if ( a >= 1.0f ) {
514  return HALF_PI;
515  }
516  return asinf( a );
517 }
518 
519 ID_INLINE float idMath::ASin16( float a ) {
520  if ( FLOATSIGNBITSET( a ) ) {
521  if ( a <= -1.0f ) {
522  return -HALF_PI;
523  }
524  a = fabs( a );
525  return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a ) - HALF_PI;
526  } else {
527  if ( a >= 1.0f ) {
528  return HALF_PI;
529  }
530  return HALF_PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a );
531  }
532 }
533 
534 ID_INLINE double idMath::ASin64( float a ) {
535  if ( a <= -1.0f ) {
536  return -HALF_PI;
537  }
538  if ( a >= 1.0f ) {
539  return HALF_PI;
540  }
541  return asin( a );
542 }
543 
544 ID_INLINE float idMath::ACos( float a ) {
545  if ( a <= -1.0f ) {
546  return PI;
547  }
548  if ( a >= 1.0f ) {
549  return 0.0f;
550  }
551  return acosf( a );
552 }
553 
554 ID_INLINE float idMath::ACos16( float a ) {
555  if ( FLOATSIGNBITSET( a ) ) {
556  if ( a <= -1.0f ) {
557  return PI;
558  }
559  a = fabs( a );
560  return PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a );
561  } else {
562  if ( a >= 1.0f ) {
563  return 0.0f;
564  }
565  return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * sqrt( 1.0f - a );
566  }
567 }
568 
569 ID_INLINE double idMath::ACos64( float a ) {
570  if ( a <= -1.0f ) {
571  return PI;
572  }
573  if ( a >= 1.0f ) {
574  return 0.0f;
575  }
576  return acos( a );
577 }
578 
579 ID_INLINE float idMath::ATan( float a ) {
580  return atanf( a );
581 }
582 
583 ID_INLINE float idMath::ATan16( float a ) {
584  float s;
585 
586  if ( fabs( a ) > 1.0f ) {
587  a = 1.0f / a;
588  s = a * a;
589  s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
590  * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
591  if ( FLOATSIGNBITSET( a ) ) {
592  return s - HALF_PI;
593  } else {
594  return s + HALF_PI;
595  }
596  } else {
597  s = a * a;
598  return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
599  * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
600  }
601 }
602 
603 ID_INLINE double idMath::ATan64( float a ) {
604  return atan( a );
605 }
606 
607 ID_INLINE float idMath::ATan( float y, float x ) {
608  return atan2f( y, x );
609 }
610 
611 ID_INLINE float idMath::ATan16( float y, float x ) {
612  float a, s;
613 
614  if ( fabs( y ) > fabs( x ) ) {
615  a = x / y;
616  s = a * a;
617  s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
618  * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
619  if ( FLOATSIGNBITSET( a ) ) {
620  return s - HALF_PI;
621  } else {
622  return s + HALF_PI;
623  }
624  } else {
625  a = y / x;
626  s = a * a;
627  return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f )
628  * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a;
629  }
630 }
631 
632 ID_INLINE double idMath::ATan64( float y, float x ) {
633  return atan2( y, x );
634 }
635 
636 ID_INLINE float idMath::Pow( float x, float y ) {
637  return powf( x, y );
638 }
639 
640 ID_INLINE float idMath::Pow16( float x, float y ) {
641  return Exp16( y * Log16( x ) );
642 }
643 
644 ID_INLINE double idMath::Pow64( float x, float y ) {
645  return pow( x, y );
646 }
647 
648 ID_INLINE float idMath::Exp( float f ) {
649  return expf( f );
650 }
651 
652 ID_INLINE float idMath::Exp16( float f ) {
653  int i, s, e, m, exponent;
654  float x, x2, y, p, q;
655 
656  x = f * 1.44269504088896340f; // multiply with ( 1 / log( 2 ) )
657 #if 1
658  i = *reinterpret_cast<int *>(&x);
659  s = ( i >> IEEE_FLT_SIGN_BIT );
660  e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
661  m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS );
662  i = ( ( m >> ( IEEE_FLT_MANTISSA_BITS - e ) ) & ~( e >> 31 ) ) ^ s;
663 #else
664  i = (int) x;
665  if ( x < 0.0f ) {
666  i--;
667  }
668 #endif
669  exponent = ( i + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS;
670  y = *reinterpret_cast<float *>(&exponent);
671  x -= (float) i;
672  if ( x >= 0.5f ) {
673  x -= 0.5f;
674  y *= 1.4142135623730950488f; // multiply with sqrt( 2 )
675  }
676  x2 = x * x;
677  p = x * ( 7.2152891511493f + x2 * 0.0576900723731f );
678  q = 20.8189237930062f + x2;
679  x = y * ( q + p ) / ( q - p );
680  return x;
681 }
682 
683 ID_INLINE double idMath::Exp64( float f ) {
684  return exp( f );
685 }
686 
687 ID_INLINE float idMath::Log( float f ) {
688  return logf( f );
689 }
690 
691 ID_INLINE float idMath::Log16( float f ) {
692  int i, exponent;
693  float y, y2;
694 
695  i = *reinterpret_cast<int *>(&f);
696  exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
697  i -= ( exponent + 1 ) << IEEE_FLT_MANTISSA_BITS; // get value in the range [.5, 1>
698  y = *reinterpret_cast<float *>(&i);
699  y *= 1.4142135623730950488f; // multiply with sqrt( 2 )
700  y = ( y - 1.0f ) / ( y + 1.0f );
701  y2 = y * y;
702  y = y * ( 2.000000000046727f + y2 * ( 0.666666635059382f + y2 * ( 0.4000059794795f + y2 * ( 0.28525381498f + y2 * 0.2376245609f ) ) ) );
703  y += 0.693147180559945f * ( (float)exponent + 0.5f );
704  return y;
705 }
706 
707 ID_INLINE double idMath::Log64( float f ) {
708  return log( f );
709 }
710 
711 ID_INLINE int idMath::IPow( int x, int y ) {
712  int r; for( r = x; y > 1; y-- ) { r *= x; } return r;
713 }
714 
715 ID_INLINE int idMath::ILog2( float f ) {
716  return ( ( (*reinterpret_cast<int *>(&f)) >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
717 }
718 
719 ID_INLINE int idMath::ILog2( int i ) {
720  return ILog2( (float)i );
721 }
722 
723 ID_INLINE int idMath::BitsForFloat( float f ) {
724  return ILog2( f ) + 1;
725 }
726 
727 ID_INLINE int idMath::BitsForInteger( int i ) {
728  return ILog2( (float)i ) + 1;
729 }
730 
731 ID_INLINE int idMath::MaskForFloatSign( float f ) {
732  return ( (*reinterpret_cast<int *>(&f)) >> 31 );
733 }
734 
735 ID_INLINE int idMath::MaskForIntegerSign( int i ) {
736  return ( i >> 31 );
737 }
738 
739 ID_INLINE int idMath::FloorPowerOfTwo( int x ) {
740  return CeilPowerOfTwo( x ) >> 1;
741 }
742 
743 ID_INLINE int idMath::CeilPowerOfTwo( int x ) {
744  x--;
745  x |= x >> 1;
746  x |= x >> 2;
747  x |= x >> 4;
748  x |= x >> 8;
749  x |= x >> 16;
750  x++;
751  return x;
752 }
753 
754 ID_INLINE bool idMath::IsPowerOfTwo( int x ) {
755  return ( x & ( x - 1 ) ) == 0 && x > 0;
756 }
757 
758 ID_INLINE int idMath::BitCount( int x ) {
759  x -= ( ( x >> 1 ) & 0x55555555 );
760  x = ( ( ( x >> 2 ) & 0x33333333 ) + ( x & 0x33333333 ) );
761  x = ( ( ( x >> 4 ) + x ) & 0x0f0f0f0f );
762  x += ( x >> 8 );
763  return ( ( x + ( x >> 16 ) ) & 0x0000003f );
764 }
765 
766 ID_INLINE int idMath::BitReverse( int x ) {
767  x = ( ( ( x >> 1 ) & 0x55555555 ) | ( ( x & 0x55555555 ) << 1 ) );
768  x = ( ( ( x >> 2 ) & 0x33333333 ) | ( ( x & 0x33333333 ) << 2 ) );
769  x = ( ( ( x >> 4 ) & 0x0f0f0f0f ) | ( ( x & 0x0f0f0f0f ) << 4 ) );
770  x = ( ( ( x >> 8 ) & 0x00ff00ff ) | ( ( x & 0x00ff00ff ) << 8 ) );
771  return ( ( x >> 16 ) | ( x << 16 ) );
772 }
773 
774 ID_INLINE int idMath::Abs( int x ) {
775  int y = x >> 31;
776  return ( ( x ^ y ) - y );
777 }
778 
779 ID_INLINE float idMath::Fabs( float f ) {
780  int tmp = *reinterpret_cast<int *>( &f );
781  tmp &= 0x7FFFFFFF;
782  return *reinterpret_cast<float *>( &tmp );
783 }
784 
785 ID_INLINE float idMath::Floor( float f ) {
786  return floorf( f );
787 }
788 
789 ID_INLINE float idMath::Ceil( float f ) {
790  return ceilf( f );
791 }
792 
793 ID_INLINE float idMath::Rint( float f ) {
794  return floorf( f + 0.5f );
795 }
796 
797 ID_INLINE int idMath::Ftoi( float f ) {
798  return (int) f;
799 }
800 
801 ID_INLINE int idMath::FtoiFast( float f ) {
802 #ifdef _WIN32
803  int i;
804  __asm fld f
805  __asm fistp i // use default rouding mode (round nearest)
806  return i;
807 #elif 0 // round chop (C/C++ standard)
808  int i, s, e, m, shift;
809  i = *reinterpret_cast<int *>(&f);
810  s = i >> IEEE_FLT_SIGN_BIT;
811  e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
812  m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS );
813  shift = e - IEEE_FLT_MANTISSA_BITS;
814  return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s;
815 //#elif defined( __i386__ )
816 #elif 0
817  int i = 0;
818  __asm__ __volatile__ (
819  "fld %1\n" \
820  "fistp %0\n" \
821  : "=m" (i) \
822  : "m" (f) );
823  return i;
824 #else
825  return (int) f;
826 #endif
827 }
828 
829 ID_INLINE unsigned long idMath::Ftol( float f ) {
830  return (unsigned long) f;
831 }
832 
833 ID_INLINE unsigned long idMath::FtolFast( float f ) {
834 #ifdef _WIN32
835  // FIXME: this overflows on 31bits still .. same as FtoiFast
836  unsigned long i;
837  __asm fld f
838  __asm fistp i // use default rouding mode (round nearest)
839  return i;
840 #elif 0 // round chop (C/C++ standard)
841  int i, s, e, m, shift;
842  i = *reinterpret_cast<int *>(&f);
843  s = i >> IEEE_FLT_SIGN_BIT;
844  e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS;
845  m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS );
846  shift = e - IEEE_FLT_MANTISSA_BITS;
847  return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> 31 ) ) ^ s ) - s;
848 //#elif defined( __i386__ )
849 #elif 0
850  // for some reason, on gcc I need to make sure i == 0 before performing a fistp
851  int i = 0;
852  __asm__ __volatile__ (
853  "fld %1\n" \
854  "fistp %0\n" \
855  : "=m" (i) \
856  : "m" (f) );
857  return i;
858 #else
859  return (unsigned long) f;
860 #endif
861 }
862 
863 ID_INLINE signed char idMath::ClampChar( int i ) {
864  if ( i < -128 ) {
865  return -128;
866  }
867  if ( i > 127 ) {
868  return 127;
869  }
870  return i;
871 }
872 
873 ID_INLINE signed short idMath::ClampShort( int i ) {
874  if ( i < -32768 ) {
875  return -32768;
876  }
877  if ( i > 32767 ) {
878  return 32767;
879  }
880  return i;
881 }
882 
883 ID_INLINE int idMath::ClampInt( int min, int max, int value ) {
884  if ( value < min ) {
885  return min;
886  }
887  if ( value > max ) {
888  return max;
889  }
890  return value;
891 }
892 
893 ID_INLINE float idMath::ClampFloat( float min, float max, float value ) {
894  if ( value < min ) {
895  return min;
896  }
897  if ( value > max ) {
898  return max;
899  }
900  return value;
901 }
902 
903 ID_INLINE float idMath::AngleNormalize360( float angle ) {
904  if ( ( angle >= 360.0f ) || ( angle < 0.0f ) ) {
905  angle -= floor( angle / 360.0f ) * 360.0f;
906  }
907  return angle;
908 }
909 
910 ID_INLINE float idMath::AngleNormalize180( float angle ) {
911  angle = AngleNormalize360( angle );
912  if ( angle > 180.0f ) {
913  angle -= 360.0f;
914  }
915  return angle;
916 }
917 
918 ID_INLINE float idMath::AngleDelta( float angle1, float angle2 ) {
919  return AngleNormalize180( angle1 - angle2 );
920 }
921 
922 ID_INLINE int idMath::FloatHash( const float *array, const int numFloats ) {
923  int i, hash = 0;
924  const int *ptr;
925 
926  ptr = reinterpret_cast<const int *>( array );
927  for ( i = 0; i < numFloats; i++ ) {
928  hash ^= ptr[i];
929  }
930  return hash;
931 }
932 
933 #endif /* !__MATH_MATH_H__ */
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:2959
static float ATan16(float a)
Definition: Math.h:583
unsigned int dword
Definition: Lib.h:77
static const float INFINITY
Definition: Math.h:218
static float Log16(float f)
Definition: Math.h:691
Definition: Math.h:108
#define min(a, b)
GLsizei const GLfloat * value
Definition: glext.h:3614
static double Sqrt64(float x)
Definition: Math.h:306
static int BitReverse(int x)
Definition: Math.h:766
static const float SQRT_TWO
Definition: Math.h:210
assert(prefInfo.fullscreenBtn)
static float Log(float f)
Definition: Math.h:687
static double Tan64(float a)
Definition: Math.h:505
static void SinCos64(float a, double &s, double &c)
Definition: Math.h:443
#define IEEE_FLT_EXPONENT_BIAS
Definition: Math.h:82
static float Exp16(float f)
Definition: Math.h:652
static double Exp64(float f)
Definition: Math.h:683
static float Tan16(float a)
Definition: Math.h:463
static float ACos16(float a)
Definition: Math.h:554
GLdouble GLdouble x2
Definition: qgl.h:415
static const float SQRT_THREE
Definition: Math.h:211
static const float ONEFOURTH_PI
Definition: Math.h:208
static const float PI
Definition: Math.h:205
GLenum GLint GLint y
Definition: glext.h:2849
case const int
Definition: Callbacks.cpp:52
static const float FLT_EPSILON
Definition: Math.h:219
static double ASin64(float a)
Definition: Math.h:534
static int FloatHash(const float *array, const int numFloats)
Definition: Math.h:922
static float ClampFloat(float min, float max, float value)
Definition: Math.h:893
static float AngleDelta(float angle1, float angle2)
Definition: Math.h:918
#define IEEE_FLT_SIGN_BIT
Definition: Math.h:83
case const float
Definition: Callbacks.cpp:62
static bool initialized
Definition: Math.h:238
static float Sqrt(float x)
Definition: Math.h:302
ID_INLINE T Square(T x)
Definition: Math.h:104
static const float M_DEG2RAD
Definition: Math.h:214
static float InvSqrt16(float x)
Definition: Math.h:254
static int FloorPowerOfTwo(int x)
Definition: Math.h:739
GLdouble s
Definition: glext.h:2935
static const float HALF_PI
Definition: Math.h:207
static float Sqrt16(float x)
Definition: Math.h:298
ID_INLINE int MinIndex(T x, T y)
Definition: Math.h:96
static int ClampInt(int min, int max, int value)
Definition: Math.h:883
static float Rint(float f)
Definition: Math.h:793
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
static void SinCos(float a, float &s, float &c)
Definition: Math.h:390
static double ATan64(float a)
Definition: Math.h:603
static const float M_SEC2MS
Definition: Math.h:216
static float BitsToFloat(int i, int exponentBits, int mantissaBits)
Definition: Math.cpp:118
static int Ftoi(float f)
Definition: Math.h:797
static float ASin(float a)
Definition: Math.h:509
static float Cos16(float a)
Definition: Math.h:350
static float Sin16(float a)
Definition: Math.h:314
static double Pow64(float x, float y)
Definition: Math.h:644
static const float M_RAD2DEG
Definition: Math.h:215
static float Pow16(float x, float y)
Definition: Math.h:640
static int BitCount(int x)
Definition: Math.h:758
static double Log64(float f)
Definition: Math.h:707
static int MaskForIntegerSign(int i)
Definition: Math.h:735
#define FLOATSIGNBITSET(f)
Definition: Math.h:68
dword i
Definition: Math.h:233
static float ASin16(float a)
Definition: Math.h:519
const GLubyte * c
Definition: glext.h:4677
static int FtoiFast(float f)
Definition: Math.h:801
static float ATan(float a)
Definition: Math.h:579
static float Sin(float a)
Definition: Math.h:310
static double ACos64(float a)
Definition: Math.h:569
static float Fabs(float f)
Definition: Math.h:779
static float Floor(float f)
Definition: Math.h:785
ID_INLINE T Max3(T x, T y, T z)
Definition: Math.h:98
static const float SQRT_1OVER2
Definition: Math.h:212
static float AngleNormalize360(float angle)
Definition: Math.h:903
static int CeilPowerOfTwo(int x)
Definition: Math.h:743
static int MaskForFloatSign(float f)
Definition: Math.h:731
static int Abs(int x)
Definition: Math.h:774
static double Cos64(float a)
Definition: Math.h:386
ID_INLINE T Sign(T f)
Definition: Math.h:103
ID_INLINE T Cube(T x)
Definition: Math.h:105
static float InvSqrt(float x)
Definition: Math.h:268
static float Tan(float a)
Definition: Math.h:459
static const float E
Definition: Math.h:209
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
static float Exp(float f)
Definition: Math.h:648
static void SinCos16(float a, float &s, float &c)
Definition: Math.h:406
ID_INLINE T Min3(T x, T y, T z)
Definition: Math.h:99
static int BitsForInteger(int i)
Definition: Math.h:727
GLdouble GLdouble GLdouble y2
Definition: qgl.h:415
static float Ceil(float f)
Definition: Math.h:789
static bool IsPowerOfTwo(int x)
Definition: Math.h:754
static float Pow(float x, float y)
Definition: Math.h:636
static const float TWO_PI
Definition: Math.h:206
ID_INLINE int Min3Index(T x, T y, T z)
Definition: Math.h:101
ID_INLINE int Max3Index(T x, T y, T z)
Definition: Math.h:100
static double InvSqrt64(float x)
Definition: Math.h:283
ID_INLINE int MaxIndex(T x, T y)
Definition: Math.h:95
#define IEEE_FLT_EXPONENT_BITS
Definition: Math.h:81
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
static signed char ClampChar(int i)
Definition: Math.h:863
tuple f
Definition: idal.py:89
static double Sin64(float a)
Definition: Math.h:342
static unsigned long Ftol(float f)
Definition: Math.h:829
#define IEEE_FLT_MANTISSA_BITS
Definition: Math.h:80
static int IPow(int x, int y)
Definition: Math.h:711
static float AngleNormalize180(float angle)
Definition: Math.h:910
static int ILog2(float f)
Definition: Math.h:715
static dword iSqrt[SQRT_TABLE_SIZE]
Definition: Math.h:237
static unsigned long FtolFast(float)
Definition: Math.h:833
static float ACos(float a)
Definition: Math.h:544
#define max(x, y)
Definition: os.h:70
GLfloat GLfloat p
Definition: glext.h:4674
float f
Definition: Math.h:234
GLdouble GLdouble z
Definition: glext.h:3067
Definition: eax4.h:1413
static const float SQRT_1OVER3
Definition: Math.h:213
static const float M_MS2SEC
Definition: Math.h:217
static void Init(void)
Definition: Math.cpp:57
static float RSqrt(float x)
Definition: Math.h:241
static int FloatToBits(float f, int exponentBits, int mantissaBits)
Definition: Math.cpp:76
static int BitsForFloat(float f)
Definition: Math.h:723
static signed short ClampShort(int i)
Definition: Math.h:873
GLdouble GLdouble t
Definition: glext.h:2943
static float Cos(float a)
Definition: Math.h:346