Math.h 27 KB

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