DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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__ */