Math.h (37337B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition 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 BFG Edition 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 #include <ppc_intrinsics.h> 35 // for FLT_MIN 36 #include <float.h> 37 #endif 38 39 /* 40 =============================================================================== 41 42 Math 43 44 =============================================================================== 45 */ 46 47 #ifdef INFINITY 48 #undef INFINITY 49 #endif 50 51 #ifdef FLT_EPSILON 52 #undef FLT_EPSILON 53 #endif 54 55 #define DEG2RAD(a) ( (a) * idMath::M_DEG2RAD ) 56 #define RAD2DEG(a) ( (a) * idMath::M_RAD2DEG ) 57 58 #define SEC2MS(t) ( idMath::Ftoi( (t) * idMath::M_SEC2MS ) ) 59 #define MS2SEC(t) ( (t) * idMath::M_MS2SEC ) 60 61 #define ANGLE2SHORT(x) ( idMath::Ftoi( (x) * 65536.0f / 360.0f ) & 65535 ) 62 #define SHORT2ANGLE(x) ( (x) * ( 360.0f / 65536.0f ) ) 63 64 #define ANGLE2BYTE(x) ( idMath::Ftoi( (x) * 256.0f / 360.0f ) & 255 ) 65 #define BYTE2ANGLE(x) ( (x) * ( 360.0f / 256.0f ) ) 66 67 #define C_FLOAT_TO_INT( x ) (int)(x) 68 69 /* 70 ================================================================================================ 71 72 two-complements integer bit layouts 73 74 ================================================================================================ 75 */ 76 77 #define INT8_SIGN_BIT 7 78 #define INT16_SIGN_BIT 15 79 #define INT32_SIGN_BIT 31 80 #define INT64_SIGN_BIT 63 81 82 #define INT8_SIGN_MASK ( 1 << INT8_SIGN_BIT ) 83 #define INT16_SIGN_MASK ( 1 << INT16_SIGN_BIT ) 84 #define INT32_SIGN_MASK ( 1UL << INT32_SIGN_BIT ) 85 #define INT64_SIGN_MASK ( 1ULL << INT64_SIGN_BIT ) 86 87 /* 88 ================================================================================================ 89 90 integer sign bit tests 91 92 ================================================================================================ 93 */ 94 95 // If this was ever compiled on a system that had 64 bit unsigned ints, 96 // it would fail. 97 compile_time_assert( sizeof( unsigned int ) == 4 ); 98 99 #define OLD_INT32_SIGNBITSET(i) (static_cast<const unsigned int>(i) >> INT32_SIGN_BIT) 100 #define OLD_INT32_SIGNBITNOTSET(i) ((~static_cast<const unsigned int>(i)) >> INT32_SIGN_BIT) 101 102 // Unfortunately, /analyze can't figure out that these always return 103 // either 0 or 1, so this extra wrapper is needed to avoid the static 104 // alaysis warning. 105 106 ID_INLINE_EXTERN int INT32_SIGNBITSET( int i ) { 107 int r = OLD_INT32_SIGNBITSET( i ); 108 assert( r == 0 || r == 1 ); 109 return r; 110 } 111 112 ID_INLINE_EXTERN int INT32_SIGNBITNOTSET( int i ) { 113 int r = OLD_INT32_SIGNBITNOTSET( i ); 114 assert( r == 0 || r == 1 ); 115 return r; 116 } 117 118 /* 119 ================================================================================================ 120 121 floating point bit layouts according to the IEEE 754-1985 and 754-2008 standard 122 123 ================================================================================================ 124 */ 125 126 #define IEEE_FLT16_MANTISSA_BITS 10 127 #define IEEE_FLT16_EXPONENT_BITS 5 128 #define IEEE_FLT16_EXPONENT_BIAS 15 129 #define IEEE_FLT16_SIGN_BIT 15 130 #define IEEE_FLT16_SIGN_MASK ( 1U << IEEE_FLT16_SIGN_BIT ) 131 132 #define IEEE_FLT_MANTISSA_BITS 23 133 #define IEEE_FLT_EXPONENT_BITS 8 134 #define IEEE_FLT_EXPONENT_BIAS 127 135 #define IEEE_FLT_SIGN_BIT 31 136 #define IEEE_FLT_SIGN_MASK ( 1UL << IEEE_FLT_SIGN_BIT ) 137 138 #define IEEE_DBL_MANTISSA_BITS 52 139 #define IEEE_DBL_EXPONENT_BITS 11 140 #define IEEE_DBL_EXPONENT_BIAS 1023 141 #define IEEE_DBL_SIGN_BIT 63 142 #define IEEE_DBL_SIGN_MASK ( 1ULL << IEEE_DBL_SIGN_BIT ) 143 144 #define IEEE_DBLE_MANTISSA_BITS 63 145 #define IEEE_DBLE_EXPONENT_BITS 15 146 #define IEEE_DBLE_EXPONENT_BIAS 0 147 #define IEEE_DBLE_SIGN_BIT 79 148 149 /* 150 ================================================================================================ 151 152 floating point sign bit tests 153 154 ================================================================================================ 155 */ 156 157 #define IEEE_FLT_SIGNBITSET( a ) (reinterpret_cast<const unsigned int &>(a) >> IEEE_FLT_SIGN_BIT) 158 #define IEEE_FLT_SIGNBITNOTSET( a ) ((~reinterpret_cast<const unsigned int &>(a)) >> IEEE_FLT_SIGN_BIT) 159 #define IEEE_FLT_ISNOTZERO( a ) (reinterpret_cast<const unsigned int &>(a) & ~(1u<<IEEE_FLT_SIGN_BIT)) 160 161 /* 162 ================================================================================================ 163 164 floating point special value tests 165 166 ================================================================================================ 167 */ 168 169 /* 170 ======================== 171 IEEE_FLT_IS_NAN 172 ======================== 173 */ 174 ID_INLINE_EXTERN bool IEEE_FLT_IS_NAN( float x ) { 175 return x != x; 176 } 177 178 /* 179 ======================== 180 IEEE_FLT_IS_INF 181 ======================== 182 */ 183 ID_INLINE_EXTERN bool IEEE_FLT_IS_INF( float x ) { 184 return x == x && x * 0 != x * 0; 185 } 186 187 /* 188 ======================== 189 IEEE_FLT_IS_INF_NAN 190 ======================== 191 */ 192 ID_INLINE_EXTERN bool IEEE_FLT_IS_INF_NAN( float x ) { 193 return x * 0 != x * 0; 194 } 195 196 /* 197 ======================== 198 IEEE_FLT_IS_IND 199 ======================== 200 */ 201 ID_INLINE_EXTERN bool IEEE_FLT_IS_IND( float x ) { 202 return (reinterpret_cast<const unsigned int &>(x) == 0xffc00000); 203 } 204 205 /* 206 ======================== 207 IEEE_FLT_IS_DENORMAL 208 ======================== 209 */ 210 ID_INLINE_EXTERN bool IEEE_FLT_IS_DENORMAL( float x ) { 211 return ((reinterpret_cast<const unsigned int &>(x) & 0x7f800000) == 0x00000000 && 212 (reinterpret_cast<const unsigned int &>(x) & 0x007fffff) != 0x00000000 ); 213 } 214 215 216 /* 217 ======================== 218 IsNAN 219 ======================== 220 */template<class type> 221 ID_INLINE_EXTERN bool IsNAN( const type &v ) { 222 for ( int i = 0; i < v.GetDimension(); i++ ) { 223 const float f = v.ToFloatPtr()[i]; 224 if ( IEEE_FLT_IS_NAN( f ) || IEEE_FLT_IS_INF( f ) || IEEE_FLT_IS_IND( f ) ) { 225 return true; 226 } 227 } 228 return false; 229 } 230 231 /* 232 ======================== 233 IsValid 234 ======================== 235 */ 236 template<class type> 237 ID_INLINE_EXTERN bool IsValid( const type &v ) { 238 for ( int i = 0; i < v.GetDimension(); i++ ) { 239 const float f = v.ToFloatPtr()[i]; 240 if ( IEEE_FLT_IS_NAN( f ) || IEEE_FLT_IS_INF( f ) || IEEE_FLT_IS_IND( f ) || IEEE_FLT_IS_DENORMAL( f ) ) { 241 return false; 242 } 243 } 244 return true; 245 } 246 247 /* 248 ======================== 249 IsValid 250 ======================== 251 */ 252 template<> 253 ID_INLINE_EXTERN bool IsValid( const float & f ) { // these parameter must be a reference for the function to be considered a specialization 254 return !( IEEE_FLT_IS_NAN( f ) || IEEE_FLT_IS_INF( f ) || IEEE_FLT_IS_IND( f ) || IEEE_FLT_IS_DENORMAL( f ) ); 255 } 256 257 /* 258 ======================== 259 IsNAN 260 ======================== 261 */ 262 template<> 263 ID_INLINE_EXTERN bool IsNAN( const float & f ) { // these parameter must be a reference for the function to be considered a specialization 264 if ( IEEE_FLT_IS_NAN( f ) || IEEE_FLT_IS_INF( f ) || IEEE_FLT_IS_IND( f ) ) { 265 return true; 266 } 267 return false; 268 } 269 270 /* 271 ======================== 272 IsInRange 273 274 Returns true if any scalar is greater than the range or less than the negative range. 275 ======================== 276 */ 277 template<class type> 278 ID_INLINE_EXTERN bool IsInRange( const type &v, const float range ) { 279 for ( int i = 0; i < v.GetDimension(); i++ ) { 280 const float f = v.ToFloatPtr()[i]; 281 if ( f > range || f < -range ) { 282 return false; 283 } 284 } 285 return true; 286 } 287 288 289 /* 290 ================================================================================================ 291 292 MinIndex/MaxIndex 293 294 ================================================================================================ 295 */ 296 template<class T> ID_INLINE int MaxIndex( T x, T y ) { return ( x > y ) ? 0 : 1; } 297 template<class T> ID_INLINE int MinIndex( T x, T y ) { return ( x < y ) ? 0 : 1; } 298 299 template<class T> ID_INLINE T Max3( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? x : z ) : ( ( y > z ) ? y : z ); } 300 template<class T> ID_INLINE T Min3( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? x : z ) : ( ( y < z ) ? y : z ); } 301 template<class T> ID_INLINE int Max3Index( T x, T y, T z ) { return ( x > y ) ? ( ( x > z ) ? 0 : 2 ) : ( ( y > z ) ? 1 : 2 ); } 302 template<class T> ID_INLINE int Min3Index( T x, T y, T z ) { return ( x < y ) ? ( ( x < z ) ? 0 : 2 ) : ( ( y < z ) ? 1 : 2 ); } 303 304 /* 305 ================================================================================================ 306 307 Sign/Square/Cube 308 309 ================================================================================================ 310 */ 311 template<class T> ID_INLINE T Sign( T f ) { return ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ); } 312 template<class T> ID_INLINE T Square( T x ) { return x * x; } 313 template<class T> ID_INLINE T Cube( T x ) { return x * x * x; } 314 315 class idMath { 316 public: 317 318 static void Init(); 319 320 static float InvSqrt( float x ); // inverse square root with 32 bits precision, returns huge number when x == 0.0 321 static float InvSqrt16( float x ); // inverse square root with 16 bits precision, returns huge number when x == 0.0 322 323 static float Sqrt( float x ); // square root with 32 bits precision 324 static float Sqrt16( float x ); // square root with 16 bits precision 325 326 static float Sin( float a ); // sine with 32 bits precision 327 static float Sin16( float a ); // sine with 16 bits precision, maximum absolute error is 2.3082e-09 328 329 static float Cos( float a ); // cosine with 32 bits precision 330 static float Cos16( float a ); // cosine with 16 bits precision, maximum absolute error is 2.3082e-09 331 332 static void SinCos( float a, float &s, float &c ); // sine and cosine with 32 bits precision 333 static void SinCos16( float a, float &s, float &c ); // sine and cosine with 16 bits precision 334 335 static float Tan( float a ); // tangent with 32 bits precision 336 static float Tan16( float a ); // tangent with 16 bits precision, maximum absolute error is 1.8897e-08 337 338 static float ASin( float a ); // arc sine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN 339 static float ASin16( float a ); // arc sine with 16 bits precision, maximum absolute error is 6.7626e-05 340 341 static float ACos( float a ); // arc cosine with 32 bits precision, input is clamped to [-1, 1] to avoid a silent NaN 342 static float ACos16( float a ); // arc cosine with 16 bits precision, maximum absolute error is 6.7626e-05 343 344 static float ATan( float a ); // arc tangent with 32 bits precision 345 static float ATan16( float a ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08 346 347 static float ATan( float y, float x ); // arc tangent with 32 bits precision 348 static float ATan16( float y, float x ); // arc tangent with 16 bits precision, maximum absolute error is 1.3593e-08 349 350 static float Pow( float x, float y ); // x raised to the power y with 32 bits precision 351 static float Pow16( float x, float y ); // x raised to the power y with 16 bits precision 352 353 static float Exp( float f ); // e raised to the power f with 32 bits precision 354 static float Exp16( float f ); // e raised to the power f with 16 bits precision 355 356 static float Log( float f ); // natural logarithm with 32 bits precision 357 static float Log16( float f ); // natural logarithm with 16 bits precision 358 359 static int IPow( int x, int y ); // integral x raised to the power y 360 static int ILog2( float f ); // integral base-2 logarithm of the floating point value 361 static int ILog2( int i ); // integral base-2 logarithm of the integer value 362 363 static int BitsForFloat( float f ); // minumum number of bits required to represent ceil( f ) 364 static int BitsForInteger( int i ); // minumum number of bits required to represent i 365 static int MaskForFloatSign( float f );// returns 0x00000000 if x >= 0.0f and returns 0xFFFFFFFF if x <= -0.0f 366 static int MaskForIntegerSign( int i );// returns 0x00000000 if x >= 0 and returns 0xFFFFFFFF if x < 0 367 static int FloorPowerOfTwo( int x ); // round x down to the nearest power of 2 368 static int CeilPowerOfTwo( int x ); // round x up to the nearest power of 2 369 static bool IsPowerOfTwo( int x ); // returns true if x is a power of 2 370 static int BitCount( int x ); // returns the number of 1 bits in x 371 static int BitReverse( int x ); // returns the bit reverse of x 372 373 static int Abs( int x ); // returns the absolute value of the integer value (for reference only) 374 static float Fabs( float f ); // returns the absolute value of the floating point value 375 static float Floor( float f ); // returns the largest integer that is less than or equal to the given value 376 static float Ceil( float f ); // returns the smallest integer that is greater than or equal to the given value 377 static float Rint( float f ); // returns the nearest integer 378 379 static float Frac( float f ); // f - Floor( f ) 380 381 static int Ftoi( float f ); // float to int conversion 382 static char Ftoi8( float f ); // float to char conversion 383 static short Ftoi16( float f ); // float to short conversion 384 static unsigned short Ftoui16( float f ); // float to unsigned short conversion 385 static byte Ftob( float f ); // float to byte conversion, the result is clamped to the range [0-255] 386 387 static signed char ClampChar( int i ); 388 static signed short ClampShort( int i ); 389 static int ClampInt( int min, int max, int value ); 390 static float ClampFloat( float min, float max, float value ); 391 392 static float AngleNormalize360( float angle ); 393 static float AngleNormalize180( float angle ); 394 static float AngleDelta( float angle1, float angle2 ); 395 396 static int FloatToBits( float f, int exponentBits, int mantissaBits ); 397 static float BitsToFloat( int i, int exponentBits, int mantissaBits ); 398 399 static int FloatHash( const float *array, const int numFloats ); 400 401 static float LerpToWithScale( const float cur, const float dest, const float scale ); 402 403 static const float PI; // pi 404 static const float TWO_PI; // pi * 2 405 static const float HALF_PI; // pi / 2 406 static const float ONEFOURTH_PI; // pi / 4 407 static const float ONEOVER_PI; // 1 / pi 408 static const float ONEOVER_TWOPI; // 1 / pi * 2 409 static const float E; // e 410 static const float SQRT_TWO; // sqrt( 2 ) 411 static const float SQRT_THREE; // sqrt( 3 ) 412 static const float SQRT_1OVER2; // sqrt( 1 / 2 ) 413 static const float SQRT_1OVER3; // sqrt( 1 / 3 ) 414 static const float M_DEG2RAD; // degrees to radians multiplier 415 static const float M_RAD2DEG; // radians to degrees multiplier 416 static const float M_SEC2MS; // seconds to milliseconds multiplier 417 static const float M_MS2SEC; // milliseconds to seconds multiplier 418 static const float INFINITY; // huge number which should be larger than any valid number used 419 static const float FLT_EPSILON; // smallest positive number such that 1.0+FLT_EPSILON != 1.0 420 static const float FLT_SMALLEST_NON_DENORMAL; // smallest non-denormal 32-bit floating point value 421 422 #if defined( ID_WIN_X86_SSE_INTRIN ) 423 static const __m128 SIMD_SP_zero; 424 static const __m128 SIMD_SP_255; 425 static const __m128 SIMD_SP_min_char; 426 static const __m128 SIMD_SP_max_char; 427 static const __m128 SIMD_SP_min_short; 428 static const __m128 SIMD_SP_max_short; 429 static const __m128 SIMD_SP_smallestNonDenorm; 430 static const __m128 SIMD_SP_tiny; 431 static const __m128 SIMD_SP_rsqrt_c0; 432 static const __m128 SIMD_SP_rsqrt_c1; 433 #endif 434 435 private: 436 enum { 437 LOOKUP_BITS = 8, 438 EXP_POS = 23, 439 EXP_BIAS = 127, 440 LOOKUP_POS = (EXP_POS-LOOKUP_BITS), 441 SEED_POS = (EXP_POS-8), 442 SQRT_TABLE_SIZE = (2<<LOOKUP_BITS), 443 LOOKUP_MASK = (SQRT_TABLE_SIZE-1) 444 }; 445 446 union _flint { 447 dword i; 448 float f; 449 }; 450 451 static dword iSqrt[SQRT_TABLE_SIZE]; 452 static bool initialized; 453 }; 454 455 ID_INLINE byte CLAMP_BYTE( int x ) { 456 return ( (x) < 0 ? (0) : ( (x) > 255 ? 255 : (byte)(x) ) ); 457 } 458 459 /* 460 ======================== 461 idMath::InvSqrt 462 ======================== 463 */ 464 ID_INLINE float idMath::InvSqrt( float x ) { 465 #ifdef ID_WIN_X86_SSE_INTRIN 466 467 return ( x > FLT_SMALLEST_NON_DENORMAL ) ? sqrtf( 1.0f / x ) : INFINITY; 468 469 #else 470 471 return ( x > FLT_SMALLEST_NON_DENORMAL ) ? sqrtf( 1.0f / x ) : INFINITY; 472 473 #endif 474 } 475 476 /* 477 ======================== 478 idMath::InvSqrt16 479 ======================== 480 */ 481 ID_INLINE float idMath::InvSqrt16( float x ) { 482 #ifdef ID_WIN_X86_SSE_INTRIN 483 484 return ( x > FLT_SMALLEST_NON_DENORMAL ) ? sqrtf( 1.0f / x ) : INFINITY; 485 486 #else 487 488 return ( x > FLT_SMALLEST_NON_DENORMAL ) ? sqrtf( 1.0f / x ) : INFINITY; 489 490 #endif 491 } 492 493 /* 494 ======================== 495 idMath::Sqrt 496 ======================== 497 */ 498 ID_INLINE float idMath::Sqrt( float x ) { 499 #ifdef ID_WIN_X86_SSE_INTRIN 500 return ( x >= 0.0f ) ? x * InvSqrt( x ) : 0.0f; 501 #else 502 return ( x >= 0.0f ) ? sqrtf( x ) : 0.0f; 503 #endif 504 } 505 506 /* 507 ======================== 508 idMath::Sqrt16 509 ======================== 510 */ 511 ID_INLINE float idMath::Sqrt16( float x ) { 512 #ifdef ID_WIN_X86_SSE_INTRIN 513 return ( x >= 0.0f ) ? x * InvSqrt16( x ) : 0.0f; 514 #else 515 return ( x >= 0.0f ) ? sqrtf( x ) : 0.0f; 516 #endif 517 } 518 519 /* 520 ======================== 521 idMath::Frac 522 ======================== 523 */ 524 ID_INLINE float idMath::Frac( float f ) { 525 return f - floorf( f ); 526 } 527 528 /* 529 ======================== 530 idMath::Sin 531 ======================== 532 */ 533 ID_INLINE float idMath::Sin( float a ) { 534 return sinf( a ); 535 } 536 537 /* 538 ======================== 539 idMath::Sin16 540 ======================== 541 */ 542 ID_INLINE float idMath::Sin16( float a ) { 543 float s; 544 545 if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { 546 a -= floorf( a * ONEOVER_TWOPI ) * TWO_PI; 547 } 548 #if 1 549 if ( a < PI ) { 550 if ( a > HALF_PI ) { 551 a = PI - a; 552 } 553 } else { 554 if ( a > PI + HALF_PI ) { 555 a = a - TWO_PI; 556 } else { 557 a = PI - a; 558 } 559 } 560 #else 561 a = PI - a; 562 if ( fabsf( a ) >= HALF_PI ) { 563 a = ( ( a < 0.0f ) ? -PI : PI ) - a; 564 } 565 #endif 566 s = a * a; 567 return a * ( ( ( ( ( -2.39e-08f * s + 2.7526e-06f ) * s - 1.98409e-04f ) * s + 8.3333315e-03f ) * s - 1.666666664e-01f ) * s + 1.0f ); 568 } 569 570 /* 571 ======================== 572 idMath::Cos 573 ======================== 574 */ 575 ID_INLINE float idMath::Cos( float a ) { 576 return cosf( a ); 577 } 578 579 /* 580 ======================== 581 idMath::Cos16 582 ======================== 583 */ 584 ID_INLINE float idMath::Cos16( float a ) { 585 float s, d; 586 587 if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { 588 a -= floorf( a * ONEOVER_TWOPI ) * TWO_PI; 589 } 590 #if 1 591 if ( a < PI ) { 592 if ( a > HALF_PI ) { 593 a = PI - a; 594 d = -1.0f; 595 } else { 596 d = 1.0f; 597 } 598 } else { 599 if ( a > PI + HALF_PI ) { 600 a = a - TWO_PI; 601 d = 1.0f; 602 } else { 603 a = PI - a; 604 d = -1.0f; 605 } 606 } 607 #else 608 a = PI - a; 609 if ( fabsf( a ) >= HALF_PI ) { 610 a = ( ( a < 0.0f ) ? -PI : PI ) - a; 611 d = 1.0f; 612 } else { 613 d = -1.0f; 614 } 615 #endif 616 s = a * a; 617 return d * ( ( ( ( ( -2.605e-07f * s + 2.47609e-05f ) * s - 1.3888397e-03f ) * s + 4.16666418e-02f ) * s - 4.999999963e-01f ) * s + 1.0f ); 618 } 619 620 /* 621 ======================== 622 idMath::SinCos 623 ======================== 624 */ 625 ID_INLINE void idMath::SinCos( float a, float &s, float &c ) { 626 #if defined( ID_WIN_X86_ASM ) 627 _asm { 628 fld a 629 fsincos 630 mov ecx, c 631 mov edx, s 632 fstp dword ptr [ecx] 633 fstp dword ptr [edx] 634 } 635 #else 636 s = sinf( a ); 637 c = cosf( a ); 638 #endif 639 } 640 641 /* 642 ======================== 643 idMath::SinCos16 644 ======================== 645 */ 646 ID_INLINE void idMath::SinCos16( float a, float &s, float &c ) { 647 float t, d; 648 649 if ( ( a < 0.0f ) || ( a >= TWO_PI ) ) { 650 a -= floorf( a * ONEOVER_TWOPI ) * TWO_PI; 651 } 652 #if 1 653 if ( a < PI ) { 654 if ( a > HALF_PI ) { 655 a = PI - a; 656 d = -1.0f; 657 } else { 658 d = 1.0f; 659 } 660 } else { 661 if ( a > PI + HALF_PI ) { 662 a = a - TWO_PI; 663 d = 1.0f; 664 } else { 665 a = PI - a; 666 d = -1.0f; 667 } 668 } 669 #else 670 a = PI - a; 671 if ( fabsf( a ) >= HALF_PI ) { 672 a = ( ( a < 0.0f ) ? -PI : PI ) - a; 673 d = 1.0f; 674 } else { 675 d = -1.0f; 676 } 677 #endif 678 t = a * a; 679 s = a * ( ( ( ( ( -2.39e-08f * t + 2.7526e-06f ) * t - 1.98409e-04f ) * t + 8.3333315e-03f ) * t - 1.666666664e-01f ) * t + 1.0f ); 680 c = d * ( ( ( ( ( -2.605e-07f * t + 2.47609e-05f ) * t - 1.3888397e-03f ) * t + 4.16666418e-02f ) * t - 4.999999963e-01f ) * t + 1.0f ); 681 } 682 683 /* 684 ======================== 685 idMath::Tan 686 ======================== 687 */ 688 ID_INLINE float idMath::Tan( float a ) { 689 return tanf( a ); 690 } 691 692 /* 693 ======================== 694 idMath::Tan16 695 ======================== 696 */ 697 ID_INLINE float idMath::Tan16( float a ) { 698 float s; 699 bool reciprocal; 700 701 if ( ( a < 0.0f ) || ( a >= PI ) ) { 702 a -= floorf( a * ONEOVER_PI ) * PI; 703 } 704 #if 1 705 if ( a < HALF_PI ) { 706 if ( a > ONEFOURTH_PI ) { 707 a = HALF_PI - a; 708 reciprocal = true; 709 } else { 710 reciprocal = false; 711 } 712 } else { 713 if ( a > HALF_PI + ONEFOURTH_PI ) { 714 a = a - PI; 715 reciprocal = false; 716 } else { 717 a = HALF_PI - a; 718 reciprocal = true; 719 } 720 } 721 #else 722 a = HALF_PI - a; 723 if ( fabsf( a ) >= ONEFOURTH_PI ) { 724 a = ( ( a < 0.0f ) ? -HALF_PI : HALF_PI ) - a; 725 reciprocal = false; 726 } else { 727 reciprocal = true; 728 } 729 #endif 730 s = a * a; 731 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 ); 732 if ( reciprocal ) { 733 return 1.0f / s; 734 } else { 735 return s; 736 } 737 } 738 739 /* 740 ======================== 741 idMath::ASin 742 ======================== 743 */ 744 ID_INLINE float idMath::ASin( float a ) { 745 if ( a <= -1.0f ) { 746 return -HALF_PI; 747 } 748 if ( a >= 1.0f ) { 749 return HALF_PI; 750 } 751 return asinf( a ); 752 } 753 754 /* 755 ======================== 756 idMath::ASin16 757 ======================== 758 */ 759 ID_INLINE float idMath::ASin16( float a ) { 760 if ( a < 0.0f ) { 761 if ( a <= -1.0f ) { 762 return -HALF_PI; 763 } 764 a = fabsf( a ); 765 return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * idMath::Sqrt( 1.0f - a ) - HALF_PI; 766 } else { 767 if ( a >= 1.0f ) { 768 return HALF_PI; 769 } 770 return HALF_PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * idMath::Sqrt( 1.0f - a ); 771 } 772 } 773 774 /* 775 ======================== 776 idMath::ACos 777 ======================== 778 */ 779 ID_INLINE float idMath::ACos( float a ) { 780 if ( a <= -1.0f ) { 781 return PI; 782 } 783 if ( a >= 1.0f ) { 784 return 0.0f; 785 } 786 return acosf( a ); 787 } 788 789 /* 790 ======================== 791 idMath::ACos16 792 ======================== 793 */ 794 ID_INLINE float idMath::ACos16( float a ) { 795 if ( a < 0.0f ) { 796 if ( a <= -1.0f ) { 797 return PI; 798 } 799 a = fabsf( a ); 800 return PI - ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * idMath::Sqrt( 1.0f - a ); 801 } else { 802 if ( a >= 1.0f ) { 803 return 0.0f; 804 } 805 return ( ( ( -0.0187293f * a + 0.0742610f ) * a - 0.2121144f ) * a + 1.5707288f ) * idMath::Sqrt( 1.0f - a ); 806 } 807 } 808 809 /* 810 ======================== 811 idMath::ATan 812 ======================== 813 */ 814 ID_INLINE float idMath::ATan( float a ) { 815 return atanf( a ); 816 } 817 818 /* 819 ======================== 820 idMath::ATan16 821 ======================== 822 */ 823 ID_INLINE float idMath::ATan16( float a ) { 824 float s; 825 if ( fabsf( a ) > 1.0f ) { 826 a = 1.0f / a; 827 s = a * a; 828 s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) 829 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; 830 if ( a < 0.0f ) { 831 return s - HALF_PI; 832 } else { 833 return s + HALF_PI; 834 } 835 } else { 836 s = a * a; 837 return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) 838 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; 839 } 840 } 841 842 /* 843 ======================== 844 idMath::ATan 845 ======================== 846 */ 847 ID_INLINE float idMath::ATan( float y, float x ) { 848 assert( fabs( y ) > idMath::FLT_SMALLEST_NON_DENORMAL || fabs( x ) > idMath::FLT_SMALLEST_NON_DENORMAL ); 849 return atan2f( y, x ); 850 } 851 852 /* 853 ======================== 854 idMath::ATan16 855 ======================== 856 */ 857 ID_INLINE float idMath::ATan16( float y, float x ) { 858 assert( fabs( y ) > idMath::FLT_SMALLEST_NON_DENORMAL || fabs( x ) > idMath::FLT_SMALLEST_NON_DENORMAL ); 859 860 float a, s; 861 if ( fabsf( y ) > fabsf( x ) ) { 862 a = x / y; 863 s = a * a; 864 s = - ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) 865 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; 866 if ( a < 0.0f ) { 867 return s - HALF_PI; 868 } else { 869 return s + HALF_PI; 870 } 871 } else { 872 a = y / x; 873 s = a * a; 874 return ( ( ( ( ( ( ( ( ( 0.0028662257f * s - 0.0161657367f ) * s + 0.0429096138f ) * s - 0.0752896400f ) 875 * s + 0.1065626393f ) * s - 0.1420889944f ) * s + 0.1999355085f ) * s - 0.3333314528f ) * s ) + 1.0f ) * a; 876 } 877 } 878 879 /* 880 ======================== 881 idMath::Pow 882 ======================== 883 */ 884 ID_INLINE float idMath::Pow( float x, float y ) { 885 return powf( x, y ); 886 } 887 888 /* 889 ======================== 890 idMath::Pow16 891 ======================== 892 */ 893 ID_INLINE float idMath::Pow16( float x, float y ) { 894 return Exp16( y * Log16( x ) ); 895 } 896 897 /* 898 ======================== 899 idMath::Exp 900 ======================== 901 */ 902 ID_INLINE float idMath::Exp( float f ) { 903 return expf( f ); 904 } 905 906 /* 907 ======================== 908 idMath::Exp16 909 ======================== 910 */ 911 ID_INLINE float idMath::Exp16( float f ) { 912 float x = f * 1.44269504088896340f; // multiply with ( 1 / log( 2 ) ) 913 #if 1 914 int i = *reinterpret_cast<int *>(&x); 915 int s = ( i >> IEEE_FLT_SIGN_BIT ); 916 int e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; 917 int m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); 918 i = ( ( m >> ( IEEE_FLT_MANTISSA_BITS - e ) ) & ~( e >> INT32_SIGN_BIT ) ) ^ s; 919 #else 920 int i = (int) x; 921 if ( x < 0.0f ) { 922 i--; 923 } 924 #endif 925 int exponent = ( i + IEEE_FLT_EXPONENT_BIAS ) << IEEE_FLT_MANTISSA_BITS; 926 float y = *reinterpret_cast<float *>(&exponent); 927 x -= (float) i; 928 if ( x >= 0.5f ) { 929 x -= 0.5f; 930 y *= 1.4142135623730950488f; // multiply with sqrt( 2 ) 931 } 932 float x2 = x * x; 933 float p = x * ( 7.2152891511493f + x2 * 0.0576900723731f ); 934 float q = 20.8189237930062f + x2; 935 x = y * ( q + p ) / ( q - p ); 936 return x; 937 } 938 939 /* 940 ======================== 941 idMath::Log 942 ======================== 943 */ 944 ID_INLINE float idMath::Log( float f ) { 945 return logf( f ); 946 } 947 948 /* 949 ======================== 950 idMath::Log16 951 ======================== 952 */ 953 ID_INLINE float idMath::Log16( float f ) { 954 int i = *reinterpret_cast<int *>(&f); 955 int exponent = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; 956 i -= ( exponent + 1 ) << IEEE_FLT_MANTISSA_BITS; // get value in the range [.5, 1> 957 float y = *reinterpret_cast<float *>(&i); 958 y *= 1.4142135623730950488f; // multiply with sqrt( 2 ) 959 y = ( y - 1.0f ) / ( y + 1.0f ); 960 float y2 = y * y; 961 y = y * ( 2.000000000046727f + y2 * ( 0.666666635059382f + y2 * ( 0.4000059794795f + y2 * ( 0.28525381498f + y2 * 0.2376245609f ) ) ) ); 962 y += 0.693147180559945f * ( (float)exponent + 0.5f ); 963 return y; 964 } 965 966 /* 967 ======================== 968 idMath::IPow 969 ======================== 970 */ 971 ID_INLINE int idMath::IPow( int x, int y ) { 972 int r; for( r = x; y > 1; y-- ) { r *= x; } return r; 973 } 974 975 /* 976 ======================== 977 idMath::ILog2 978 ======================== 979 */ 980 ID_INLINE int idMath::ILog2( float f ) { 981 return ( ( (*reinterpret_cast<int *>(&f)) >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; 982 } 983 984 /* 985 ======================== 986 idMath::ILog2 987 ======================== 988 */ 989 ID_INLINE int idMath::ILog2( int i ) { 990 return ILog2( (float)i ); 991 } 992 993 /* 994 ======================== 995 idMath::BitsForFloat 996 ======================== 997 */ 998 ID_INLINE int idMath::BitsForFloat( float f ) { 999 return ILog2( f ) + 1; 1000 } 1001 1002 /* 1003 ======================== 1004 idMath::BitsForInteger 1005 ======================== 1006 */ 1007 ID_INLINE int idMath::BitsForInteger( int i ) { 1008 return ILog2( (float)i ) + 1; 1009 } 1010 1011 /* 1012 ======================== 1013 idMath::MaskForFloatSign 1014 ======================== 1015 */ 1016 ID_INLINE int idMath::MaskForFloatSign( float f ) { 1017 return ( (*reinterpret_cast<int *>(&f)) >> IEEE_FLT_SIGN_BIT ); 1018 } 1019 1020 /* 1021 ======================== 1022 idMath::MaskForIntegerSign 1023 ======================== 1024 */ 1025 ID_INLINE int idMath::MaskForIntegerSign( int i ) { 1026 return ( i >> INT32_SIGN_BIT ); 1027 } 1028 1029 /* 1030 ======================== 1031 idMath::FloorPowerOfTwo 1032 ======================== 1033 */ 1034 ID_INLINE int idMath::FloorPowerOfTwo( int x ) { 1035 x |= x >> 1; 1036 x |= x >> 2; 1037 x |= x >> 4; 1038 x |= x >> 8; 1039 x |= x >> 16; 1040 x++; 1041 return x >> 1; 1042 } 1043 1044 /* 1045 ======================== 1046 idMath::CeilPowerOfTwo 1047 ======================== 1048 */ 1049 ID_INLINE int idMath::CeilPowerOfTwo( int x ) { 1050 x--; 1051 x |= x >> 1; 1052 x |= x >> 2; 1053 x |= x >> 4; 1054 x |= x >> 8; 1055 x |= x >> 16; 1056 x++; 1057 return x; 1058 } 1059 1060 /* 1061 ======================== 1062 idMath::IsPowerOfTwo 1063 ======================== 1064 */ 1065 ID_INLINE bool idMath::IsPowerOfTwo( int x ) { 1066 return ( x & ( x - 1 ) ) == 0 && x > 0; 1067 } 1068 1069 /* 1070 ======================== 1071 idMath::BitCount 1072 ======================== 1073 */ 1074 ID_INLINE int idMath::BitCount( int x ) { 1075 x -= ( ( x >> 1 ) & 0x55555555 ); 1076 x = ( ( ( x >> 2 ) & 0x33333333 ) + ( x & 0x33333333 ) ); 1077 x = ( ( ( x >> 4 ) + x ) & 0x0f0f0f0f ); 1078 x += ( x >> 8 ); 1079 return ( ( x + ( x >> 16 ) ) & 0x0000003f ); 1080 } 1081 1082 /* 1083 ======================== 1084 idMath::BitReverse 1085 ======================== 1086 */ 1087 ID_INLINE int idMath::BitReverse( int x ) { 1088 x = ( ( ( x >> 1 ) & 0x55555555 ) | ( ( x & 0x55555555 ) << 1 ) ); 1089 x = ( ( ( x >> 2 ) & 0x33333333 ) | ( ( x & 0x33333333 ) << 2 ) ); 1090 x = ( ( ( x >> 4 ) & 0x0f0f0f0f ) | ( ( x & 0x0f0f0f0f ) << 4 ) ); 1091 x = ( ( ( x >> 8 ) & 0x00ff00ff ) | ( ( x & 0x00ff00ff ) << 8 ) ); 1092 return ( ( x >> 16 ) | ( x << 16 ) ); 1093 } 1094 1095 /* 1096 ======================== 1097 idMath::Abs 1098 ======================== 1099 */ 1100 ID_INLINE int idMath::Abs( int x ) { 1101 #if 1 1102 return abs( x ); 1103 #else 1104 int y = x >> INT32_SIGN_BIT; 1105 return ( ( x ^ y ) - y ); 1106 #endif 1107 } 1108 1109 /* 1110 ======================== 1111 idMath::Fabs 1112 ======================== 1113 */ 1114 ID_INLINE float idMath::Fabs( float f ) { 1115 #if 1 1116 return fabsf( f ); 1117 #else 1118 int tmp = *reinterpret_cast<int *>( &f ); 1119 tmp &= 0x7FFFFFFF; 1120 return *reinterpret_cast<float *>( &tmp ); 1121 #endif 1122 } 1123 1124 /* 1125 ======================== 1126 idMath::Floor 1127 ======================== 1128 */ 1129 ID_INLINE float idMath::Floor( float f ) { 1130 return floorf( f ); 1131 } 1132 1133 /* 1134 ======================== 1135 idMath::Ceil 1136 ======================== 1137 */ 1138 ID_INLINE float idMath::Ceil( float f ) { 1139 return ceilf( f ); 1140 } 1141 1142 /* 1143 ======================== 1144 idMath::Rint 1145 ======================== 1146 */ 1147 ID_INLINE float idMath::Rint( float f ) { 1148 return floorf( f + 0.5f ); 1149 } 1150 1151 1152 /* 1153 ======================== 1154 idMath::Ftoi 1155 ======================== 1156 */ 1157 ID_INLINE int idMath::Ftoi( float f ) { 1158 #ifdef ID_WIN_X86_SSE_INTRIN 1159 // If a converted result is larger than the maximum signed doubleword integer, 1160 // the floating-point invalid exception is raised, and if this exception is masked, 1161 // the indefinite integer value (80000000H) is returned. 1162 __m128 x = _mm_load_ss( &f ); 1163 return _mm_cvttss_si32( x ); 1164 #elif 0 // round chop (C/C++ standard) 1165 int i, s, e, m, shift; 1166 i = *reinterpret_cast<int *>(&f); 1167 s = i >> IEEE_FLT_SIGN_BIT; 1168 e = ( ( i >> IEEE_FLT_MANTISSA_BITS ) & ( ( 1 << IEEE_FLT_EXPONENT_BITS ) - 1 ) ) - IEEE_FLT_EXPONENT_BIAS; 1169 m = ( i & ( ( 1 << IEEE_FLT_MANTISSA_BITS ) - 1 ) ) | ( 1 << IEEE_FLT_MANTISSA_BITS ); 1170 shift = e - IEEE_FLT_MANTISSA_BITS; 1171 return ( ( ( ( m >> -shift ) | ( m << shift ) ) & ~( e >> INT32_SIGN_BIT ) ) ^ s ) - s; 1172 #else 1173 // If a converted result is larger than the maximum signed doubleword integer the result is undefined. 1174 return C_FLOAT_TO_INT( f ); 1175 #endif 1176 } 1177 1178 /* 1179 ======================== 1180 idMath::Ftoi8 1181 ======================== 1182 */ 1183 ID_INLINE char idMath::Ftoi8( float f ) { 1184 #ifdef ID_WIN_X86_SSE_INTRIN 1185 __m128 x = _mm_load_ss( &f ); 1186 x = _mm_max_ss( x, SIMD_SP_min_char ); 1187 x = _mm_min_ss( x, SIMD_SP_max_char ); 1188 return static_cast<char>( _mm_cvttss_si32( x ) ); 1189 #else 1190 // The converted result is clamped to the range [-128,127]. 1191 int i = C_FLOAT_TO_INT( f ); 1192 if ( i < -128 ) { 1193 return -128; 1194 } else if ( i > 127 ) { 1195 return 127; 1196 } 1197 return static_cast<char>( i ); 1198 #endif 1199 } 1200 1201 /* 1202 ======================== 1203 idMath::Ftoi16 1204 ======================== 1205 */ 1206 ID_INLINE short idMath::Ftoi16( float f ) { 1207 #ifdef ID_WIN_X86_SSE_INTRIN 1208 __m128 x = _mm_load_ss( &f ); 1209 x = _mm_max_ss( x, SIMD_SP_min_short ); 1210 x = _mm_min_ss( x, SIMD_SP_max_short ); 1211 return static_cast<short>( _mm_cvttss_si32( x ) ); 1212 #else 1213 // The converted result is clamped to the range [-32768,32767]. 1214 int i = C_FLOAT_TO_INT( f ); 1215 if ( i < -32768 ) { 1216 return -32768; 1217 } else if ( i > 32767 ) { 1218 return 32767; 1219 } 1220 return static_cast<short>( i ); 1221 #endif 1222 } 1223 1224 /* 1225 ======================== 1226 idMath::Ftoui16 1227 ======================== 1228 */ 1229 ID_INLINE unsigned short idMath::Ftoui16( float f ) { 1230 // TO DO - SSE ?? 1231 1232 // The converted result is clamped to the range [-32768,32767]. 1233 int i = C_FLOAT_TO_INT( f ); 1234 if ( i < 0 ) { 1235 return 0; 1236 } else if ( i > 65535 ) { 1237 return 65535; 1238 } 1239 return static_cast<unsigned short>( i ); 1240 } 1241 1242 /* 1243 ======================== 1244 idMath::Ftob 1245 ======================== 1246 */ 1247 ID_INLINE byte idMath::Ftob( float f ) { 1248 #ifdef ID_WIN_X86_SSE_INTRIN 1249 // If a converted result is negative the value (0) is returned and if the 1250 // converted result is larger than the maximum byte the value (255) is returned. 1251 __m128 x = _mm_load_ss( &f ); 1252 x = _mm_max_ss( x, SIMD_SP_zero ); 1253 x = _mm_min_ss( x, SIMD_SP_255 ); 1254 return static_cast<byte>( _mm_cvttss_si32( x ) ); 1255 #else 1256 // The converted result is clamped to the range [0,255]. 1257 int i = C_FLOAT_TO_INT( f ); 1258 if ( i < 0 ) { 1259 return 0; 1260 } else if ( i > 255 ) { 1261 return 255; 1262 } 1263 return static_cast<byte>( i ); 1264 #endif 1265 } 1266 1267 /* 1268 ======================== 1269 idMath::ClampChar 1270 ======================== 1271 */ 1272 ID_INLINE signed char idMath::ClampChar( int i ) { 1273 if ( i < -128 ) { 1274 return -128; 1275 } 1276 if ( i > 127 ) { 1277 return 127; 1278 } 1279 return static_cast<signed char>( i ); 1280 } 1281 1282 /* 1283 ======================== 1284 idMath::ClampShort 1285 ======================== 1286 */ 1287 ID_INLINE signed short idMath::ClampShort( int i ) { 1288 if ( i < -32768 ) { 1289 return -32768; 1290 } 1291 if ( i > 32767 ) { 1292 return 32767; 1293 } 1294 return static_cast<signed short>( i ); 1295 } 1296 1297 /* 1298 ======================== 1299 idMath::ClampInt 1300 ======================== 1301 */ 1302 ID_INLINE int idMath::ClampInt( int min, int max, int value ) { 1303 if ( value < min ) { 1304 return min; 1305 } 1306 if ( value > max ) { 1307 return max; 1308 } 1309 return value; 1310 } 1311 1312 /* 1313 ======================== 1314 idMath::ClampFloat 1315 ======================== 1316 */ 1317 ID_INLINE float idMath::ClampFloat( float min, float max, float value ) { 1318 return Max( min, Min( max, value ) ); 1319 } 1320 1321 /* 1322 ======================== 1323 idMath::AngleNormalize360 1324 ======================== 1325 */ 1326 ID_INLINE float idMath::AngleNormalize360( float angle ) { 1327 if ( ( angle >= 360.0f ) || ( angle < 0.0f ) ) { 1328 angle -= floorf( angle * ( 1.0f / 360.0f ) ) * 360.0f; 1329 } 1330 return angle; 1331 } 1332 1333 /* 1334 ======================== 1335 idMath::AngleNormalize180 1336 ======================== 1337 */ 1338 ID_INLINE float idMath::AngleNormalize180( float angle ) { 1339 angle = AngleNormalize360( angle ); 1340 if ( angle > 180.0f ) { 1341 angle -= 360.0f; 1342 } 1343 return angle; 1344 } 1345 1346 /* 1347 ======================== 1348 idMath::AngleDelta 1349 ======================== 1350 */ 1351 ID_INLINE float idMath::AngleDelta( float angle1, float angle2 ) { 1352 return AngleNormalize180( angle1 - angle2 ); 1353 } 1354 1355 /* 1356 ======================== 1357 idMath::FloatHash 1358 ======================== 1359 */ 1360 ID_INLINE int idMath::FloatHash( const float *array, const int numFloats ) { 1361 int i, hash = 0; 1362 const int *ptr; 1363 1364 ptr = reinterpret_cast<const int *>( array ); 1365 for ( i = 0; i < numFloats; i++ ) { 1366 hash ^= ptr[i]; 1367 } 1368 return hash; 1369 } 1370 1371 template< typename T > 1372 ID_INLINE_EXTERN T Lerp( const T from, const T to, float f ) { 1373 return from + ( ( to - from ) * f ); 1374 } 1375 1376 template<> 1377 ID_INLINE_EXTERN int Lerp( const int from, const int to, float f ) { 1378 return idMath::Ftoi( (float) from + ( ( (float) to - (float) from ) * f ) ); 1379 } 1380 1381 1382 /* 1383 ======================== 1384 LerpToWithScale 1385 1386 Lerps from "cur" to "dest", scaling the delta to change by "scale" 1387 If the delta between "cur" and "dest" is very small, dest is returned to prevent denormals. 1388 ======================== 1389 */ 1390 inline float idMath::LerpToWithScale( const float cur, const float dest, const float scale ) { 1391 float delta = dest - cur; 1392 if ( delta > -1.0e-6f && delta < 1.0e-6f ) { 1393 return dest; 1394 } 1395 return cur + ( dest - cur ) * scale; 1396 } 1397 1398 1399 #endif /* !__MATH_MATH_H__ */