Cry_Matrix44.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : Common matrix class
  9. #ifndef CRYINCLUDE_CRYCOMMON_CRY_MATRIX44_H
  10. #define CRYINCLUDE_CRYCOMMON_CRY_MATRIX44_H
  11. #pragma once
  12. ///////////////////////////////////////////////////////////////////////////////
  13. ///////////////////////////////////////////////////////////////////////////////
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // struct Matrix44_tpl
  16. ///////////////////////////////////////////////////////////////////////////////
  17. ///////////////////////////////////////////////////////////////////////////////
  18. ///////////////////////////////////////////////////////////////////////////////
  19. template<typename F>
  20. struct Matrix44_tpl
  21. {
  22. F m00, m01, m02, m03;
  23. F m10, m11, m12, m13;
  24. F m20, m21, m22, m23;
  25. F m30, m31, m32, m33;
  26. //---------------------------------------------------------------------------------
  27. #if defined(_DEBUG)
  28. ILINE Matrix44_tpl()
  29. {
  30. if constexpr (sizeof(F) == 4)
  31. {
  32. uint32* p = (uint32*)&m00;
  33. p[ 0] = F32NAN;
  34. p[ 1] = F32NAN;
  35. p[ 2] = F32NAN;
  36. p[ 3] = F32NAN;
  37. p[ 4] = F32NAN;
  38. p[ 5] = F32NAN;
  39. p[ 6] = F32NAN;
  40. p[ 7] = F32NAN;
  41. p[ 8] = F32NAN;
  42. p[ 9] = F32NAN;
  43. p[10] = F32NAN;
  44. p[11] = F32NAN;
  45. p[12] = F32NAN;
  46. p[13] = F32NAN;
  47. p[14] = F32NAN;
  48. p[15] = F32NAN;
  49. }
  50. if constexpr (sizeof(F) == 8)
  51. {
  52. uint64* p = (uint64*)&m00;
  53. p[ 0] = F64NAN;
  54. p[ 1] = F64NAN;
  55. p[ 2] = F64NAN;
  56. p[ 3] = F64NAN;
  57. p[ 4] = F64NAN;
  58. p[ 5] = F64NAN;
  59. p[ 6] = F64NAN;
  60. p[ 7] = F64NAN;
  61. p[ 8] = F64NAN;
  62. p[ 9] = F64NAN;
  63. p[10] = F64NAN;
  64. p[11] = F64NAN;
  65. p[12] = F64NAN;
  66. p[13] = F64NAN;
  67. p[14] = F64NAN;
  68. p[15] = F64NAN;
  69. }
  70. }
  71. #else
  72. ILINE Matrix44_tpl(){};
  73. #endif
  74. //initialize with zeros
  75. ILINE Matrix44_tpl(type_zero)
  76. {
  77. m00 = 0;
  78. m01 = 0;
  79. m02 = 0;
  80. m03 = 0;
  81. m10 = 0;
  82. m11 = 0;
  83. m12 = 0;
  84. m13 = 0;
  85. m20 = 0;
  86. m21 = 0;
  87. m22 = 0;
  88. m23 = 0;
  89. m30 = 0;
  90. m31 = 0;
  91. m32 = 0;
  92. m33 = 0;
  93. }
  94. //ASSIGNMENT OPERATOR of identical Matrix44 types.
  95. //The assignment operator has precedence over assignment constructor
  96. //Matrix44 m; m=m44;
  97. ILINE Matrix44_tpl<F>& operator = (const Matrix44_tpl<F>& m)
  98. {
  99. assert(m.IsValid());
  100. m00 = m.m00;
  101. m01 = m.m01;
  102. m02 = m.m02;
  103. m03 = m.m03;
  104. m10 = m.m10;
  105. m11 = m.m11;
  106. m12 = m.m12;
  107. m13 = m.m13;
  108. m20 = m.m20;
  109. m21 = m.m21;
  110. m22 = m.m22;
  111. m23 = m.m23;
  112. m30 = m.m30;
  113. m31 = m.m31;
  114. m32 = m.m32;
  115. m33 = m.m33;
  116. return *this;
  117. }
  118. //--------------------------------------------------------------------
  119. //---- implementation of the constructors ---
  120. //--------------------------------------------------------------------
  121. ILINE Matrix44_tpl<F>(F v00, F v01, F v02, F v03,
  122. F v10, F v11, F v12, F v13,
  123. F v20, F v21, F v22, F v23,
  124. F v30, F v31, F v32, F v33)
  125. {
  126. m00 = v00;
  127. m01 = v01;
  128. m02 = v02;
  129. m03 = v03;
  130. m10 = v10;
  131. m11 = v11;
  132. m12 = v12;
  133. m13 = v13;
  134. m20 = v20;
  135. m21 = v21;
  136. m22 = v22;
  137. m23 = v23;
  138. m30 = v30;
  139. m31 = v31;
  140. m32 = v32;
  141. m33 = v33;
  142. }
  143. //CONSTRUCTOR for different types. It converts a Matrix33 into a Matrix44.
  144. //Matrix44(m33);
  145. ILINE Matrix44_tpl<F>(const Matrix33_tpl<F>&m)
  146. {
  147. assert(m.IsValid());
  148. m00 = m.m00;
  149. m01 = m.m01;
  150. m02 = m.m02;
  151. m03 = 0;
  152. m10 = m.m10;
  153. m11 = m.m11;
  154. m12 = m.m12;
  155. m13 = 0;
  156. m20 = m.m20;
  157. m21 = m.m21;
  158. m22 = m.m22;
  159. m23 = 0;
  160. m30 = 0;
  161. m31 = 0;
  162. m32 = 0;
  163. m33 = 1;
  164. }
  165. //CONSTRUCTOR for different types. It converts a Matrix33 into a Matrix44 and also converts between double/float.
  166. //Matrix44(Matrix33);
  167. template<class F1>
  168. ILINE Matrix44_tpl<F>(const Matrix33_tpl<F1>&m)
  169. {
  170. assert(m.IsValid());
  171. m00 = F(m.m00);
  172. m01 = F(m.m01);
  173. m02 = F(m.m02);
  174. m03 = 0;
  175. m10 = F(m.m10);
  176. m11 = F(m.m11);
  177. m12 = F(m.m12);
  178. m13 = 0;
  179. m20 = F(m.m20);
  180. m21 = F(m.m21);
  181. m22 = F(m.m22);
  182. m23 = 0;
  183. m30 = 0;
  184. m31 = 0;
  185. m32 = 0;
  186. m33 = 1;
  187. }
  188. //CONSTRUCTOR for different types. It converts a Matrix34 into a Matrix44.
  189. //Matrix44(m34);
  190. ILINE Matrix44_tpl<F>(const Matrix34_tpl<F>&m)
  191. {
  192. assert(m.IsValid());
  193. m00 = m.m00;
  194. m01 = m.m01;
  195. m02 = m.m02;
  196. m03 = m.m03;
  197. m10 = m.m10;
  198. m11 = m.m11;
  199. m12 = m.m12;
  200. m13 = m.m13;
  201. m20 = m.m20;
  202. m21 = m.m21;
  203. m22 = m.m22;
  204. m23 = m.m23;
  205. m30 = 0;
  206. m31 = 0;
  207. m32 = 0;
  208. m33 = 1;
  209. }
  210. //CONSTRUCTOR for different types. It converts a Matrix34 into a Matrix44 and also converts between double/float.
  211. //Matrix44(Matrix34);
  212. template<class F1>
  213. ILINE Matrix44_tpl<F>(const Matrix34_tpl<F1>&m)
  214. {
  215. assert(m.IsValid());
  216. m00 = F(m.m00);
  217. m01 = F(m.m01);
  218. m02 = F(m.m02);
  219. m03 = F(m.m03);
  220. m10 = F(m.m10);
  221. m11 = F(m.m11);
  222. m12 = F(m.m12);
  223. m13 = F(m.m13);
  224. m20 = F(m.m20);
  225. m21 = F(m.m21);
  226. m22 = F(m.m22);
  227. m23 = F(m.m23);
  228. m30 = 0;
  229. m31 = 0;
  230. m32 = 0;
  231. m33 = 1;
  232. }
  233. //CONSTRUCTOR for identical types
  234. //Matrix44 m=m44;
  235. ILINE Matrix44_tpl<F>(const Matrix44_tpl<F>&m)
  236. {
  237. assert(m.IsValid());
  238. m00 = m.m00;
  239. m01 = m.m01;
  240. m02 = m.m02;
  241. m03 = m.m03;
  242. m10 = m.m10;
  243. m11 = m.m11;
  244. m12 = m.m12;
  245. m13 = m.m13;
  246. m20 = m.m20;
  247. m21 = m.m21;
  248. m22 = m.m22;
  249. m23 = m.m23;
  250. m30 = m.m30;
  251. m31 = m.m31;
  252. m32 = m.m32;
  253. m33 = m.m33;
  254. }
  255. //---------------------------------------------------------------------
  256. //! multiply all m1 matrix's values by f and return the matrix
  257. friend ILINE Matrix44_tpl<F> operator * (const Matrix44_tpl<F>& m, const f32 f)
  258. {
  259. assert(m.IsValid());
  260. Matrix44_tpl<F> r;
  261. r.m00 = m.m00 * f;
  262. r.m01 = m.m01 * f;
  263. r.m02 = m.m02 * f;
  264. r.m03 = m.m03 * f;
  265. r.m10 = m.m10 * f;
  266. r.m11 = m.m11 * f;
  267. r.m12 = m.m12 * f;
  268. r.m13 = m.m13 * f;
  269. r.m20 = m.m20 * f;
  270. r.m21 = m.m21 * f;
  271. r.m22 = m.m22 * f;
  272. r.m23 = m.m23 * f;
  273. r.m30 = m.m30 * f;
  274. r.m31 = m.m31 * f;
  275. r.m32 = m.m32 * f;
  276. r.m33 = m.m33 * f;
  277. return r;
  278. }
  279. //! add all m matrix's values and return the matrix
  280. friend ILINE Matrix44_tpl<F> operator + (const Matrix44_tpl<F>& mm0, const Matrix44_tpl<F>& mm1)
  281. {
  282. assert(mm0.IsValid());
  283. assert(mm1.IsValid());
  284. Matrix44_tpl<F> r;
  285. r.m00 = mm0.m00 + mm1.m00;
  286. r.m01 = mm0.m01 + mm1.m01;
  287. r.m02 = mm0.m02 + mm1.m02;
  288. r.m03 = mm0.m03 + mm1.m03;
  289. r.m10 = mm0.m10 + mm1.m10;
  290. r.m11 = mm0.m11 + mm1.m11;
  291. r.m12 = mm0.m12 + mm1.m12;
  292. r.m13 = mm0.m13 + mm1.m13;
  293. r.m20 = mm0.m20 + mm1.m20;
  294. r.m21 = mm0.m21 + mm1.m21;
  295. r.m22 = mm0.m22 + mm1.m22;
  296. r.m23 = mm0.m23 + mm1.m23;
  297. r.m30 = mm0.m30 + mm1.m30;
  298. r.m31 = mm0.m31 + mm1.m31;
  299. r.m32 = mm0.m32 + mm1.m32;
  300. r.m33 = mm0.m33 + mm1.m33;
  301. return r;
  302. }
  303. ILINE void SetIdentity()
  304. {
  305. m00 = 1;
  306. m01 = 0;
  307. m02 = 0;
  308. m03 = 0;
  309. m10 = 0;
  310. m11 = 1;
  311. m12 = 0;
  312. m13 = 0;
  313. m20 = 0;
  314. m21 = 0;
  315. m22 = 1;
  316. m23 = 0;
  317. m30 = 0;
  318. m31 = 0;
  319. m32 = 0;
  320. m33 = 1;
  321. }
  322. ILINE Matrix44_tpl(type_identity) { SetIdentity(); }
  323. ILINE void Transpose()
  324. {
  325. Matrix44_tpl<F> tmp = *this;
  326. m00 = tmp.m00;
  327. m01 = tmp.m10;
  328. m02 = tmp.m20;
  329. m03 = tmp.m30;
  330. m10 = tmp.m01;
  331. m11 = tmp.m11;
  332. m12 = tmp.m21;
  333. m13 = tmp.m31;
  334. m20 = tmp.m02;
  335. m21 = tmp.m12;
  336. m22 = tmp.m22;
  337. m23 = tmp.m32;
  338. m30 = tmp.m03;
  339. m31 = tmp.m13;
  340. m32 = tmp.m23;
  341. m33 = tmp.m33;
  342. }
  343. ILINE Matrix44_tpl<F> GetTransposed() const
  344. {
  345. Matrix44_tpl<F> tmp;
  346. tmp.m00 = m00;
  347. tmp.m01 = m10;
  348. tmp.m02 = m20;
  349. tmp.m03 = m30;
  350. tmp.m10 = m01;
  351. tmp.m11 = m11;
  352. tmp.m12 = m21;
  353. tmp.m13 = m31;
  354. tmp.m20 = m02;
  355. tmp.m21 = m12;
  356. tmp.m22 = m22;
  357. tmp.m23 = m32;
  358. tmp.m30 = m03;
  359. tmp.m31 = m13;
  360. tmp.m32 = m23;
  361. tmp.m33 = m33;
  362. return tmp;
  363. }
  364. /*!
  365. *
  366. * Calculate a real inversion of a Matrix44.
  367. *
  368. * Uses Cramer's Rule which is faster (branchless) but numerically more unstable
  369. * than other methods like Gaussian Elimination.
  370. *
  371. * Example 1:
  372. * Matrix44 im44; im44.Invert();
  373. *
  374. * Example 2:
  375. * Matrix44 im44 = m33.GetInverted();
  376. */
  377. void Invert(void)
  378. {
  379. F tmp[12];
  380. Matrix44_tpl<F> m = *this;
  381. // Calculate pairs for first 8 elements (cofactors)
  382. tmp[0] = m.m22 * m.m33;
  383. tmp[1] = m.m32 * m.m23;
  384. tmp[2] = m.m12 * m.m33;
  385. tmp[3] = m.m32 * m.m13;
  386. tmp[4] = m.m12 * m.m23;
  387. tmp[5] = m.m22 * m.m13;
  388. tmp[6] = m.m02 * m.m33;
  389. tmp[7] = m.m32 * m.m03;
  390. tmp[8] = m.m02 * m.m23;
  391. tmp[9] = m.m22 * m.m03;
  392. tmp[10] = m.m02 * m.m13;
  393. tmp[11] = m.m12 * m.m03;
  394. // Calculate first 8 elements (cofactors)
  395. m00 = tmp[0] * m.m11 + tmp[3] * m.m21 + tmp[ 4] * m.m31;
  396. m00 -= tmp[1] * m.m11 + tmp[2] * m.m21 + tmp[ 5] * m.m31;
  397. m01 = tmp[1] * m.m01 + tmp[6] * m.m21 + tmp[ 9] * m.m31;
  398. m01 -= tmp[0] * m.m01 + tmp[7] * m.m21 + tmp[ 8] * m.m31;
  399. m02 = tmp[2] * m.m01 + tmp[7] * m.m11 + tmp[10] * m.m31;
  400. m02 -= tmp[3] * m.m01 + tmp[6] * m.m11 + tmp[11] * m.m31;
  401. m03 = tmp[5] * m.m01 + tmp[8] * m.m11 + tmp[11] * m.m21;
  402. m03 -= tmp[4] * m.m01 + tmp[9] * m.m11 + tmp[10] * m.m21;
  403. m10 = tmp[1] * m.m10 + tmp[2] * m.m20 + tmp[ 5] * m.m30;
  404. m10 -= tmp[0] * m.m10 + tmp[3] * m.m20 + tmp[ 4] * m.m30;
  405. m11 = tmp[0] * m.m00 + tmp[7] * m.m20 + tmp[ 8] * m.m30;
  406. m11 -= tmp[1] * m.m00 + tmp[6] * m.m20 + tmp[ 9] * m.m30;
  407. m12 = tmp[3] * m.m00 + tmp[6] * m.m10 + tmp[11] * m.m30;
  408. m12 -= tmp[2] * m.m00 + tmp[7] * m.m10 + tmp[10] * m.m30;
  409. m13 = tmp[4] * m.m00 + tmp[9] * m.m10 + tmp[10] * m.m20;
  410. m13 -= tmp[5] * m.m00 + tmp[8] * m.m10 + tmp[11] * m.m20;
  411. // Calculate pairs for second 8 elements (cofactors)
  412. tmp[ 0] = m.m20 * m.m31;
  413. tmp[ 1] = m.m30 * m.m21;
  414. tmp[ 2] = m.m10 * m.m31;
  415. tmp[ 3] = m.m30 * m.m11;
  416. tmp[ 4] = m.m10 * m.m21;
  417. tmp[ 5] = m.m20 * m.m11;
  418. tmp[ 6] = m.m00 * m.m31;
  419. tmp[ 7] = m.m30 * m.m01;
  420. tmp[ 8] = m.m00 * m.m21;
  421. tmp[ 9] = m.m20 * m.m01;
  422. tmp[10] = m.m00 * m.m11;
  423. tmp[11] = m.m10 * m.m01;
  424. // Calculate second 8 elements (cofactors)
  425. m20 = tmp[ 0] * m.m13 + tmp[ 3] * m.m23 + tmp[ 4] * m.m33;
  426. m20 -= tmp[ 1] * m.m13 + tmp[ 2] * m.m23 + tmp[ 5] * m.m33;
  427. m21 = tmp[ 1] * m.m03 + tmp[ 6] * m.m23 + tmp[ 9] * m.m33;
  428. m21 -= tmp[ 0] * m.m03 + tmp[ 7] * m.m23 + tmp[ 8] * m.m33;
  429. m22 = tmp[ 2] * m.m03 + tmp[ 7] * m.m13 + tmp[10] * m.m33;
  430. m22 -= tmp[ 3] * m.m03 + tmp[ 6] * m.m13 + tmp[11] * m.m33;
  431. m23 = tmp[ 5] * m.m03 + tmp[ 8] * m.m13 + tmp[11] * m.m23;
  432. m23 -= tmp[ 4] * m.m03 + tmp[ 9] * m.m13 + tmp[10] * m.m23;
  433. m30 = tmp[ 2] * m.m22 + tmp[ 5] * m.m32 + tmp[ 1] * m.m12;
  434. m30 -= tmp[ 4] * m.m32 + tmp[ 0] * m.m12 + tmp[ 3] * m.m22;
  435. m31 = tmp[ 8] * m.m32 + tmp[ 0] * m.m02 + tmp[ 7] * m.m22;
  436. m31 -= tmp[ 6] * m.m22 + tmp[ 9] * m.m32 + tmp[ 1] * m.m02;
  437. m32 = tmp[ 6] * m.m12 + tmp[11] * m.m32 + tmp[ 3] * m.m02;
  438. m32 -= tmp[10] * m.m32 + tmp[ 2] * m.m02 + tmp[ 7] * m.m12;
  439. m33 = tmp[10] * m.m22 + tmp[ 4] * m.m02 + tmp[ 9] * m.m12;
  440. m33 -= tmp[ 8] * m.m12 + tmp[11] * m.m22 + tmp[ 5] * m.m02;
  441. // Calculate determinant
  442. F det = (m.m00 * m00 + m.m10 * m01 + m.m20 * m02 + m.m30 * m03);
  443. //if (fabs_tpl(det)<0.0001f) assert(0);
  444. // Divide the cofactor-matrix by the determinant
  445. F idet = (F)1.0 / det;
  446. m00 *= idet;
  447. m01 *= idet;
  448. m02 *= idet;
  449. m03 *= idet;
  450. m10 *= idet;
  451. m11 *= idet;
  452. m12 *= idet;
  453. m13 *= idet;
  454. m20 *= idet;
  455. m21 *= idet;
  456. m22 *= idet;
  457. m23 *= idet;
  458. m30 *= idet;
  459. m31 *= idet;
  460. m32 *= idet;
  461. m33 *= idet;
  462. }
  463. ILINE Matrix44_tpl<F> GetInverted() const
  464. {
  465. Matrix44_tpl<F> dst = *this;
  466. dst.Invert();
  467. return dst;
  468. }
  469. ILINE f32 Determinant() const
  470. {
  471. //determinant is ambiguous: only the upper-left-submatrix's determinant is calculated
  472. return (m00 * m11 * m22) + (m01 * m12 * m20) + (m02 * m10 * m21) - (m02 * m11 * m20) - (m00 * m12 * m21) - (m01 * m10 * m22);
  473. }
  474. //! transform a vector
  475. ILINE Vec3 TransformVector(const Vec3& b) const
  476. {
  477. assert(b.IsValid());
  478. Vec3 v;
  479. v.x = m00 * b.x + m01 * b.y + m02 * b.z;
  480. v.y = m10 * b.x + m11 * b.y + m12 * b.z;
  481. v.z = m20 * b.x + m21 * b.y + m22 * b.z;
  482. return v;
  483. }
  484. //! transform a point
  485. ILINE Vec3 TransformPoint(const Vec3& b) const
  486. {
  487. assert(b.IsValid());
  488. Vec3 v;
  489. v.x = m00 * b.x + m01 * b.y + m02 * b.z + m03;
  490. v.y = m10 * b.x + m11 * b.y + m12 * b.z + m13;
  491. v.z = m20 * b.x + m21 * b.y + m22 * b.z + m23;
  492. return v;
  493. }
  494. //--------------------------------------------------------------------------------
  495. //---- helper functions to access matrix-members ------------
  496. //--------------------------------------------------------------------------------
  497. ILINE F* GetData() { return &m00; }
  498. ILINE const F* GetData() const { return &m00; }
  499. ILINE F operator () (uint32 i, uint32 j) const { assert ((i < 4) && (j < 4)); F* p_data = (F*)(&m00); return p_data[i * 4 + j]; }
  500. ILINE F& operator () (uint32 i, uint32 j) { assert ((i < 4) && (j < 4)); F* p_data = (F*)(&m00); return p_data[i * 4 + j]; }
  501. ILINE void SetRow(int i, const Vec3_tpl<F>& v) { assert(i < 4); F* p = (F*)(&m00); p[0 + 4 * i] = v.x; p[1 + 4 * i] = v.y; p[2 + 4 * i] = v.z; }
  502. ILINE void SetRow4(int i, const Vec4& v) { assert(i < 4); F* p = (F*)(&m00); p[0 + 4 * i] = v.x; p[1 + 4 * i] = v.y; p[2 + 4 * i] = v.z; p[3 + 4 * i] = v.w; }
  503. ILINE const Vec3_tpl<F>& GetRow(int i) const { assert(i < 4); return *(const Vec3_tpl<F>*)(&m00 + 4 * i); }
  504. ILINE void SetColumn(int i, const Vec3_tpl<F>& v) { assert(i < 4); F* p = (F*)(&m00); p[i + 4 * 0] = v.x; p[i + 4 * 1] = v.y; p[i + 4 * 2] = v.z; }
  505. ILINE Vec3_tpl<F> GetColumn(int i) const { assert(i < 4); F* p = (F*)(&m00); return Vec3(p[i + 4 * 0], p[i + 4 * 1], p[i + 4 * 2]); }
  506. ILINE Vec4 GetColumn4(int i) const { assert(i < 4); F* p = (F*)(&m00); return Vec4(p[i + 4 * 0], p[i + 4 * 1], p[i + 4 * 2], p[i + 4 * 3]); }
  507. ILINE Vec3 GetTranslation() const { return Vec3(m03, m13, m23); }
  508. ILINE void SetTranslation(const Vec3& t) { m03 = t.x; m13 = t.y; m23 = t.z; }
  509. bool IsValid() const
  510. {
  511. if (!NumberValid(m00))
  512. {
  513. return false;
  514. }
  515. if (!NumberValid(m01))
  516. {
  517. return false;
  518. }
  519. if (!NumberValid(m02))
  520. {
  521. return false;
  522. }
  523. if (!NumberValid(m03))
  524. {
  525. return false;
  526. }
  527. if (!NumberValid(m10))
  528. {
  529. return false;
  530. }
  531. if (!NumberValid(m11))
  532. {
  533. return false;
  534. }
  535. if (!NumberValid(m12))
  536. {
  537. return false;
  538. }
  539. if (!NumberValid(m13))
  540. {
  541. return false;
  542. }
  543. if (!NumberValid(m20))
  544. {
  545. return false;
  546. }
  547. if (!NumberValid(m21))
  548. {
  549. return false;
  550. }
  551. if (!NumberValid(m22))
  552. {
  553. return false;
  554. }
  555. if (!NumberValid(m23))
  556. {
  557. return false;
  558. }
  559. if (!NumberValid(m30))
  560. {
  561. return false;
  562. }
  563. if (!NumberValid(m31))
  564. {
  565. return false;
  566. }
  567. if (!NumberValid(m32))
  568. {
  569. return false;
  570. }
  571. if (!NumberValid(m33))
  572. {
  573. return false;
  574. }
  575. return true;
  576. }
  577. static bool IsEquivalent(const Matrix44_tpl<F>& m0, const Matrix44_tpl<F>& m1, F e = VEC_EPSILON)
  578. {
  579. return (
  580. (fabs_tpl(m0.m00 - m1.m00) <= e) && (fabs_tpl(m0.m01 - m1.m01) <= e) && (fabs_tpl(m0.m02 - m1.m02) <= e) && (fabs_tpl(m0.m03 - m1.m03) <= e) &&
  581. (fabs_tpl(m0.m10 - m1.m10) <= e) && (fabs_tpl(m0.m11 - m1.m11) <= e) && (fabs_tpl(m0.m12 - m1.m12) <= e) && (fabs_tpl(m0.m13 - m1.m13) <= e) &&
  582. (fabs_tpl(m0.m20 - m1.m20) <= e) && (fabs_tpl(m0.m21 - m1.m21) <= e) && (fabs_tpl(m0.m22 - m1.m22) <= e) && (fabs_tpl(m0.m23 - m1.m23) <= e) &&
  583. (fabs_tpl(m0.m30 - m1.m30) <= e) && (fabs_tpl(m0.m31 - m1.m31) <= e) && (fabs_tpl(m0.m32 - m1.m32) <= e) && (fabs_tpl(m0.m33 - m1.m33) <= e)
  584. );
  585. }
  586. };
  587. ///////////////////////////////////////////////////////////////////////////////
  588. // Typedefs //
  589. ///////////////////////////////////////////////////////////////////////////////
  590. typedef Matrix44_tpl<f32> Matrix44; //always 32 bit
  591. //----------------------------------------------------------------------------------
  592. //----------------------------------------------------------------------------------
  593. //----------------------------------------------------------------------------------
  594. //------------- implementation of Matrix44 ------------------------------
  595. //----------------------------------------------------------------------------------
  596. //----------------------------------------------------------------------------------
  597. //----------------------------------------------------------------------------------
  598. /*!
  599. * Implements the multiplication operator: Matrix44=Matrix44*Matrix33
  600. *
  601. * Matrix44 and Matrix33 are specified in collumn order.
  602. * AxB = rotation B followed by rotation A.
  603. * This operation takes 48 mults and 24 adds.
  604. *
  605. * Example:
  606. * Matrix33 m34=CreateRotationX33(1.94192f);;
  607. * Matrix44 m44=CreateRotationZ33(3.14192f);
  608. * Matrix44 result=m44*m33;
  609. */
  610. template<class F1, class F2>
  611. ILINE Matrix44_tpl<F1> operator * (const Matrix44_tpl<F1>& l, const Matrix33_tpl<F2>& r)
  612. {
  613. assert(l.IsValid());
  614. assert(r.IsValid());
  615. Matrix44_tpl<F1> m;
  616. m.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20;
  617. m.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20;
  618. m.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20;
  619. m.m30 = l.m30 * r.m00 + l.m31 * r.m10 + l.m32 * r.m20;
  620. m.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21;
  621. m.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21;
  622. m.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21;
  623. m.m31 = l.m30 * r.m01 + l.m31 * r.m11 + l.m32 * r.m21;
  624. m.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22;
  625. m.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22;
  626. m.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22;
  627. m.m32 = l.m30 * r.m02 + l.m31 * r.m12 + l.m32 * r.m22;
  628. m.m03 = l.m03;
  629. m.m13 = l.m13;
  630. m.m23 = l.m23;
  631. m.m33 = l.m33;
  632. return m;
  633. }
  634. /*!
  635. * Implements the multiplication operator: Matrix44=Matrix44*Matrix34
  636. *
  637. * Matrix44 and Matrix34 are specified in collumn order.
  638. * AxB = rotation B followed by rotation A.
  639. * This operation takes 48 mults and 36 adds.
  640. *
  641. * Example:
  642. * Matrix34 m34=CreateRotationX33(1.94192f);;
  643. * Matrix44 m44=CreateRotationZ33(3.14192f);
  644. * Matrix44 result=m44*m34;
  645. */
  646. template<class F>
  647. ILINE Matrix44_tpl<F> operator * (const Matrix44_tpl<F>& l, const Matrix34_tpl<F>& r)
  648. {
  649. assert(l.IsValid());
  650. assert(r.IsValid());
  651. Matrix44_tpl<F> m;
  652. m.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20;
  653. m.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20;
  654. m.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20;
  655. m.m30 = l.m30 * r.m00 + l.m31 * r.m10 + l.m32 * r.m20;
  656. m.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21;
  657. m.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21;
  658. m.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21;
  659. m.m31 = l.m30 * r.m01 + l.m31 * r.m11 + l.m32 * r.m21;
  660. m.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22;
  661. m.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22;
  662. m.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22;
  663. m.m32 = l.m30 * r.m02 + l.m31 * r.m12 + l.m32 * r.m22;
  664. m.m03 = l.m00 * r.m03 + l.m01 * r.m13 + l.m02 * r.m23 + l.m03;
  665. m.m13 = l.m10 * r.m03 + l.m11 * r.m13 + l.m12 * r.m23 + l.m13;
  666. m.m23 = l.m20 * r.m03 + l.m21 * r.m13 + l.m22 * r.m23 + l.m23;
  667. m.m33 = l.m30 * r.m03 + l.m31 * r.m13 + l.m32 * r.m23 + l.m33;
  668. return m;
  669. }
  670. /*!
  671. * Implements the multiplication operator: Matrix44=Matrix44*Matrix44
  672. *
  673. * Matrix44 and Matrix34 are specified in collumn order.
  674. * AxB = rotation B followed by rotation A.
  675. * This operation takes 48 mults and 36 adds.
  676. *
  677. * Example:
  678. * Matrix44 m44=CreateRotationX33(1.94192f);;
  679. * Matrix44 m44=CreateRotationZ33(3.14192f);
  680. * Matrix44 result=m44*m44;
  681. */
  682. template<class F1, class F2>
  683. ILINE Matrix44_tpl<F1> operator * (const Matrix44_tpl<F1>& l, const Matrix44_tpl<F2>& r)
  684. {
  685. assert(l.IsValid());
  686. assert(r.IsValid());
  687. Matrix44_tpl<F1> res;
  688. res.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20 + l.m03 * r.m30;
  689. res.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20 + l.m13 * r.m30;
  690. res.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20 + l.m23 * r.m30;
  691. res.m30 = l.m30 * r.m00 + l.m31 * r.m10 + l.m32 * r.m20 + l.m33 * r.m30;
  692. res.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21 + l.m03 * r.m31;
  693. res.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21 + l.m13 * r.m31;
  694. res.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21 + l.m23 * r.m31;
  695. res.m31 = l.m30 * r.m01 + l.m31 * r.m11 + l.m32 * r.m21 + l.m33 * r.m31;
  696. res.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22 + l.m03 * r.m32;
  697. res.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22 + l.m13 * r.m32;
  698. res.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22 + l.m23 * r.m32;
  699. res.m32 = l.m30 * r.m02 + l.m31 * r.m12 + l.m32 * r.m22 + l.m33 * r.m32;
  700. res.m03 = l.m00 * r.m03 + l.m01 * r.m13 + l.m02 * r.m23 + l.m03 * r.m33;
  701. res.m13 = l.m10 * r.m03 + l.m11 * r.m13 + l.m12 * r.m23 + l.m13 * r.m33;
  702. res.m23 = l.m20 * r.m03 + l.m21 * r.m13 + l.m22 * r.m23 + l.m23 * r.m33;
  703. res.m33 = l.m30 * r.m03 + l.m31 * r.m13 + l.m32 * r.m23 + l.m33 * r.m33;
  704. return res;
  705. }
  706. //post-multiply
  707. template<class F2>
  708. ILINE Vec4 operator*(const Matrix44_tpl<F2>& m, const Vec4& v)
  709. {
  710. assert(m.IsValid());
  711. assert(v.IsValid());
  712. return Vec4(v.x * m.m00 + v.y * m.m01 + v.z * m.m02 + v.w * m.m03,
  713. v.x * m.m10 + v.y * m.m11 + v.z * m.m12 + v.w * m.m13,
  714. v.x * m.m20 + v.y * m.m21 + v.z * m.m22 + v.w * m.m23,
  715. v.x * m.m30 + v.y * m.m31 + v.z * m.m32 + v.w * m.m33);
  716. }
  717. //pre-multiply
  718. template<class F2>
  719. ILINE Vec4 operator*(const Vec4& v, const Matrix44_tpl<F2>& m)
  720. {
  721. assert(m.IsValid());
  722. assert(v.IsValid());
  723. return Vec4(v.x * m.m00 + v.y * m.m10 + v.z * m.m20 + v.w * m.m30,
  724. v.x * m.m01 + v.y * m.m11 + v.z * m.m21 + v.w * m.m31,
  725. v.x * m.m02 + v.y * m.m12 + v.z * m.m22 + v.w * m.m32,
  726. v.x * m.m03 + v.y * m.m13 + v.z * m.m23 + v.w * m.m33);
  727. }
  728. #endif // CRYINCLUDE_CRYCOMMON_CRY_MATRIX44_H