mMathFn.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 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. #ifndef _PLATFORM_H_
  25. #include "platform/platform.h"
  26. #endif
  27. #ifndef _MCONSTANTS_H_
  28. #include "math/mConstants.h"
  29. #endif
  30. #ifndef _CONSOLE_H_
  31. #include "console/console.h"
  32. #endif
  33. #include <math.h>
  34. // Remove a couple of annoying macros, if they are present (In VC 6, they are.)
  35. #ifdef min
  36. #undef min
  37. #endif
  38. #ifdef max
  39. #undef max
  40. #endif
  41. class MatrixF;
  42. class PlaneF;
  43. extern void MathConsoleInit();
  44. //--------------------------------------
  45. // Installable Library Prototypes
  46. extern S32 (*m_mulDivS32)(S32 a, S32 b, S32 c);
  47. extern U32 (*m_mulDivU32)(S32 a, S32 b, U32 c);
  48. extern F32 (*m_catmullrom)(F32 t, F32 p0, F32 p1, F32 p2, F32 p3);
  49. extern void (*m_point2F_normalize)(F32 *p);
  50. extern void (*m_point2F_normalize_f)(F32 *p, F32 len);
  51. extern void (*m_point2D_normalize)(F64 *p);
  52. extern void (*m_point2D_normalize_f)(F64 *p, F64 len);
  53. extern void (*m_point3F_normalize)(F32 *p);
  54. extern void (*m_point3F_normalize_f)(F32 *p, F32 len);
  55. extern void (*m_point3F_interpolate)(const F32 *from, const F32 *to, F32 factor, F32 *result);
  56. extern void (*m_point3D_normalize)(F64 *p);
  57. extern void (*m_point3D_normalize_f)(F64 *p, F64 len);
  58. extern void (*m_point3D_interpolate)(const F64 *from, const F64 *to, F64 factor, F64 *result);
  59. extern void (*m_point3F_bulk_dot)(const F32* refVector,
  60. const F32* dotPoints,
  61. const U32 numPoints,
  62. const U32 pointStride,
  63. F32* output);
  64. extern void (*m_point3F_bulk_dot_indexed)(const F32* refVector,
  65. const F32* dotPoints,
  66. const U32 numPoints,
  67. const U32 pointStride,
  68. const U32* pointIndices,
  69. F32* output);
  70. extern void (*m_quatF_set_matF)( F32 x, F32 y, F32 z, F32 w, F32* m );
  71. extern void (*m_matF_set_euler)(const F32 *e, F32 *result);
  72. extern void (*m_matF_set_euler_point)(const F32 *e, const F32 *p, F32 *result);
  73. extern void (*m_matF_identity)(F32 *m);
  74. extern void (*m_matF_inverse)(F32 *m);
  75. extern void (*m_matF_affineInverse)(F32 *m);
  76. extern void (*m_matF_transpose)(F32 *m);
  77. extern void (*m_matF_scale)(F32 *m,const F32* p);
  78. extern void (*m_matF_normalize)(F32 *m);
  79. extern F32 (*m_matF_determinant)(const F32 *m);
  80. extern void (*m_matF_x_matF)(const F32 *a, const F32 *b, F32 *mresult);
  81. extern void(*m_matF_x_matF_aligned)(const F32 *a, const F32 *b, F32 *mresult);
  82. // extern void (*m_matF_x_point3F)(const F32 *m, const F32 *p, F32 *presult);
  83. // extern void (*m_matF_x_vectorF)(const F32 *m, const F32 *v, F32 *vresult);
  84. extern void (*m_matF_x_point4F)(const F32 *m, const F32 *p, F32 *presult);
  85. extern void (*m_matF_x_scale_x_planeF)(const F32 *m, const F32* s, const F32 *p, F32 *presult);
  86. extern void (*m_matF_x_box3F)(const F32 *m, F32 *min, F32 *max);
  87. // Note that x must point to at least 4 values for quartics, and 3 for cubics
  88. extern U32 (*mSolveQuadratic)(F32 a, F32 b, F32 c, F32* x);
  89. extern U32 (*mSolveCubic)(F32 a, F32 b, F32 c, F32 d, F32* x);
  90. extern U32 (*mSolveQuartic)(F32 a, F32 b, F32 c, F32 d, F32 e, F32* x);
  91. extern S32 mRandI(S32 i1, S32 i2); // random # from i1 to i2 inclusive
  92. extern F32 mRandF(F32 f1, F32 f2); // random # from f1 to f2 inclusive
  93. inline void m_matF_x_point3F(const F32 *m, const F32 *p, F32 *presult)
  94. {
  95. AssertFatal(p != presult, "Error, aliasing matrix mul pointers not allowed here!");
  96. #if defined(TORQUE_SUPPORTS_GCC_INLINE_X86_ASM)
  97. // inline assembly version because gcc's math optimization isn't as good
  98. // JMQ: the profiler shows that with g++ 2.96, the difference
  99. // between the asm and optimized c versions is minimal.
  100. int u0, u1, u2;
  101. __asm__ __volatile__ (
  102. "flds 0x8(%%eax)\n"
  103. "fmuls 0x8(%%ecx)\n"
  104. "flds 0x4(%%eax)\n"
  105. "fmuls 0x4(%%ecx)\n"
  106. "faddp %%st,%%st(1)\n"
  107. "flds (%%eax)\n"
  108. "fmuls (%%ecx)\n"
  109. "faddp %%st,%%st(1)\n"
  110. "fadds 0xc(%%eax)\n"
  111. "fstps (%%edx)\n"
  112. "flds 0x18(%%eax)\n"
  113. "fmuls 0x8(%%ecx)\n"
  114. "flds 0x10(%%eax)\n"
  115. "fmuls (%%ecx)\n"
  116. "faddp %%st,%%st(1)\n"
  117. "flds 0x14(%%eax)\n"
  118. "fmuls 0x4(%%ecx)\n"
  119. "faddp %%st,%%st(1)\n"
  120. "fadds 0x1c(%%eax)\n"
  121. "fstps 0x4(%%edx)\n"
  122. "flds 0x28(%%eax)\n"
  123. "fmuls 0x8(%%ecx)\n"
  124. "flds 0x20(%%eax)\n"
  125. "fmuls (%%ecx)\n"
  126. "faddp %%st,%%st(1)\n"
  127. "flds 0x24(%%eax)\n"
  128. "fmuls 0x4(%%ecx)\n"
  129. "faddp %%st,%%st(1)\n"
  130. "fadds 0x2c(%%eax)\n"
  131. "fstps 0x8(%%edx)\n"
  132. : "=&a" (u0), "=&c" (u1), "=&d" (u2)
  133. : "0" (m), "1" (p), "2" (presult)
  134. : "memory" );
  135. #else
  136. presult[0] = m[0]*p[0] + m[1]*p[1] + m[2]*p[2] + m[3];
  137. presult[1] = m[4]*p[0] + m[5]*p[1] + m[6]*p[2] + m[7];
  138. presult[2] = m[8]*p[0] + m[9]*p[1] + m[10]*p[2] + m[11];
  139. #endif
  140. }
  141. //--------------------------------------
  142. inline void m_matF_x_vectorF(const F32 *m, const F32 *v, F32 *vresult)
  143. {
  144. AssertFatal(v != vresult, "Error, aliasing matrix mul pointers not allowed here!");
  145. #if defined(TORQUE_SUPPORTS_GCC_INLINE_X86_ASM)
  146. // inline assembly version because gcc's math optimization isn't as good
  147. // JMQ: the profiler shows that with g++ 2.96, the difference
  148. // between the asm and optimized c versions is minimal.
  149. int u0, u1, u2;
  150. __asm__ __volatile__ (
  151. "flds 0x8(%%ecx)\n"
  152. "fmuls 0x8(%%eax)\n"
  153. "flds 0x4(%%ecx)\n"
  154. "fmuls 0x4(%%eax)\n"
  155. "faddp %%st,%%st(1)\n"
  156. "flds (%%ecx)\n"
  157. "fmuls (%%eax)\n"
  158. "faddp %%st,%%st(1)\n"
  159. "fstps (%%edx)\n"
  160. "flds 0x18(%%ecx)\n"
  161. "fmuls 0x8(%%eax)\n"
  162. "flds 0x10(%%ecx)\n"
  163. "fmuls (%%eax)\n"
  164. "faddp %%st,%%st(1)\n"
  165. "flds 0x14(%%ecx)\n"
  166. "fmuls 0x4(%%eax)\n"
  167. "faddp %%st,%%st(1)\n"
  168. "fstps 0x4(%%edx)\n"
  169. "flds 0x28(%%ecx)\n"
  170. "fmuls 0x8(%%eax)\n"
  171. "flds 0x20(%%ecx)\n"
  172. "fmuls (%%eax)\n"
  173. "faddp %%st,%%st(1)\n"
  174. "flds 0x24(%%ecx)\n"
  175. "fmuls 0x4(%%eax)\n"
  176. "faddp %%st,%%st(1)\n"
  177. "fstps 0x8(%%edx)\n"
  178. : "=&c" (u0), "=&a" (u1), "=&d" (u2)
  179. : "0" (m), "1" (v), "2" (vresult)
  180. : "memory" );
  181. #else
  182. vresult[0] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2];
  183. vresult[1] = m[4]*v[0] + m[5]*v[1] + m[6]*v[2];
  184. vresult[2] = m[8]*v[0] + m[9]*v[1] + m[10]*v[2];
  185. #endif
  186. }
  187. U32 getNextPow2(U32 io_num);
  188. U32 getBinLog2(U32 io_num);
  189. /// Determines if the given U32 is some 2^n
  190. /// @returns true if in_num is a power of two, otherwise false
  191. inline bool isPow2(const U32 in_num)
  192. {
  193. return (in_num == getNextPow2(in_num));
  194. }
  195. /// Returns the lesser of the two parameters: a & b.
  196. inline U32 getMin(U32 a, U32 b)
  197. {
  198. return a>b ? b : a;
  199. }
  200. /// Returns the lesser of the two parameters: a & b.
  201. inline U16 getMin(U16 a, U16 b)
  202. {
  203. return a>b ? b : a;
  204. }
  205. /// Returns the lesser of the two parameters: a & b.
  206. inline U8 getMin(U8 a, U8 b)
  207. {
  208. return a>b ? b : a;
  209. }
  210. /// Returns the lesser of the two parameters: a & b.
  211. inline S32 getMin(S32 a, S32 b)
  212. {
  213. return a>b ? b : a;
  214. }
  215. /// Returns the lesser of the two parameters: a & b.
  216. inline S16 getMin(S16 a, S16 b)
  217. {
  218. return a>b ? b : a;
  219. }
  220. /// Returns the lesser of the two parameters: a & b.
  221. inline S8 getMin(S8 a, S8 b)
  222. {
  223. return a>b ? b : a;
  224. }
  225. /// Returns the lesser of the two parameters: a & b.
  226. inline float getMin(float a, float b)
  227. {
  228. return a>b ? b : a;
  229. }
  230. /// Returns the lesser of the two parameters: a & b.
  231. inline double getMin(double a, double b)
  232. {
  233. return a>b ? b : a;
  234. }
  235. /// Returns the greater of the two parameters: a & b.
  236. inline U32 getMax(U32 a, U32 b)
  237. {
  238. return a>b ? a : b;
  239. }
  240. /// Returns the greater of the two parameters: a & b.
  241. inline U16 getMax(U16 a, U16 b)
  242. {
  243. return a>b ? a : b;
  244. }
  245. /// Returns the greater of the two parameters: a & b.
  246. inline U8 getMax(U8 a, U8 b)
  247. {
  248. return a>b ? a : b;
  249. }
  250. /// Returns the greater of the two parameters: a & b.
  251. inline S32 getMax(S32 a, S32 b)
  252. {
  253. return a>b ? a : b;
  254. }
  255. /// Returns the greater of the two parameters: a & b.
  256. inline S16 getMax(S16 a, S16 b)
  257. {
  258. return a>b ? a : b;
  259. }
  260. /// Returns the greater of the two parameters: a & b.
  261. inline S8 getMax(S8 a, S8 b)
  262. {
  263. return a>b ? a : b;
  264. }
  265. /// Returns the greater of the two parameters: a & b.
  266. inline float getMax(float a, float b)
  267. {
  268. return a>b ? a : b;
  269. }
  270. /// Returns the greater of the two parameters: a & b.
  271. inline double getMax(double a, double b)
  272. {
  273. return a>b ? a : b;
  274. }
  275. inline F32 mFloor(const F32 val)
  276. {
  277. return (F32) floor(val);
  278. }
  279. inline F32 mCeil(const F32 val)
  280. {
  281. return (F32) ceil(val);
  282. }
  283. inline F32 mFabs(const F32 val)
  284. {
  285. return (F32) fabs(val);
  286. }
  287. inline F32 mFsign(const F32 val)
  288. {
  289. return (F32) (val > 0 ? 1 : val < 0 ? -1 : 0);
  290. }
  291. inline F32 mFmod(const F32 val, const F32 mod)
  292. {
  293. return (F32) fmod(val, mod);
  294. }
  295. inline S32 mAbs(const S32 val)
  296. {
  297. // Kinda lame, and disallows intrinsic inlining by the compiler. Maybe fix?
  298. // DMM
  299. if (val < 0)
  300. return -val;
  301. return val;
  302. }
  303. inline S32 mClamp(S32 val, S32 low, S32 high)
  304. {
  305. return getMax(getMin(val, high), low);
  306. }
  307. inline F32 mClampF(F32 val, F32 low, F32 high)
  308. {
  309. return (F32) getMax(getMin(val, high), low);
  310. }
  311. inline S32 mMulDiv(S32 a, S32 b, S32 c)
  312. {
  313. return m_mulDivS32(a, b, c);
  314. }
  315. inline U32 mMulDiv(S32 a, S32 b, U32 c)
  316. {
  317. return m_mulDivU32(a, b, c);
  318. }
  319. /// Template function for doing a linear interpolation between any two
  320. /// types which implement operators for scalar multiply and addition.
  321. template <typename T>
  322. inline T mLerp( const T &v1, const T &v2, F32 factor )
  323. {
  324. factor = mClampF( factor, 0.0f, 1.0f);
  325. return ( v1 * ( 1.0f - factor ) ) + ( v2 * factor );
  326. }
  327. template <typename T>
  328. inline T mSmoothStep( const T &v1, const T &v2, F32 factor)
  329. {
  330. factor = mClampF( factor, 0.0f, 1.0f);
  331. return mLerp(v1, v2, (factor*factor*(3.0f-2.0f*factor)));
  332. }
  333. inline F32 mSin(const F32 angle)
  334. {
  335. return (F32) sin(angle);
  336. }
  337. inline F32 mCos(const F32 angle)
  338. {
  339. return (F32) cos(angle);
  340. }
  341. inline F32 mTan(const F32 angle)
  342. {
  343. return (F32) tan(angle);
  344. }
  345. inline F32 mAsin(const F32 val)
  346. {
  347. return (F32) asin(val);
  348. }
  349. inline F32 mAcos(const F32 val)
  350. {
  351. return (F32) acos(val);
  352. }
  353. inline F32 mAtan(const F32 x, const F32 y)
  354. {
  355. return (F32) atan2(y, x);
  356. }
  357. inline void mSinCos(const F32 angle, F32 &s, F32 &c)
  358. {
  359. s = mSin(angle);
  360. c = mCos(angle);
  361. }
  362. inline F32 mTanh(const F32 angle)
  363. {
  364. return (F32) tanh(angle);
  365. }
  366. inline F32 mSqrt(const F32 val)
  367. {
  368. return (F32) sqrt(val);
  369. }
  370. inline F32 mPow(const F32 x, const F32 y)
  371. {
  372. return (F32) pow(x, y);
  373. }
  374. inline F32 mLog(const F32 val)
  375. {
  376. return (F32) log(val);
  377. }
  378. inline F64 mSin(const F64 angle)
  379. {
  380. return (F64) sin(angle);
  381. }
  382. inline F64 mCos(const F64 angle)
  383. {
  384. return (F64) cos(angle);
  385. }
  386. inline F64 mTan(const F64 angle)
  387. {
  388. return (F64) tan(angle);
  389. }
  390. inline F64 mAsin(const F64 val)
  391. {
  392. return (F64) asin(val);
  393. }
  394. inline F64 mAcos(const F64 val)
  395. {
  396. return (F64) acos(val);
  397. }
  398. inline F64 mAtan(const F64 x, const F64 y)
  399. {
  400. return (F64) atan2(y, x);
  401. }
  402. inline void mSinCos(const F64 angle, F64 &sin, F64 &cos)
  403. {
  404. sin = mSin(angle);
  405. cos = mCos(angle);
  406. }
  407. inline F64 mTanh(const F64 angle)
  408. {
  409. return (F64) tanh(angle);
  410. }
  411. inline F64 mPow(const F64 x, const F64 y)
  412. {
  413. return (F64) pow(x, y);
  414. }
  415. inline F64 mLog(const F64 val)
  416. {
  417. return (F64) log(val);
  418. }
  419. inline F32 mCatmullrom(F32 t, F32 p0, F32 p1, F32 p2, F32 p3)
  420. {
  421. return m_catmullrom(t, p0, p1, p2, p3);
  422. }
  423. inline F64 mFabsD(const F64 val)
  424. {
  425. return (F64) fabs(val);
  426. }
  427. inline F64 mFmodD(const F64 val, const F64 mod)
  428. {
  429. return (F64) fmod(val, mod);
  430. }
  431. inline F64 mSqrtD(const F64 val)
  432. {
  433. return (F64) sqrt(val);
  434. }
  435. inline F64 mFloorD(const F64 val)
  436. {
  437. return (F64) floor(val);
  438. }
  439. inline F64 mCeilD(const F64 val)
  440. {
  441. return (F64) ceil(val);
  442. }
  443. inline bool isEqual(F32 a, F32 b)
  444. {
  445. return mFabs(a - b) < __EQUAL_CONST_F;
  446. }
  447. inline bool isZero(F32 a)
  448. {
  449. return mFabs(a) < __EQUAL_CONST_F;
  450. }
  451. //--------------------------------------
  452. #ifndef _MPOINT_H_
  453. #include "math/mPoint.h"
  454. #endif
  455. inline F32 mDot(const Point2F &p1, const Point2F &p2)
  456. {
  457. return (p1.x*p2.x + p1.y*p2.y);
  458. }
  459. inline F32 mDot(const Point3F &p1, const Point3F &p2)
  460. {
  461. return (p1.x*p2.x + p1.y*p2.y + p1.z*p2.z);
  462. }
  463. inline void mCross(const Point3F &a, const Point3F &b, Point3F *res)
  464. {
  465. res->x = (a.y * b.z) - (a.z * b.y);
  466. res->y = (a.z * b.x) - (a.x * b.z);
  467. res->z = (a.x * b.y) - (a.y * b.x);
  468. }
  469. inline F64 mDot(const Point3D &p1, const Point3D &p2)
  470. {
  471. return (p1.x*p2.x + p1.y*p2.y + p1.z*p2.z);
  472. }
  473. inline void mCross(const Point3D &a, const Point3D &b, Point3D *res)
  474. {
  475. res->x = (a.y * b.z) - (a.z * b.y);
  476. res->y = (a.z * b.x) - (a.x * b.z);
  477. res->z = (a.x * b.y) - (a.y * b.x);
  478. }
  479. inline Point3F mCross(const Point3F &a, const Point3F &b)
  480. {
  481. Point3F ret;
  482. mCross(a,b,&ret);
  483. return ret;
  484. }
  485. inline void mCross(const F32* a, const F32* b, F32 *res)
  486. {
  487. res[0] = (a[1] * b[2]) - (a[2] * b[1]);
  488. res[1] = (a[2] * b[0]) - (a[0] * b[2]);
  489. res[2] = (a[0] * b[1]) - (a[1] * b[0]);
  490. }
  491. inline void mCross(const F64* a, const F64* b, F64* res)
  492. {
  493. res[0] = (a[1] * b[2]) - (a[2] * b[1]);
  494. res[1] = (a[2] * b[0]) - (a[0] * b[2]);
  495. res[2] = (a[0] * b[1]) - (a[1] * b[0]);
  496. }
  497. void mTransformPlane(const MatrixF& mat, const Point3F& scale, const PlaneF& plane, PlaneF* result);
  498. //--------------------------------------
  499. inline F32 mDegToRad(F32 d)
  500. {
  501. return F32((d * M_PI) / F32(180));
  502. }
  503. inline F32 mRadToDeg(F32 r)
  504. {
  505. return F32((r * 180.0) / M_PI);
  506. }
  507. inline F64 mDegToRad(F64 d)
  508. {
  509. return (d * M_PI) / F64(180);
  510. }
  511. inline F64 mRadToDeg(F64 r)
  512. {
  513. return (r * 180.0) / M_PI;
  514. }
  515. /// Precision Rounding.
  516. inline F32 mRound(const F32& value, const F32 epsilon = 0.5f) { return value > 0.0f ? mFloor(value + epsilon) : mCeil(value - epsilon); }
  517. /// Is NAN?
  518. inline F32 mIsNAN(const F32& value) { return (value != value); }
  519. /// Tolerate Is Zero?
  520. inline bool mIsZero(const F32& value) { return mFabs(value) < FLT_EPSILON; }
  521. /// Tolerate Not Zero?
  522. inline bool mNotZero(const F32& value) { return !mIsZero(value); }
  523. /// Tolerate Less-Than?
  524. inline bool mLessThan(const F32& a, const F32& b) { return a < b; }
  525. /// Tolerate Greater-Than?
  526. inline bool mGreaterThan(const F32& a, const F32& b) { return a > b; }
  527. /// Safe Less Than Zero?
  528. inline bool mLessThanZero(const F32& value) { return mLessThan(value, 0.0f); }
  529. /// Safe Greater Than Zero?
  530. inline bool mGreaterThanZero(const F32& value) { return mGreaterThan(value, 0.0f); }
  531. /// Safe Is Equal?
  532. inline bool mIsEqual(const F32& a, const F32& b) { return mIsZero(mFabs(a-b)); }
  533. /// Safe Not Equal?
  534. inline bool mNotEqual(const F32& a, const F32& b) { return !mIsEqual(a,b); }
  535. /// Tolerate Is Equal within Range?
  536. inline bool mIsEqualRange(const F32& a, const F32& b, const F32 epsilon = FLT_EPSILON) { return mFabs(a-b) <= epsilon; }
  537. /// Tolerate Is One?
  538. inline bool mIsOne(const F32& value) { return mIsEqual(value, 1.0f); }
  539. /// Tolerate Less-Than or Equal?
  540. inline bool mLessThanOrEqual(const F32& a, const F32& b) { return ( (a < b) || (!(a>b) && mIsEqual(a,b)) ); }
  541. /// Tolerate Greater-Than or Equal?
  542. inline bool mGreaterThanOrEqual(const F32&a, const F32& b) { return ( (a > b) || (!(a < b) && mIsEqual(a,b)) ); }
  543. /// Get Min/Max.
  544. inline void mGetMinMax(const F32& a, const F32& b, F32& min, F32& max) { if ( mGreaterThan(a,b) ) { max = a; min = b; } else { max = b; min = a; } }
  545. /// Swap.
  546. inline void mSwap(F32& a, F32& b) { F32 temp = b; b = a; a = temp; }
  547. //list of possible ways to ease progress
  548. enum EasingFunction
  549. {
  550. Linear,
  551. EaseIn,
  552. EaseOut,
  553. EaseInOut,
  554. EaseInBack,
  555. EaseOutBack,
  556. EaseInOutBack,
  557. EaseInElastic,
  558. EaseOutElastic,
  559. EaseInOutElastic,
  560. EaseInBounce,
  561. EaseOutBounce,
  562. EaseInOutBounce
  563. };
  564. static EnumTable::Enums easingEnums[] =
  565. {
  566. { EasingFunction::Linear, "linear" },
  567. { EasingFunction::EaseIn, "easeIn" },
  568. { EasingFunction::EaseOut, "easeOut" },
  569. { EasingFunction::EaseInOut, "easeInOut" },
  570. { EasingFunction::EaseInBack, "easeInBack" },
  571. { EasingFunction::EaseOutBack, "easeOutBack" },
  572. { EasingFunction::EaseInOutBack, "easeInOutBack" },
  573. { EasingFunction::EaseInElastic, "easeInElastic" },
  574. { EasingFunction::EaseOutElastic, "easeOutElastic" },
  575. { EasingFunction::EaseInOutElastic, "easeInOutElastic" },
  576. { EasingFunction::EaseInBounce, "easeInBounce" },
  577. { EasingFunction::EaseOutBounce, "easeOutBounce" },
  578. { EasingFunction::EaseInOutBounce, "easeInOutBounce" }
  579. };
  580. static EnumTable gEasingTable(13, &easingEnums[0]);
  581. // Given linear time progress between 0 and 1, this returns animation progress, based on
  582. // a selected easing function, between 0 and 1 (and possibly outside of 0 and 1 in some cases).
  583. F32 mEase(const EasingFunction &ease, const F32 &progress);
  584. #endif //_MMATHFN_H_