Math.h 36 KB

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