mMath_C.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  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. #include "math/mMath.h"
  23. #include <math.h> // Caution!!! Possible platform specific include
  24. //------------------------------------------------------------------------------
  25. // C version of Math Library
  26. // asm externals
  27. extern "C" {
  28. S32 m_mulDivS32_ASM( S32 a, S32 b, S32 c );
  29. U32 m_mulDivU32_ASM( U32 a, U32 b, U32 c );
  30. F32 m_fmod_ASM(F32 val, F32 modulo);
  31. F32 m_fmodD_ASM(F64 val, F64 modulo);
  32. void m_sincos_ASM( F32 angle, F32 *s, F32 *c );
  33. void m_sincosD_ASM( F64 angle, F64 *s, F64 *c );
  34. }
  35. //--------------------------------------
  36. static S32 m_mulDivS32_C(S32 a, S32 b, S32 c)
  37. {
  38. // S64/U64 support in most 32-bit compilers generate
  39. // horrible code, the C version are here just for porting
  40. // assembly implementation is recommended
  41. return (S32) ((S64)a*(S64)b) / (S64)c;
  42. }
  43. static U32 m_mulDivU32_C(S32 a, S32 b, U32 c)
  44. {
  45. return (U32) ((S64)a*(S64)b) / (U64)c;
  46. }
  47. //--------------------------------------
  48. static F32 m_catmullrom_C(F32 t, F32 p0, F32 p1, F32 p2, F32 p3)
  49. {
  50. return 0.5f * ((3.0f*p1 - 3.0f*p2 + p3 - p0)*t*t*t
  51. + (2.0f*p0 - 5.0f*p1 + 4.0f*p2 - p3)*t*t
  52. + (p2-p0)*t
  53. + 2.0f*p1);
  54. }
  55. //--------------------------------------
  56. static void m_point2F_normalize_C(F32 *p)
  57. {
  58. F32 factor = 1.0f / mSqrt(p[0]*p[0] + p[1]*p[1] );
  59. p[0] *= factor;
  60. p[1] *= factor;
  61. }
  62. //--------------------------------------
  63. static void m_point2F_normalize_f_C(F32 *p, F32 val)
  64. {
  65. F32 factor = val / mSqrt(p[0]*p[0] + p[1]*p[1] );
  66. p[0] *= factor;
  67. p[1] *= factor;
  68. }
  69. //--------------------------------------
  70. static void m_point2D_normalize_C(F64 *p)
  71. {
  72. F64 factor = 1.0f / mSqrtD(p[0]*p[0] + p[1]*p[1] );
  73. p[0] *= factor;
  74. p[1] *= factor;
  75. }
  76. //--------------------------------------
  77. static void m_point2D_normalize_f_C(F64 *p, F64 val)
  78. {
  79. F64 factor = val / mSqrtD(p[0]*p[0] + p[1]*p[1] );
  80. p[0] *= factor;
  81. p[1] *= factor;
  82. }
  83. //--------------------------------------
  84. static void m_point3D_normalize_f_C(F64 *p, F64 val)
  85. {
  86. F64 factor = val / mSqrtD(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
  87. p[0] *= factor;
  88. p[1] *= factor;
  89. p[2] *= factor;
  90. }
  91. //--------------------------------------
  92. static void m_point3F_normalize_C(F32 *p)
  93. {
  94. F32 squared = p[0]*p[0] + p[1]*p[1] + p[2]*p[2];
  95. // This can happen in Container::castRay -> ForceFieldBare::castRay
  96. //AssertFatal(squared != 0.0, "Error, zero length vector normalized!");
  97. if (squared != 0.0) {
  98. F32 factor = 1.0f / mSqrt(squared);
  99. p[0] *= factor;
  100. p[1] *= factor;
  101. p[2] *= factor;
  102. } else {
  103. p[0] = 0;
  104. p[1] = 0;
  105. p[2] = 1;
  106. }
  107. }
  108. //--------------------------------------
  109. static void m_point3F_normalize_f_C(F32 *p, F32 val)
  110. {
  111. F32 factor = val / mSqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
  112. p[0] *= factor;
  113. p[1] *= factor;
  114. p[2] *= factor;
  115. }
  116. //--------------------------------------
  117. static void m_point3F_interpolate_C(const F32 *from, const F32 *to, F32 factor, F32 *result )
  118. {
  119. F32 inverse = 1.0f - factor;
  120. result[0] = from[0] * inverse + to[0] * factor;
  121. result[1] = from[1] * inverse + to[1] * factor;
  122. result[2] = from[2] * inverse + to[2] * factor;
  123. }
  124. //--------------------------------------
  125. static void m_point3D_normalize_C(F64 *p)
  126. {
  127. F64 factor = 1.0f / mSqrtD(p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
  128. p[0] *= factor;
  129. p[1] *= factor;
  130. p[2] *= factor;
  131. }
  132. //--------------------------------------
  133. static void m_point3D_interpolate_C(const F64 *from, const F64 *to, F64 factor, F64 *result )
  134. {
  135. F64 inverse = 1.0f - factor;
  136. result[0] = from[0] * inverse + to[0] * factor;
  137. result[1] = from[1] * inverse + to[1] * factor;
  138. result[2] = from[2] * inverse + to[2] * factor;
  139. }
  140. static void m_quatF_set_matF_C( F32 x, F32 y, F32 z, F32 w, F32* m )
  141. {
  142. #define qidx(r,c) (r*4 + c)
  143. F32 xs = x * 2.0f;
  144. F32 ys = y * 2.0f;
  145. F32 zs = z * 2.0f;
  146. F32 wx = w * xs;
  147. F32 wy = w * ys;
  148. F32 wz = w * zs;
  149. F32 xx = x * xs;
  150. F32 xy = x * ys;
  151. F32 xz = x * zs;
  152. F32 yy = y * ys;
  153. F32 yz = y * zs;
  154. F32 zz = z * zs;
  155. m[qidx(0,0)] = 1.0f - (yy + zz);
  156. m[qidx(1,0)] = xy - wz;
  157. m[qidx(2,0)] = xz + wy;
  158. m[qidx(3,0)] = 0.0f;
  159. m[qidx(0,1)] = xy + wz;
  160. m[qidx(1,1)] = 1.0f - (xx + zz);
  161. m[qidx(2,1)] = yz - wx;
  162. m[qidx(3,1)] = 0.0f;
  163. m[qidx(0,2)] = xz - wy;
  164. m[qidx(1,2)] = yz + wx;
  165. m[qidx(2,2)] = 1.0f - (xx + yy);
  166. m[qidx(3,2)] = 0.0f;
  167. m[qidx(0,3)] = 0.0f;
  168. m[qidx(1,3)] = 0.0f;
  169. m[qidx(2,3)] = 0.0f;
  170. m[qidx(3,3)] = 1.0f;
  171. #undef qidx
  172. }
  173. //--------------------------------------
  174. static void m_matF_set_euler_C(const F32 *e, F32 *result)
  175. {
  176. enum {
  177. AXIS_X = (1<<0),
  178. AXIS_Y = (1<<1),
  179. AXIS_Z = (1<<2)
  180. };
  181. U32 axis = 0;
  182. if (e[0] != 0.0f) axis |= AXIS_X;
  183. if (e[1] != 0.0f) axis |= AXIS_Y;
  184. if (e[2] != 0.0f) axis |= AXIS_Z;
  185. switch (axis)
  186. {
  187. case 0:
  188. m_matF_identity(result);
  189. break;
  190. case AXIS_X:
  191. {
  192. F32 cx,sx;
  193. mSinCos( e[0], sx, cx );
  194. result[0] = 1.0f;
  195. result[1] = 0.0f;
  196. result[2] = 0.0f;
  197. result[3] = 0.0f;
  198. result[4] = 0.0f;
  199. result[5] = cx;
  200. result[6] = sx;
  201. result[7] = 0.0f;
  202. result[8] = 0.0f;
  203. result[9] = -sx;
  204. result[10]= cx;
  205. result[11]= 0.0f;
  206. result[12]= 0.0f;
  207. result[13]= 0.0f;
  208. result[14]= 0.0f;
  209. result[15]= 1.0f;
  210. break;
  211. }
  212. case AXIS_Y:
  213. {
  214. F32 cy,sy;
  215. mSinCos( e[1], sy, cy );
  216. result[0] = cy;
  217. result[1] = 0.0f;
  218. result[2] = -sy;
  219. result[3] = 0.0f;
  220. result[4] = 0.0f;
  221. result[5] = 1.0f;
  222. result[6] = 0.0f;
  223. result[7] = 0.0f;
  224. result[8] = sy;
  225. result[9] = 0.0f;
  226. result[10]= cy;
  227. result[11]= 0.0f;
  228. result[12]= 0.0f;
  229. result[13]= 0.0f;
  230. result[14]= 0.0f;
  231. result[15]= 1.0f;
  232. break;
  233. }
  234. case AXIS_Z:
  235. {
  236. // the matrix looks like this:
  237. // r1 - (r4 * sin(x)) r2 + (r3 * sin(x)) -cos(x) * sin(y)
  238. // -cos(x) * sin(z) cos(x) * cos(z) sin(x)
  239. // r3 + (r2 * sin(x)) r4 - (r1 * sin(x)) cos(x) * cos(y)
  240. //
  241. // where:
  242. // r1 = cos(y) * cos(z)
  243. // r2 = cos(y) * sin(z)
  244. // r3 = sin(y) * cos(z)
  245. // r4 = sin(y) * sin(z)
  246. F32 cz,sz;
  247. mSinCos( e[2], sz, cz );
  248. result[0] = cz;
  249. result[1] = sz;
  250. result[2] = 0.0f;
  251. result[3] = 0.0f;
  252. result[4] = -sz;
  253. result[5] = cz;
  254. result[6] = 0.0f;
  255. result[7] = 0.0f;
  256. result[8] = 0.0f;
  257. result[9] = 0.0f;
  258. result[10]= 1.0f;
  259. result[11]= 0.0f;
  260. result[12]= 0.0f;
  261. result[13]= 0.0f;
  262. result[14]= 0.0f;
  263. result[15]= 1.0f;
  264. break;
  265. }
  266. default:
  267. // the matrix looks like this:
  268. // r1 - (r4 * sin(x)) r2 + (r3 * sin(x)) -cos(x) * sin(y)
  269. // -cos(x) * sin(z) cos(x) * cos(z) sin(x)
  270. // r3 + (r2 * sin(x)) r4 - (r1 * sin(x)) cos(x) * cos(y)
  271. //
  272. // where:
  273. // r1 = cos(y) * cos(z)
  274. // r2 = cos(y) * sin(z)
  275. // r3 = sin(y) * cos(z)
  276. // r4 = sin(y) * sin(z)
  277. F32 cx,sx;
  278. mSinCos( e[0], sx, cx );
  279. F32 cy,sy;
  280. mSinCos( e[1], sy, cy );
  281. F32 cz,sz;
  282. mSinCos( e[2], sz, cz );
  283. F32 r1 = cy * cz;
  284. F32 r2 = cy * sz;
  285. F32 r3 = sy * cz;
  286. F32 r4 = sy * sz;
  287. result[0] = r1 - (r4 * sx);
  288. result[1] = r2 + (r3 * sx);
  289. result[2] = -cx * sy;
  290. result[3] = 0.0f;
  291. result[4] = -cx * sz;
  292. result[5] = cx * cz;
  293. result[6] = sx;
  294. result[7] = 0.0f;
  295. result[8] = r3 + (r2 * sx);
  296. result[9] = r4 - (r1 * sx);
  297. result[10]= cx * cy;
  298. result[11]= 0.0f;
  299. result[12]= 0.0f;
  300. result[13]= 0.0f;
  301. result[14]= 0.0f;
  302. result[15]= 1.0f;
  303. break;
  304. }
  305. }
  306. //--------------------------------------
  307. static void m_matF_set_euler_point_C(const F32 *e, const F32 *p, F32 *result)
  308. {
  309. m_matF_set_euler(e, result);
  310. result[3] = p[0];
  311. result[7] = p[1];
  312. result[11]= p[2];
  313. }
  314. //--------------------------------------
  315. static void m_matF_identity_C(F32 *m)
  316. {
  317. *m++ = 1.0f;
  318. *m++ = 0.0f;
  319. *m++ = 0.0f;
  320. *m++ = 0.0f;
  321. *m++ = 0.0f;
  322. *m++ = 1.0f;
  323. *m++ = 0.0f;
  324. *m++ = 0.0f;
  325. *m++ = 0.0f;
  326. *m++ = 0.0f;
  327. *m++ = 1.0f;
  328. *m++ = 0.0f;
  329. *m++ = 0.0f;
  330. *m++ = 0.0f;
  331. *m++ = 0.0f;
  332. *m = 1.0f;
  333. }
  334. //--------------------------------------
  335. static void m_matF_inverse_C(F32 *m)
  336. {
  337. // using Cramers Rule find the Inverse
  338. // Minv = (1/det(M)) * adjoint(M)
  339. F32 det = m_matF_determinant( m );
  340. AssertFatal( det != 0.0f, "MatrixF::inverse: non-singular matrix, no inverse.");
  341. F32 invDet = 1.0f/det;
  342. F32 temp[16];
  343. temp[0] = (m[5] * m[10]- m[6] * m[9]) * invDet;
  344. temp[1] = (m[9] * m[2] - m[10]* m[1]) * invDet;
  345. temp[2] = (m[1] * m[6] - m[2] * m[5]) * invDet;
  346. temp[4] = (m[6] * m[8] - m[4] * m[10])* invDet;
  347. temp[5] = (m[10]* m[0] - m[8] * m[2]) * invDet;
  348. temp[6] = (m[2] * m[4] - m[0] * m[6]) * invDet;
  349. temp[8] = (m[4] * m[9] - m[5] * m[8]) * invDet;
  350. temp[9] = (m[8] * m[1] - m[9] * m[0]) * invDet;
  351. temp[10]= (m[0] * m[5] - m[1] * m[4]) * invDet;
  352. m[0] = temp[0];
  353. m[1] = temp[1];
  354. m[2] = temp[2];
  355. m[4] = temp[4];
  356. m[5] = temp[5];
  357. m[6] = temp[6];
  358. m[8] = temp[8];
  359. m[9] = temp[9];
  360. m[10] = temp[10];
  361. // invert the translation
  362. temp[0] = -m[3];
  363. temp[1] = -m[7];
  364. temp[2] = -m[11];
  365. m_matF_x_vectorF(m, temp, &temp[4]);
  366. m[3] = temp[4];
  367. m[7] = temp[5];
  368. m[11]= temp[6];
  369. }
  370. //--------------------------------------
  371. static void m_matF_affineInverse_C(F32 *m)
  372. {
  373. // Matrix class checks to make sure this is an affine transform before calling
  374. // this function, so we can proceed assuming it is...
  375. F32 temp[16];
  376. dMemcpy(temp, m, 16 * sizeof(F32));
  377. // Transpose rotation
  378. m[1] = temp[4];
  379. m[4] = temp[1];
  380. m[2] = temp[8];
  381. m[8] = temp[2];
  382. m[6] = temp[9];
  383. m[9] = temp[6];
  384. m[3] = -(temp[0]*temp[3] + temp[4]*temp[7] + temp[8]*temp[11]);
  385. m[7] = -(temp[1]*temp[3] + temp[5]*temp[7] + temp[9]*temp[11]);
  386. m[11] = -(temp[2]*temp[3] + temp[6]*temp[7] + temp[10]*temp[11]);
  387. }
  388. inline void swap(F32 &a, F32 &b)
  389. {
  390. F32 temp = a;
  391. a = b;
  392. b = temp;
  393. }
  394. //--------------------------------------
  395. static void m_matF_transpose_C(F32 *m)
  396. {
  397. swap(m[1], m[4]);
  398. swap(m[2], m[8]);
  399. swap(m[3], m[12]);
  400. swap(m[6], m[9]);
  401. swap(m[7], m[13]);
  402. swap(m[11],m[14]);
  403. }
  404. //--------------------------------------
  405. static void m_matF_scale_C(F32 *m,const F32 *p)
  406. {
  407. // Note, doesn't allow scaling w...
  408. m[0] *= p[0]; m[1] *= p[1]; m[2] *= p[2];
  409. m[4] *= p[0]; m[5] *= p[1]; m[6] *= p[2];
  410. m[8] *= p[0]; m[9] *= p[1]; m[10] *= p[2];
  411. m[12] *= p[0]; m[13] *= p[1]; m[14] *= p[2];
  412. }
  413. //--------------------------------------
  414. static void m_matF_normalize_C(F32 *m)
  415. {
  416. F32 col0[3], col1[3], col2[3];
  417. // extract columns 0 and 1
  418. col0[0] = m[0];
  419. col0[1] = m[4];
  420. col0[2] = m[8];
  421. col1[0] = m[1];
  422. col1[1] = m[5];
  423. col1[2] = m[9];
  424. // assure their relationsips to one another
  425. mCross(col0, col1, col2);
  426. mCross(col2, col0, col1);
  427. // assure their lengh is 1.0f
  428. m_point3F_normalize( col0 );
  429. m_point3F_normalize( col1 );
  430. m_point3F_normalize( col2 );
  431. // store the normalized columns
  432. m[0] = col0[0];
  433. m[4] = col0[1];
  434. m[8] = col0[2];
  435. m[1] = col1[0];
  436. m[5] = col1[1];
  437. m[9] = col1[2];
  438. m[2] = col2[0];
  439. m[6] = col2[1];
  440. m[10]= col2[2];
  441. }
  442. //--------------------------------------
  443. static F32 m_matF_determinant_C(const F32 *m)
  444. {
  445. return m[0] * (m[5] * m[10] - m[6] * m[9]) +
  446. m[4] * (m[2] * m[9] - m[1] * m[10]) +
  447. m[8] * (m[1] * m[6] - m[2] * m[5]) ;
  448. }
  449. //--------------------------------------
  450. // Removed static in order to write benchmarking code (that compares against
  451. // specialized SSE/AMD versions) elsewhere.
  452. void default_matF_x_matF_C(const F32 *a, const F32 *b, F32 *mresult)
  453. {
  454. mresult[0] = a[0]*b[0] + a[1]*b[4] + a[2]*b[8] + a[3]*b[12];
  455. mresult[1] = a[0]*b[1] + a[1]*b[5] + a[2]*b[9] + a[3]*b[13];
  456. mresult[2] = a[0]*b[2] + a[1]*b[6] + a[2]*b[10] + a[3]*b[14];
  457. mresult[3] = a[0]*b[3] + a[1]*b[7] + a[2]*b[11] + a[3]*b[15];
  458. mresult[4] = a[4]*b[0] + a[5]*b[4] + a[6]*b[8] + a[7]*b[12];
  459. mresult[5] = a[4]*b[1] + a[5]*b[5] + a[6]*b[9] + a[7]*b[13];
  460. mresult[6] = a[4]*b[2] + a[5]*b[6] + a[6]*b[10] + a[7]*b[14];
  461. mresult[7] = a[4]*b[3] + a[5]*b[7] + a[6]*b[11] + a[7]*b[15];
  462. mresult[8] = a[8]*b[0] + a[9]*b[4] + a[10]*b[8] + a[11]*b[12];
  463. mresult[9] = a[8]*b[1] + a[9]*b[5] + a[10]*b[9] + a[11]*b[13];
  464. mresult[10]= a[8]*b[2] + a[9]*b[6] + a[10]*b[10]+ a[11]*b[14];
  465. mresult[11]= a[8]*b[3] + a[9]*b[7] + a[10]*b[11]+ a[11]*b[15];
  466. mresult[12]= a[12]*b[0]+ a[13]*b[4]+ a[14]*b[8] + a[15]*b[12];
  467. mresult[13]= a[12]*b[1]+ a[13]*b[5]+ a[14]*b[9] + a[15]*b[13];
  468. mresult[14]= a[12]*b[2]+ a[13]*b[6]+ a[14]*b[10]+ a[15]*b[14];
  469. mresult[15]= a[12]*b[3]+ a[13]*b[7]+ a[14]*b[11]+ a[15]*b[15];
  470. }
  471. // //--------------------------------------
  472. // static void m_matF_x_point3F_C(const F32 *m, const F32 *p, F32 *presult)
  473. // {
  474. // AssertFatal(p != presult, "Error, aliasing matrix mul pointers not allowed here!");
  475. // presult[0] = m[0]*p[0] + m[1]*p[1] + m[2]*p[2] + m[3];
  476. // presult[1] = m[4]*p[0] + m[5]*p[1] + m[6]*p[2] + m[7];
  477. // presult[2] = m[8]*p[0] + m[9]*p[1] + m[10]*p[2] + m[11];
  478. // }
  479. // //--------------------------------------
  480. // static void m_matF_x_vectorF_C(const F32 *m, const F32 *v, F32 *vresult)
  481. // {
  482. // AssertFatal(v != vresult, "Error, aliasing matrix mul pointers not allowed here!");
  483. // vresult[0] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2];
  484. // vresult[1] = m[4]*v[0] + m[5]*v[1] + m[6]*v[2];
  485. // vresult[2] = m[8]*v[0] + m[9]*v[1] + m[10]*v[2];
  486. // }
  487. //--------------------------------------
  488. static void m_matF_x_point4F_C(const F32 *m, const F32 *p, F32 *presult)
  489. {
  490. AssertFatal(p != presult, "Error, aliasing matrix mul pointers not allowed here!");
  491. presult[0] = m[0]*p[0] + m[1]*p[1] + m[2]*p[2] + m[3]*p[3];
  492. presult[1] = m[4]*p[0] + m[5]*p[1] + m[6]*p[2] + m[7]*p[3];
  493. presult[2] = m[8]*p[0] + m[9]*p[1] + m[10]*p[2] + m[11]*p[3];
  494. presult[3] = m[12]*p[0]+ m[13]*p[1]+ m[14]*p[2] + m[15]*p[3];
  495. }
  496. //--------------------------------------
  497. static void m_matF_x_scale_x_planeF_C(const F32* m, const F32* s, const F32* p, F32* presult)
  498. {
  499. // We take in a matrix, a scale factor, and a plane equation. We want to output
  500. // the resultant normal
  501. // We have T = m*s
  502. // To multiply the normal, we want Inv(Tr(m*s))
  503. // Inv(Tr(ms)) = Inv(Tr(s) * Tr(m))
  504. // = Inv(Tr(m)) * Inv(Tr(s))
  505. //
  506. // Inv(Tr(s)) = Inv(s) = [ 1/x 0 0 0]
  507. // [ 0 1/y 0 0]
  508. // [ 0 0 1/z 0]
  509. // [ 0 0 0 1]
  510. //
  511. // Since m is an affine matrix,
  512. // Tr(m) = [ [ ] 0 ]
  513. // [ [ R ] 0 ]
  514. // [ [ ] 0 ]
  515. // [ [ x y z ] 1 ]
  516. //
  517. // Inv(Tr(m)) = [ [ -1 ] 0 ]
  518. // [ [ R ] 0 ]
  519. // [ [ ] 0 ]
  520. // [ [ A B C ] 1 ]
  521. // Where:
  522. //
  523. // P = (x, y, z)
  524. // A = -(Row(0, r) * P);
  525. // B = -(Row(1, r) * P);
  526. // C = -(Row(2, r) * P);
  527. MatrixF invScale(true);
  528. F32* pScaleElems = invScale;
  529. pScaleElems[MatrixF::idx(0, 0)] = 1.0f / s[0];
  530. pScaleElems[MatrixF::idx(1, 1)] = 1.0f / s[1];
  531. pScaleElems[MatrixF::idx(2, 2)] = 1.0f / s[2];
  532. Point3F shear;
  533. shear.x = m[MatrixF::idx(3, 0)];
  534. shear.y = m[MatrixF::idx(3, 1)];
  535. shear.z = m[MatrixF::idx(3, 2)];
  536. Point3F row0(m[MatrixF::idx(0, 0)], m[MatrixF::idx(0, 1)], m[MatrixF::idx(0, 2)]);
  537. Point3F row1(m[MatrixF::idx(1, 0)], m[MatrixF::idx(1, 1)], m[MatrixF::idx(1, 2)]);
  538. Point3F row2(m[MatrixF::idx(2, 0)], m[MatrixF::idx(2, 1)], m[MatrixF::idx(2, 2)]);
  539. F32 A = -mDot(row0, shear);
  540. F32 B = -mDot(row1, shear);
  541. F32 C = -mDot(row2, shear);
  542. MatrixF invTrMatrix(true);
  543. F32* destMat = invTrMatrix;
  544. destMat[MatrixF::idx(0, 0)] = m[MatrixF::idx(0, 0)];
  545. destMat[MatrixF::idx(1, 0)] = m[MatrixF::idx(1, 0)];
  546. destMat[MatrixF::idx(2, 0)] = m[MatrixF::idx(2, 0)];
  547. destMat[MatrixF::idx(0, 1)] = m[MatrixF::idx(0, 1)];
  548. destMat[MatrixF::idx(1, 1)] = m[MatrixF::idx(1, 1)];
  549. destMat[MatrixF::idx(2, 1)] = m[MatrixF::idx(2, 1)];
  550. destMat[MatrixF::idx(0, 2)] = m[MatrixF::idx(0, 2)];
  551. destMat[MatrixF::idx(1, 2)] = m[MatrixF::idx(1, 2)];
  552. destMat[MatrixF::idx(2, 2)] = m[MatrixF::idx(2, 2)];
  553. destMat[MatrixF::idx(0, 3)] = A;
  554. destMat[MatrixF::idx(1, 3)] = B;
  555. destMat[MatrixF::idx(2, 3)] = C;
  556. invTrMatrix.mul(invScale);
  557. Point3F norm(p[0], p[1], p[2]);
  558. Point3F point = norm * -p[3];
  559. invTrMatrix.mulP(norm);
  560. norm.normalize();
  561. MatrixF temp;
  562. dMemcpy(temp, m, sizeof(F32) * 16);
  563. point.x *= s[0];
  564. point.y *= s[1];
  565. point.z *= s[2];
  566. temp.mulP(point);
  567. PlaneF resultPlane(point, norm);
  568. presult[0] = resultPlane.x;
  569. presult[1] = resultPlane.y;
  570. presult[2] = resultPlane.z;
  571. presult[3] = resultPlane.d;
  572. }
  573. static void m_matF_x_box3F_C(const F32 *m, F32* min, F32* max)
  574. {
  575. // Algorithm for axis aligned bounding box adapted from
  576. // Graphic Gems I, pp 548-550
  577. //
  578. F32 originalMin[3];
  579. F32 originalMax[3];
  580. originalMin[0] = min[0];
  581. originalMin[1] = min[1];
  582. originalMin[2] = min[2];
  583. originalMax[0] = max[0];
  584. originalMax[1] = max[1];
  585. originalMax[2] = max[2];
  586. min[0] = max[0] = m[3];
  587. min[1] = max[1] = m[7];
  588. min[2] = max[2] = m[11];
  589. const F32 * row = &m[0];
  590. for (U32 i = 0; i < 3; i++)
  591. {
  592. #define Do_One_Row(j) { \
  593. F32 a = (row[j] * originalMin[j]); \
  594. F32 b = (row[j] * originalMax[j]); \
  595. if (a < b) { *min += a; *max += b; } \
  596. else { *min += b; *max += a; } }
  597. // Simpler addressing (avoiding things like [ecx+edi*4]) might be worthwhile (LH):
  598. Do_One_Row(0);
  599. Do_One_Row(1);
  600. Do_One_Row(2);
  601. row += 4;
  602. min++;
  603. max++;
  604. }
  605. }
  606. void m_point3F_bulk_dot_C(const F32* refVector,
  607. const F32* dotPoints,
  608. const U32 numPoints,
  609. const U32 pointStride,
  610. F32* output)
  611. {
  612. for (U32 i = 0; i < numPoints; i++)
  613. {
  614. F32* pPoint = (F32*)(((U8*)dotPoints) + (pointStride * i));
  615. output[i] = ((refVector[0] * pPoint[0]) +
  616. (refVector[1] * pPoint[1]) +
  617. (refVector[2] * pPoint[2]));
  618. }
  619. }
  620. void m_point3F_bulk_dot_indexed_C(const F32* refVector,
  621. const F32* dotPoints,
  622. const U32 numPoints,
  623. const U32 pointStride,
  624. const U32* pointIndices,
  625. F32* output)
  626. {
  627. for (U32 i = 0; i < numPoints; i++)
  628. {
  629. F32* pPoint = (F32*)(((U8*)dotPoints) + (pointStride * pointIndices[i]));
  630. output[i] = ((refVector[0] * pPoint[0]) +
  631. (refVector[1] * pPoint[1]) +
  632. (refVector[2] * pPoint[2]));
  633. }
  634. }
  635. //------------------------------------------------------------------------------
  636. // Math function pointer declarations
  637. S32 (*m_mulDivS32)(S32 a, S32 b, S32 c) = m_mulDivS32_C;
  638. U32 (*m_mulDivU32)(S32 a, S32 b, U32 c) = m_mulDivU32_C;
  639. F32 (*m_catmullrom)(F32 t, F32 p0, F32 p1, F32 p2, F32 p3) = m_catmullrom_C;
  640. void (*m_point2F_normalize)(F32 *p) = m_point2F_normalize_C;
  641. void (*m_point2F_normalize_f)(F32 *p, F32 val) = m_point2F_normalize_f_C;
  642. void (*m_point2D_normalize)(F64 *p) = m_point2D_normalize_C;
  643. void (*m_point2D_normalize_f)(F64 *p, F64 val) = m_point2D_normalize_f_C;
  644. void (*m_point3D_normalize_f)(F64 *p, F64 val) = m_point3D_normalize_f_C;
  645. void (*m_point3F_normalize)(F32 *p) = m_point3F_normalize_C;
  646. void (*m_point3F_normalize_f)(F32 *p, F32 len) = m_point3F_normalize_f_C;
  647. void (*m_point3F_interpolate)(const F32 *from, const F32 *to, F32 factor, F32 *result) = m_point3F_interpolate_C;
  648. void (*m_point3D_normalize)(F64 *p) = m_point3D_normalize_C;
  649. void (*m_point3D_interpolate)(const F64 *from, const F64 *to, F64 factor, F64 *result) = m_point3D_interpolate_C;
  650. void (*m_point3F_bulk_dot)(const F32* refVector,
  651. const F32* dotPoints,
  652. const U32 numPoints,
  653. const U32 pointStride,
  654. F32* output) = m_point3F_bulk_dot_C;
  655. void (*m_point3F_bulk_dot_indexed)(const F32* refVector,
  656. const F32* dotPoints,
  657. const U32 numPoints,
  658. const U32 pointStride,
  659. const U32* pointIndices,
  660. F32* output) = m_point3F_bulk_dot_indexed_C;
  661. void (*m_quatF_set_matF)( F32 x, F32 y, F32 z, F32 w, F32* m ) = m_quatF_set_matF_C;
  662. void (*m_matF_set_euler)(const F32 *e, F32 *result) = m_matF_set_euler_C;
  663. void (*m_matF_set_euler_point)(const F32 *e, const F32 *p, F32 *result) = m_matF_set_euler_point_C;
  664. void (*m_matF_identity)(F32 *m) = m_matF_identity_C;
  665. void (*m_matF_inverse)(F32 *m) = m_matF_inverse_C;
  666. void (*m_matF_affineInverse)(F32 *m) = m_matF_affineInverse_C;
  667. void (*m_matF_transpose)(F32 *m) = m_matF_transpose_C;
  668. void (*m_matF_scale)(F32 *m,const F32* p) = m_matF_scale_C;
  669. void (*m_matF_normalize)(F32 *m) = m_matF_normalize_C;
  670. F32 (*m_matF_determinant)(const F32 *m) = m_matF_determinant_C;
  671. void (*m_matF_x_matF)(const F32 *a, const F32 *b, F32 *mresult) = default_matF_x_matF_C;
  672. void(*m_matF_x_matF_aligned)(const F32 *a, const F32 *b, F32 *mresult) = default_matF_x_matF_C;
  673. // void (*m_matF_x_point3F)(const F32 *m, const F32 *p, F32 *presult) = m_matF_x_point3F_C;
  674. // void (*m_matF_x_vectorF)(const F32 *m, const F32 *v, F32 *vresult) = m_matF_x_vectorF_C;
  675. void (*m_matF_x_point4F)(const F32 *m, const F32 *p, F32 *presult) = m_matF_x_point4F_C;
  676. void (*m_matF_x_scale_x_planeF)(const F32 *m, const F32* s, const F32 *p, F32 *presult) = m_matF_x_scale_x_planeF_C;
  677. void (*m_matF_x_box3F)(const F32 *m, F32 *min, F32 *max) = m_matF_x_box3F_C;
  678. //------------------------------------------------------------------------------
  679. void mInstallLibrary_C()
  680. {
  681. m_mulDivS32 = m_mulDivS32_C;
  682. m_mulDivU32 = m_mulDivU32_C;
  683. m_catmullrom = m_catmullrom_C;
  684. m_point2F_normalize = m_point2F_normalize_C;
  685. m_point2F_normalize_f = m_point2F_normalize_f_C;
  686. m_point2D_normalize = m_point2D_normalize_C;
  687. m_point2D_normalize_f = m_point2D_normalize_f_C;
  688. m_point3F_normalize = m_point3F_normalize_C;
  689. m_point3F_normalize_f = m_point3F_normalize_f_C;
  690. m_point3F_interpolate = m_point3F_interpolate_C;
  691. m_point3D_normalize = m_point3D_normalize_C;
  692. m_point3D_interpolate = m_point3D_interpolate_C;
  693. m_point3F_bulk_dot = m_point3F_bulk_dot_C;
  694. m_point3F_bulk_dot_indexed = m_point3F_bulk_dot_indexed_C;
  695. m_quatF_set_matF = m_quatF_set_matF_C;
  696. m_matF_set_euler = m_matF_set_euler_C;
  697. m_matF_set_euler_point = m_matF_set_euler_point_C;
  698. m_matF_identity = m_matF_identity_C;
  699. m_matF_inverse = m_matF_inverse_C;
  700. m_matF_affineInverse = m_matF_affineInverse_C;
  701. m_matF_transpose = m_matF_transpose_C;
  702. m_matF_scale = m_matF_scale_C;
  703. m_matF_normalize = m_matF_normalize_C;
  704. m_matF_determinant = m_matF_determinant_C;
  705. m_matF_x_matF = default_matF_x_matF_C;
  706. // m_matF_x_point3F = m_matF_x_point3F_C;
  707. // m_matF_x_vectorF = m_matF_x_vectorF_C;
  708. m_matF_x_point4F = m_matF_x_point4F_C;
  709. m_matF_x_scale_x_planeF = m_matF_x_scale_x_planeF_C;
  710. m_matF_x_box3F = m_matF_x_box3F_C;
  711. }