mMathFn.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MMATHFN_H_
  23. #define _MMATHFN_H_
  24. #include <math.h>
  25. #include <stdlib.h>
  26. #include <limits>
  27. #ifndef _MCONSTANTS_H_
  28. #include "math/mConstants.h"
  29. #endif
  30. #ifndef _PLATFORMASSERT_H_
  31. #include "platform/platformAssert.h"
  32. #endif
  33. extern void MathConsoleInit();
  34. //--------------------------------------
  35. // Installable Library Prototypes
  36. extern S32 (*m_mulDivS32)(S32 a, S32 b, S32 c);
  37. extern U32 (*m_mulDivU32)(S32 a, S32 b, U32 c);
  38. extern F32 (*m_catmullrom)(F32 t, F32 p0, F32 p1, F32 p2, F32 p3);
  39. extern void (*m_sincos)( F32 angle, F32 *s, F32 *c );
  40. extern void (*m_sincosD)( F64 angle, F64 *s, F64 *c );
  41. extern void (*m_point2F_normalize)(F32 *p);
  42. extern void (*m_point2F_normalize_f)(F32 *p, F32 len);
  43. extern void (*m_point2D_normalize)(F64 *p);
  44. extern void (*m_point2D_normalize_f)(F64 *p, F64 len);
  45. extern void (*m_point3F_normalize)(F32 *p);
  46. extern void (*m_point3F_normalize_f)(F32 *p, F32 len);
  47. extern void (*m_point3F_interpolate)(const F32 *from, const F32 *to, F32 factor, F32 *result);
  48. extern void (*m_point3D_normalize)(F64 *p);
  49. extern void (*m_point3D_normalize_f)(F64 *p, F64 len);
  50. extern void (*m_point3D_interpolate)(const F64 *from, const F64 *to, F64 factor, F64 *result);
  51. extern void (*m_point3F_bulk_dot)(const F32* refVector,
  52. const F32* dotPoints,
  53. const U32 numPoints,
  54. const U32 pointStride,
  55. F32* output);
  56. extern void (*m_point3F_bulk_dot_indexed)(const F32* refVector,
  57. const F32* dotPoints,
  58. const U32 numPoints,
  59. const U32 pointStride,
  60. const U32* pointIndices,
  61. F32* output);
  62. extern void (*m_quatF_set_matF)( F32 x, F32 y, F32 z, F32 w, F32* m );
  63. extern void (*m_matF_set_euler)(const F32 *e, F32 *result);
  64. extern void (*m_matF_set_euler_point)(const F32 *e, const F32 *p, F32 *result);
  65. extern void (*m_matF_identity)(F32 *m);
  66. extern void (*m_matF_inverse)(F32 *m);
  67. extern void (*m_matF_invert_to)(const F32 *m, F32 *d);
  68. extern void (*m_matF_affineInverse)(F32 *m);
  69. extern void (*m_matF_transpose)(F32 *m);
  70. extern void (*m_matF_scale)(F32 *m,const F32* p);
  71. extern void (*m_matF_normalize)(F32 *m);
  72. extern F32 (*m_matF_determinant)(const F32 *m);
  73. extern void (*m_matF_x_matF)(const F32 *a, const F32 *b, F32 *mresult);
  74. extern void (*m_matF_x_matF_aligned)(const F32 *a, const F32 *b, F32 *mresult);
  75. // extern void (*m_matF_x_point3F)(const F32 *m, const F32 *p, F32 *presult);
  76. // extern void (*m_matF_x_vectorF)(const F32 *m, const F32 *v, F32 *vresult);
  77. extern void (*m_matF_x_point4F)(const F32 *m, const F32 *p, F32 *presult);
  78. extern void (*m_matF_x_scale_x_planeF)(const F32 *m, const F32* s, const F32 *p, F32 *presult);
  79. extern void (*m_matF_x_box3F)(const F32 *m, F32 *min, F32 *max);
  80. // Note that x must point to at least 4 values for quartics, and 3 for cubics
  81. extern U32 (*mSolveQuadratic)(F32 a, F32 b, F32 c, F32* x);
  82. extern U32 (*mSolveCubic)(F32 a, F32 b, F32 c, F32 d, F32* x);
  83. extern U32 (*mSolveQuartic)(F32 a, F32 b, F32 c, F32 d, F32 e, F32* x);
  84. extern S32 mRandI(S32 i1, S32 i2); // random # from i1 to i2 inclusive
  85. extern F32 mRandF(F32 f1, F32 f2); // random # from f1 to f2 inclusive
  86. extern F32 mRandF(); // random # from 0.0 to 1.0 inclusive
  87. inline void m_matF_x_point3F(const F32 *m, const F32 *p, F32 *presult)
  88. {
  89. AssertFatal(p != presult, "Error, aliasing matrix mul pointers not allowed here!");
  90. #ifdef TORQUE_COMPILER_GCC
  91. const F32 p0 = p[0], p1 = p[1], p2 = p[2];
  92. const F32 m0 = m[0], m1 = m[1], m2 = m[2];
  93. const F32 m3 = m[3], m4 = m[4], m5 = m[5];
  94. const F32 m6 = m[6], m7 = m[7], m8 = m[8];
  95. const F32 m9 = m[9], m10 = m[10], m11 = m[11];
  96. presult[0] = m0*p0 + m1*p1 + m2*p2 + m3;
  97. presult[1] = m4*p0 + m5*p1 + m6*p2 + m7;
  98. presult[2] = m8*p0 + m9*p1 + m10*p2 + m11;
  99. #else
  100. presult[0] = m[0]*p[0] + m[1]*p[1] + m[2]*p[2] + m[3];
  101. presult[1] = m[4]*p[0] + m[5]*p[1] + m[6]*p[2] + m[7];
  102. presult[2] = m[8]*p[0] + m[9]*p[1] + m[10]*p[2] + m[11];
  103. #endif
  104. }
  105. //--------------------------------------
  106. inline void m_matF_x_vectorF(const F32 *m, const F32 *v, F32 *vresult)
  107. {
  108. AssertFatal(v != vresult, "Error, aliasing matrix mul pointers not allowed here!");
  109. #ifdef TORQUE_COMPILER_GCC
  110. const F32 v0 = v[0], v1 = v[1], v2 = v[2];
  111. const F32 m0 = m[0], m1 = m[1], m2 = m[2];
  112. const F32 m4 = m[4], m5 = m[5], m6 = m[6];
  113. const F32 m8 = m[8], m9 = m[9], m10 = m[10];
  114. vresult[0] = m0*v0 + m1*v1 + m2*v2;
  115. vresult[1] = m4*v0 + m5*v1 + m6*v2;
  116. vresult[2] = m8*v0 + m9*v1 + m10*v2;
  117. #else
  118. vresult[0] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2];
  119. vresult[1] = m[4]*v[0] + m[5]*v[1] + m[6]*v[2];
  120. vresult[2] = m[8]*v[0] + m[9]*v[1] + m[10]*v[2];
  121. #endif
  122. }
  123. //--------------------------------------
  124. // Inlines
  125. inline bool mIsEqual( F32 a, F32 b, const F32 epsilon = __EQUAL_CONST_F )
  126. {
  127. F32 diff = a - b;
  128. return diff > -epsilon && diff < epsilon;
  129. }
  130. inline bool mIsZero(const F32 val, const F32 epsilon = __EQUAL_CONST_F )
  131. {
  132. return (val > -epsilon) && (val < epsilon);
  133. }
  134. inline F32 mClampToZero(F32& input)
  135. {
  136. if (input < __EQUAL_CONST_F && input > -__EQUAL_CONST_F)
  137. input = 0.0f;
  138. return input;
  139. }
  140. inline F32 mMax(const F32 x, const F32 y)
  141. {
  142. if (x > y)
  143. return x;
  144. return y;
  145. }
  146. inline F32 mMin(const F32 x, const F32 y)
  147. {
  148. if (x < y)
  149. return x;
  150. return y;
  151. }
  152. inline F32 mFloor(const F32 val)
  153. {
  154. return (F32) floor(val);
  155. }
  156. inline F32 mCeil(const F32 val)
  157. {
  158. return (F32) ceil(val);
  159. }
  160. inline F32 mFabs(const F32 val)
  161. {
  162. return (F32) fabs(val);
  163. }
  164. inline F64 mFabs(const F64 val)
  165. {
  166. return fabs(val);
  167. }
  168. inline F32 mFmod(const F32 val, const F32 mod)
  169. {
  170. return fmod(val, mod);
  171. }
  172. inline S32 mRound(const F32 val)
  173. {
  174. return (S32)floor(val + 0.5f);
  175. }
  176. inline F32 mRound(const F32 val, const S32 n)
  177. {
  178. S32 place = (S32) pow(10.0f, n);
  179. return mFloor((val*place)+0.5)/place;
  180. }
  181. inline F32 mRoundF(const F32 val, const F32 step)
  182. {
  183. if (step == 0.0f)
  184. return val;
  185. F32 a = mFmod(val, step);
  186. F32 temp = val;
  187. if (mFabs(a) > (step / 2))
  188. val < 0.0f ? temp -= step : temp += step;
  189. return(temp - a);
  190. }
  191. inline S32 mAbs(const S32 val)
  192. {
  193. return abs(val);
  194. }
  195. inline F32 mRoundToNearest( const F32 val )
  196. {
  197. return mFloor( val + .5f );
  198. }
  199. inline S32 mClamp(S32 val, S32 low, S32 high)
  200. {
  201. return getMax(getMin(val, high), low);
  202. }
  203. inline U32 mClampU(U32 val, U32 low, U32 high)
  204. {
  205. return getMax(getMin(val, high), low);
  206. }
  207. inline F32 mClampF(F32 val, F32 low, F32 high)
  208. {
  209. return (F32) getMax(getMin(val, high), low);
  210. }
  211. inline S32 mWrap(S32 val, S32 low, S32 high)
  212. {
  213. int len = high - low;
  214. return low + (val >= 0 ? val % len : -val % len ? len - (-val % len) : 0);
  215. }
  216. inline F32 mWrapF(F32 val, F32 low, F32 high)
  217. {
  218. F32 t = fmod(val - low, high - low);
  219. return t < 0 ? t + high : t + low;
  220. }
  221. /// Template function for doing a linear interpolation between any two
  222. /// types which implement operators for scalar multiply and addition.
  223. template <typename T>
  224. inline T mLerp( const T &v1, const T &v2, F32 factor )
  225. {
  226. return ( v1 * ( 1.0f - factor ) ) + ( v2 * factor );
  227. }
  228. /// Template function for determining a percentage of interpolation between any two
  229. /// types which implement operators for scalar multiply and addition.
  230. template <typename T>
  231. inline T mInvLerp(const T& v1, const T& v2, F32 point)
  232. {
  233. return (point - v1) / (v2 - v1);
  234. }
  235. inline S32 mMulDiv(S32 a, S32 b, S32 c)
  236. {
  237. return m_mulDivS32(a, b, c);
  238. }
  239. inline U32 mMulDiv(S32 a, S32 b, U32 c)
  240. {
  241. return m_mulDivU32(a, b, c);
  242. }
  243. inline F32 mSin(const F32 angle)
  244. {
  245. return (F32) sin(angle);
  246. }
  247. inline F32 mCos(const F32 angle)
  248. {
  249. return (F32) cos(angle);
  250. }
  251. inline F32 mTan(const F32 angle)
  252. {
  253. return (F32) tan(angle);
  254. }
  255. inline F32 mAsin(const F32 val)
  256. {
  257. return (F32) asin(val);
  258. }
  259. inline F32 mAcos(const F32 val)
  260. {
  261. return (F32) acos(val);
  262. }
  263. inline F32 mAtan( const F32 x )
  264. {
  265. return (F32) atan( x );
  266. }
  267. inline F32 mAtan2(const F32 y, const F32 x)
  268. {
  269. return (F32)atan2(y, x);
  270. }
  271. inline void mSinCos(const F32 angle, F32 &s, F32 &c)
  272. {
  273. m_sincos( angle, &s, &c );
  274. }
  275. inline F32 mTanh(const F32 angle)
  276. {
  277. return (F32) tanh(angle);
  278. }
  279. inline F32 mSqrt(const F32 val)
  280. {
  281. return (F32) sqrt(val);
  282. }
  283. inline F64 mSqrt(const F64 val)
  284. {
  285. return (F64) sqrt(val);
  286. }
  287. inline F32 mPow(const F32 x, const F32 y)
  288. {
  289. return (F32) pow(x, y);
  290. }
  291. inline F32 mLog(const F32 val)
  292. {
  293. return (F32) log(val);
  294. }
  295. inline F32 mLog2(const F32 val)
  296. {
  297. return (F32) log2(val);
  298. }
  299. inline F32 mExp(const F32 val)
  300. {
  301. return (F32) exp(val);
  302. }
  303. inline F64 mSin(const F64 angle)
  304. {
  305. return (F64) sin(angle);
  306. }
  307. inline F64 mCos(const F64 angle)
  308. {
  309. return (F64) cos(angle);
  310. }
  311. inline F64 mTan(const F64 angle)
  312. {
  313. return (F64) tan(angle);
  314. }
  315. inline F64 mAsin(const F64 val)
  316. {
  317. return (F64) asin(val);
  318. }
  319. inline F64 mAcos(const F64 val)
  320. {
  321. return (F64) acos(val);
  322. }
  323. inline F64 mAtan( const F64 x )
  324. {
  325. return (F64) atan( x );
  326. }
  327. inline F64 mAtan2(const F64 x, const F64 y)
  328. {
  329. return (F64) atan2(x, y);
  330. }
  331. inline void mSinCos(const F64 angle, F64 &s, F64 &c)
  332. {
  333. m_sincosD( angle, &s, &c );
  334. }
  335. inline F64 mTanh(const F64 angle)
  336. {
  337. return (F64) tanh(angle);
  338. }
  339. inline F64 mPow(const F64 x, const F64 y)
  340. {
  341. return (F64) pow(x, y);
  342. }
  343. inline F64 mLog(const F64 val)
  344. {
  345. return (F64) log(val);
  346. }
  347. inline F64 mLog2(const F64 val)
  348. {
  349. return (F64) log2(val);
  350. }
  351. inline F32 mCatmullrom(F32 t, F32 p0, F32 p1, F32 p2, F32 p3)
  352. {
  353. return m_catmullrom(t, p0, p1, p2, p3);
  354. }
  355. inline F64 mFabsD(const F64 val)
  356. {
  357. return (F64) fabs(val);
  358. }
  359. inline F64 mFmodD(const F64 val, const F64 mod)
  360. {
  361. return (F64) fmod(val, mod);
  362. }
  363. inline F64 mSqrtD(const F64 val)
  364. {
  365. return (F64) sqrt(val);
  366. }
  367. inline F64 mFloorD(const F64 val)
  368. {
  369. return (F64) floor(val);
  370. }
  371. inline F64 mCeilD(const F64 val)
  372. {
  373. return (F64) ceil(val);
  374. }
  375. ///
  376. template< typename A, typename B >
  377. inline A mAlignToMultiple( A val, B mul )
  378. {
  379. A rem = val % mul;
  380. return ( rem ? val + mul - rem : val );
  381. }
  382. //--------------------------------------
  383. inline F32 mDegToRad(F32 d)
  384. {
  385. return((d * M_PI_F) / 180.0f);
  386. }
  387. inline F32 mRadToDeg(F32 r)
  388. {
  389. return((r * 180.0f) / M_PI_F);
  390. }
  391. inline F64 mDegToRad(F64 d)
  392. {
  393. return (d * M_PI) / 180.0;
  394. }
  395. inline F64 mRadToDeg(F64 r)
  396. {
  397. return (r * 180.0) / M_PI;
  398. }
  399. //------------------------------------------------------------------------------
  400. inline bool mIsNaN_F( const F32 x )
  401. {
  402. // If x is a floating point variable, then (x != x) will be TRUE if x has the value NaN.
  403. // This is only going to work if the compiler is IEEE 748 compliant.
  404. //
  405. // Tested and working on VC2k5
  406. return ( x != x );
  407. }
  408. inline bool mIsInf_F( const F32 x )
  409. {
  410. return ( x == std::numeric_limits< F32 >::infinity() );
  411. }
  412. inline F32 mSign( const F32 n )
  413. {
  414. if ( n > 0.0f )
  415. return 1.0f;
  416. if ( n < 0.0f )
  417. return -1.0f;
  418. return 0.0f;
  419. }
  420. /// Returns the input value squared.
  421. inline F32 mSquared( F32 n )
  422. {
  423. return n * n;
  424. }
  425. /// @copydoc mSquaredF
  426. inline F64 mSquared( F64 n )
  427. {
  428. return n * n;
  429. }
  430. template< typename T >
  431. inline void mSwap(T& a, T& b) { T temp = b; b = a; a = temp; }
  432. #endif //_MMATHFN_H_