idMath.h 29 KB

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