Mat3.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. #ifndef ANKI_MATH_MAT3_H
  2. #define ANKI_MATH_MAT3_H
  3. #include "anki/math/CommonIncludes.h"
  4. namespace anki {
  5. /// @addtogroup Math
  6. /// @{
  7. /// 3x3 Matrix. Mainly used for rotations. It includes many helpful member
  8. /// functions. Its row major. The columns are the x,y,z axis
  9. template<typename T>
  10. class TMat3
  11. {
  12. /// @name Friends
  13. /// @{
  14. template<typename Y>
  15. friend TMat3<Y> operator+(Y f, const TMat3<Y>& m3);
  16. template<typename Y>
  17. friend TMat3<Y> operator-(Y f, const TMat3<Y>& m3);
  18. template<typename Y>
  19. friend TMat3<Y> operator*(Y f, const TMat3<Y>& m3);
  20. template<typename Y>
  21. friend TMat3<Y> operator/(Y f, const TMat3<Y>& m3);
  22. /// @}
  23. public:
  24. /// @name Constructors
  25. /// @{
  26. explicit TMat3()
  27. {}
  28. explicit TMat3(const T f)
  29. {
  30. for(U i = 0; i < 9; i++)
  31. {
  32. arr1[i] = f;
  33. }
  34. }
  35. explicit TMat3(const T m00, const T m01, const T m02,
  36. const T m10, const T m11, const T m12,
  37. const T m20, const T m21, const T m22)
  38. {
  39. TMat3& m = *this;
  40. m(0, 0) = m00;
  41. m(0, 1) = m01;
  42. m(0, 2) = m02;
  43. m(1, 0) = m10;
  44. m(1, 1) = m11;
  45. m(1, 2) = m12;
  46. m(2, 0) = m20;
  47. m(2, 1) = m21;
  48. m(2, 2) = m22;
  49. }
  50. explicit TMat3(const T arr[])
  51. {
  52. for(U i = 0; i < 9; i++)
  53. {
  54. arr1[i] = arr[i];
  55. }
  56. }
  57. TMat3(const TMat3& b)
  58. {
  59. for(U i = 0; i < 9; i++)
  60. {
  61. arr1[i] = b.arr1[i];
  62. }
  63. }
  64. /// TQuat to TMat3. 12 muls, 12 adds
  65. explicit TMat3(const TQuat<T>& q)
  66. {
  67. TMat3& m = *this;
  68. // If length is > 1 + 0.002 or < 1 - 0.002 then not normalized quat
  69. ANKI_ASSERT(fabs(1.0 - q.getLength()) <= 0.002);
  70. T xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
  71. xs = q.x() + q.x();
  72. ys = q.y() + q.y();
  73. zs = q.z() + q.z();
  74. wx = q.w() * xs;
  75. wy = q.w() * ys;
  76. wz = q.w() * zs;
  77. xx = q.x() * xs;
  78. xy = q.x() * ys;
  79. xz = q.x() * zs;
  80. yy = q.y() * ys;
  81. yz = q.y() * zs;
  82. zz = q.z() * zs;
  83. m(0, 0) = 1.0 - (yy + zz);
  84. m(0, 1) = xy - wz;
  85. m(0, 2) = xz + wy;
  86. m(1, 0) = xy + wz;
  87. m(1, 1) = 1.0 - (xx + zz);
  88. m(1, 2) = yz - wx;
  89. m(2, 0) = xz - wy;
  90. m(2, 1) = yz + wx;
  91. m(2, 2) = 1.0 - (xx + yy);
  92. }
  93. explicit TMat3(const TEuler<T>& e)
  94. {
  95. TMat3& m = *this;
  96. T ch, sh, ca, sa, cb, sb;
  97. sinCos(e.y(), sh, ch);
  98. sinCos(e.z(), sa, ca);
  99. sinCos(e.x(), sb, cb);
  100. m(0, 0) = ch * ca;
  101. m(0, 1) = sh * sb - ch * sa * cb;
  102. m(0, 2) = ch * sa * sb + sh * cb;
  103. m(1, 0) = sa;
  104. m(1, 1) = ca * cb;
  105. m(1, 2) = -ca * sb;
  106. m(2, 0) = -sh * ca;
  107. m(2, 1) = sh * sa * cb + ch * sb;
  108. m(2, 2) = -sh * sa * sb + ch * cb;
  109. }
  110. explicit TMat3(const TAxisang<T>& axisang)
  111. {
  112. TMat3& m = *this;
  113. // Not normalized axis
  114. ANKI_ASSERT(isZero<T>(1.0 - axisang.getAxis().getLength()));
  115. T c, s;
  116. sinCos(axisang.getAngle(), s, c);
  117. T t = 1.0 - c;
  118. const TVec3<T>& axis = axisang.getAxis();
  119. m(0, 0) = c + axis.x() * axis.x() * t;
  120. m(1, 1) = c + axis.y() * axis.y() * t;
  121. m(2, 2) = c + axis.z() * axis.z() * t;
  122. T tmp1 = axis.x() * axis.y() * t;
  123. T tmp2 = axis.z() * s;
  124. m(1, 0) = tmp1 + tmp2;
  125. m(0, 1) = tmp1 - tmp2;
  126. tmp1 = axis.x() * axis.z() * t;
  127. tmp2 = axis.y() * s;
  128. m(2, 0) = tmp1 - tmp2;
  129. m(0, 2) = tmp1 + tmp2;
  130. tmp1 = axis.y() * axis.z() * t;
  131. tmp2 = axis.x() * s;
  132. m(2, 1) = tmp1 + tmp2;
  133. m(1, 2) = tmp1 - tmp2;
  134. }
  135. /// @}
  136. /// @name Accessors
  137. /// @{
  138. T& operator()(const U i, const U j)
  139. {
  140. return arr2[i][j];
  141. }
  142. const T& operator()(const U i, const U j) const
  143. {
  144. return arr2[i][j];
  145. }
  146. T& operator[](const U i)
  147. {
  148. return arr1[i];
  149. }
  150. const T& operator[](const U i) const
  151. {
  152. return arr1[i];
  153. }
  154. /// @}
  155. /// @name Operators with same type
  156. /// @{
  157. TMat3& operator=(const TMat3& b)
  158. {
  159. for(U i = 0; i < 9; i++)
  160. {
  161. arr1[i] = b.arr1[i];
  162. }
  163. return (*this);
  164. }
  165. TMat3 operator+(const TMat3& b) const
  166. {
  167. TMat3<T> c;
  168. for(U i = 0; i < 9; i++)
  169. {
  170. c.arr1[i] = arr1[i] + b.arr1[i];
  171. }
  172. return c;
  173. }
  174. TMat3& operator+=(const TMat3& b)
  175. {
  176. for(U i = 0; i < 9; i++)
  177. {
  178. arr1[i] += b.arr1[i];
  179. }
  180. return (*this);
  181. }
  182. TMat3 operator-(const TMat3& b) const
  183. {
  184. TMat3 c;
  185. for(U i = 0; i < 9; i++)
  186. {
  187. c.arr1[i] = arr1[i] - b.arr1[i];
  188. }
  189. return c;
  190. }
  191. TMat3& operator-=(const TMat3& b)
  192. {
  193. for(U i = 0; i < 9; i++)
  194. {
  195. arr1[i] -= b.arr1[i];
  196. }
  197. return (*this);
  198. }
  199. /// @note 27 muls, 18 adds
  200. TMat3 operator*(const TMat3& b) const
  201. {
  202. TMat3 c;
  203. const TMat3& a = *this;
  204. c(0, 0) = a(0, 0) * b(0, 0) + a(0, 1) * b(1, 0) + a(0, 2) * b(2, 0);
  205. c(0, 1) = a(0, 0) * b(0, 1) + a(0, 1) * b(1, 1) + a(0, 2) * b(2, 1);
  206. c(0, 2) = a(0, 0) * b(0, 2) + a(0, 1) * b(1, 2) + a(0, 2) * b(2, 2);
  207. c(1, 0) = a(1, 0) * b(0, 0) + a(1, 1) * b(1, 0) + a(1, 2) * b(2, 0);
  208. c(1, 1) = a(1, 0) * b(0, 1) + a(1, 1) * b(1, 1) + a(1, 2) * b(2, 1);
  209. c(1, 2) = a(1, 0) * b(0, 2) + a(1, 1) * b(1, 2) + a(1, 2) * b(2, 2);
  210. c(2, 0) = a(2, 0) * b(0, 0) + a(2, 1) * b(1, 0) + a(2, 2) * b(2, 0);
  211. c(2, 1) = a(2, 0) * b(0, 1) + a(2, 1) * b(1, 1) + a(2, 2) * b(2, 1);
  212. c(2, 2) = a(2, 0) * b(0, 2) + a(2, 1) * b(1, 2) + a(2, 2) * b(2, 2);
  213. return c;
  214. }
  215. TMat3& operator*=(const TMat3& b)
  216. {
  217. (*this) = (*this) * b;
  218. return (*this);
  219. }
  220. Bool operator==(const TMat3& b) const
  221. {
  222. for(U i = 0; i < 9; i++)
  223. {
  224. if(!isZero<T>(arr1[i] - b.arr1[i]))
  225. {
  226. return false;
  227. }
  228. }
  229. return true;
  230. }
  231. Bool operator!=(const TMat3& b) const
  232. {
  233. for(U i = 0; i < 9; i++)
  234. {
  235. if(!isZero<T>(arr1[i] - b.arr1[i]))
  236. {
  237. return true;
  238. }
  239. }
  240. return false;
  241. }
  242. /// @}
  243. /// @name Operators with T
  244. /// @{
  245. TMat3 operator+(const T f) const
  246. {
  247. TMat3 c;
  248. for(U i = 0; i < 9; i++)
  249. {
  250. c.arr1[i] = arr1[i] + f;
  251. }
  252. return c;
  253. }
  254. TMat3& operator+=(const T f)
  255. {
  256. for(U i = 0; i < 9; i++)
  257. {
  258. arr1[i] += f;
  259. }
  260. return (*this);
  261. }
  262. TMat3 operator-(const T f) const
  263. {
  264. TMat3 c;
  265. for(U i = 0; i < 9; i++)
  266. {
  267. c.arr1[i] = arr1[i] - f;
  268. }
  269. return c;
  270. }
  271. TMat3& operator-=(const T f)
  272. {
  273. for(U i = 0; i < 9; i++)
  274. {
  275. arr1[i] -= f;
  276. }
  277. return (*this);
  278. }
  279. TMat3 operator*(const T f) const
  280. {
  281. TMat3 c;
  282. for(U i = 0; i < 9; i++)
  283. {
  284. c.arr1[i] = arr1[i] * f;
  285. }
  286. return c;
  287. }
  288. TMat3& operator*=(const T f)
  289. {
  290. for(U i = 0; i < 9; i++)
  291. {
  292. arr1[i] *= f;
  293. }
  294. return (*this);
  295. }
  296. TMat3 operator/(const T f) const
  297. {
  298. TMat3 c;
  299. for(U i = 0; i < 9; i++)
  300. {
  301. c.arr1[i] = arr1[i] / f;
  302. }
  303. return c;
  304. }
  305. TMat3& operator/=(const T f)
  306. {
  307. for(U i = 0; i < 9; i++)
  308. {
  309. arr1[i] /= f;
  310. }
  311. return (*this);
  312. }
  313. /// @}
  314. /// @name Operators with others
  315. /// @{
  316. /// TVec3<T>(dot(row0 * b), dot(row1 * b), dot(row2 * b)). 9 muls, 6 adds
  317. TVec3<T> operator*(const TVec3<T>& b) const
  318. {
  319. const TMat3& m = *this;
  320. return TVec3<T>(
  321. m(0, 0) * b.x() + m(0, 1) * b.y() + m(0, 2) * b.z(),
  322. m(1, 0) * b.x() + m(1, 1) * b.y() + m(1, 2) * b.z(),
  323. m(2, 0) * b.x() + m(2, 1) * b.y() + m(2, 2) * b.z());
  324. }
  325. /// @}
  326. /// @name Other
  327. /// @{
  328. void setRows(const TVec3<T>& a, const TVec3<T>& b, const TVec3<T>& c)
  329. {
  330. setRow(0, a);
  331. setRow(1, b);
  332. setRow(2, c);
  333. }
  334. void setRow(const U i, const TVec3<T>& v)
  335. {
  336. TMat3& m = *this;
  337. m(i, 0) = v.x();
  338. m(i, 1) = v.y();
  339. m(i, 2) = v.z();
  340. }
  341. void getRows(TVec3<T>& a, TVec3<T>& b, TVec3<T>& c) const
  342. {
  343. a = getRow(0);
  344. b = getRow(1);
  345. c = getRow(2);
  346. }
  347. TVec3<T> getRow(const U i) const
  348. {
  349. const TMat3& m = *this;
  350. return TVec3<T>(m(i, 0), m(i, 1), m(i, 2));
  351. }
  352. void setColumns(const TVec3<T>& a, const TVec3<T>& b, const TVec3<T>& c)
  353. {
  354. setColumn(0, a);
  355. setColumn(1, b);
  356. setColumn(2, c);
  357. }
  358. void setColumn(const U i, const TVec3<T>& v)
  359. {
  360. TMat3& m = *this;
  361. m(0, i) = v.x();
  362. m(1, i) = v.y();
  363. m(2, i) = v.z();
  364. }
  365. void getColumns(TVec3<T>& a, TVec3<T>& b, TVec3<T>& c) const
  366. {
  367. a = getColumn(0);
  368. b = getColumn(1);
  369. c = getColumn(2);
  370. }
  371. TVec3<T> getColumn(const U i) const
  372. {
  373. const TMat3& m = *this;
  374. return TVec3<T>(m(0, i), m(1, i), m(2, i));
  375. }
  376. /// Get 1st column
  377. TVec3<T> getXAxis() const
  378. {
  379. return getColumn(0);
  380. }
  381. /// Get 2nd column
  382. TVec3<T> getYAxis() const
  383. {
  384. return getColumn(1);
  385. }
  386. /// Get 3rd column
  387. TVec3<T> getZAxis() const
  388. {
  389. return getColumn(2);
  390. }
  391. /// Set 1st column
  392. void setXAxis(const TVec3<T>& v3)
  393. {
  394. setColumn(0, v3);
  395. }
  396. /// Set 2nd column
  397. void setYAxis(const TVec3<T>& v3)
  398. {
  399. setColumn(1, v3);
  400. }
  401. /// Set 3rd column
  402. void setZAxis(const TVec3<T>& v3)
  403. {
  404. setColumn(2, v3);
  405. }
  406. void setRotationX(const T rad)
  407. {
  408. TMat3& m = *this;
  409. T sintheta, costheta;
  410. sinCos(rad, sintheta, costheta);
  411. m(0, 0) = 1.0;
  412. m(0, 1) = 0.0;
  413. m(0, 2) = 0.0;
  414. m(1, 0) = 0.0;
  415. m(1, 1) = costheta;
  416. m(1, 2) = -sintheta;
  417. m(2, 0) = 0.0;
  418. m(2, 1) = sintheta;
  419. m(2, 2) = costheta;
  420. }
  421. void setRotationY(const T rad)
  422. {
  423. TMat3& m = *this;
  424. T sintheta, costheta;
  425. sinCos(rad, sintheta, costheta);
  426. m(0, 0) = costheta;
  427. m(0, 1) = 0.0;
  428. m(0, 2) = sintheta;
  429. m(1, 0) = 0.0;
  430. m(1, 1) = 1.0;
  431. m(1, 2) = 0.0;
  432. m(2, 0) = -sintheta;
  433. m(2, 1) = 0.0;
  434. m(2, 2) = costheta;
  435. }
  436. void setRotationZ(const T rad)
  437. {
  438. TMat3& m = *this;
  439. T sintheta, costheta;
  440. sinCos(rad, sintheta, costheta);
  441. m(0, 0) = costheta;
  442. m(0, 1) = -sintheta;
  443. m(0, 2) = 0.0;
  444. m(1, 0) = sintheta;
  445. m(1, 1) = costheta;
  446. m(1, 2) = 0.0;
  447. m(2, 0) = 0.0;
  448. m(2, 1) = 0.0;
  449. m(2, 2) = 1.0;
  450. }
  451. /// It rotates "this" in the axis defined by the rotation AND not the
  452. /// world axis
  453. void rotateXAxis(const T rad)
  454. {
  455. TMat3& m = *this;
  456. // If we analize the mat3 we can extract the 3 unit vectors rotated by
  457. // the mat3. The 3 rotated vectors are in mat's columns. This means
  458. // that: mat3.colomn[0] == i * mat3. rotateXAxis() rotates rad angle
  459. // not from i vector (aka x axis) but from the vector from colomn 0
  460. // NOTE: See the clean code from < r664
  461. T sina, cosa;
  462. sinCos(rad, sina, cosa);
  463. // zAxis = zAxis*cosa - yAxis*sina;
  464. m(0, 2) = m(0, 2) * cosa - m(0, 1) * sina;
  465. m(1, 2) = m(1, 2) * cosa - m(1, 1) * sina;
  466. m(2, 2) = m(2, 2) * cosa - m(2, 1) * sina;
  467. // zAxis.normalize();
  468. T len = sqrt(m(0, 2) * m(0, 2)
  469. + m(1, 2) * m(1, 2) + m(2, 2) * m(2, 2));
  470. m(0, 2) /= len;
  471. m(1, 2) /= len;
  472. m(2, 2) /= len;
  473. // yAxis = zAxis * xAxis;
  474. m(0, 1) = m(1, 2) * m(2, 0) - m(2, 2) * m(1, 0);
  475. m(1, 1) = m(2, 2) * m(0, 0) - m(0, 2) * m(2, 0);
  476. m(2, 1) = m(0, 2) * m(1, 0) - m(1, 2) * m(0, 0);
  477. // yAxis.normalize();
  478. }
  479. /// @copybrief rotateXAxis
  480. void rotateYAxis(const T rad)
  481. {
  482. TMat3& m = *this;
  483. // NOTE: See the clean code from < r664
  484. T sina, cosa;
  485. sinCos(rad, sina, cosa);
  486. // zAxis = zAxis*cosa + xAxis*sina;
  487. m(0, 2) = m(0, 2) * cosa + m(0, 0) * sina;
  488. m(1, 2) = m(1, 2) * cosa + m(1, 0) * sina;
  489. m(2, 2) = m(2, 2) * cosa + m(2, 0) * sina;
  490. // zAxis.normalize();
  491. T len = sqrt(m(0, 2) * m(0, 2)
  492. + m(1, 2) * m(1, 2) + m(2, 2) * m(2, 2));
  493. m(0, 2) /= len;
  494. m(1, 2) /= len;
  495. m(2, 2) /= len;
  496. // xAxis = (zAxis*yAxis) * -1.0f;
  497. m(0, 0) = m(2, 2) * m(1, 1) - m(1, 2) * m(2, 1);
  498. m(1, 0) = m(0, 2) * m(2, 1) - m(2, 2) * m(0, 1);
  499. m(2, 0) = m(1, 2) * m(0, 1) - m(0, 2) * m(1, 1);
  500. }
  501. /// @copybrief rotateXAxis
  502. void rotateZAxis(const T rad)
  503. {
  504. TMat3& m = *this;
  505. // NOTE: See the clean code from < r664
  506. T sina, cosa;
  507. sinCos(rad, sina, cosa);
  508. // xAxis = xAxis*cosa + yAxis*sina;
  509. m(0, 0) = m(0, 0) * cosa + m(0, 1) * sina;
  510. m(1, 0) = m(1, 0) * cosa + m(1, 1) * sina;
  511. m(2, 0) = m(2, 0) * cosa + m(2, 1) * sina;
  512. // xAxis.normalize();
  513. T len = sqrt(m(0, 0) * m(0, 0)
  514. + m(1, 0) * m(1, 0) + m(2, 0) * m(2, 0));
  515. m(0, 0) /= len;
  516. m(1, 0) /= len;
  517. m(2, 0) /= len;
  518. // yAxis = zAxis*xAxis;
  519. m(0, 1) = m(1, 2) * m(2, 0) - m(2, 2) * m(1, 0);
  520. m(1, 1) = m(2, 2) * m(0, 0) - m(0, 2) * m(2, 0);
  521. m(2, 1) = m(0, 2) * m(1, 0) - m(1, 2) * m(0, 0);
  522. }
  523. void transpose()
  524. {
  525. TMat3& m = *this;
  526. T temp = m(0, 1);
  527. m(0, 1) = m(1, 0);
  528. m(1, 0) = temp;
  529. temp = m(0, 2);
  530. m(0, 2) = m(2, 0);
  531. m(2, 0) = temp;
  532. temp = m(1, 2);
  533. m(1, 2) = m(2, 1);
  534. m(2, 1) = temp;
  535. }
  536. TMat3 getTransposed() const
  537. {
  538. const TMat3& m = *this;
  539. TMat3 m3;
  540. for(U i = 0; i < 3; i++)
  541. {
  542. for(U j = 0; j < 3; j++)
  543. {
  544. m3(i, j) = m(j, i);
  545. }
  546. }
  547. return m3;
  548. }
  549. void reorthogonalize()
  550. {
  551. // There are 2 methods, the standard and the Gram-Schmidt method with a
  552. // twist for zAxis. This uses the 2nd. For the first see < r664
  553. TVec3<T> xAxis, yAxis, zAxis;
  554. getColumns(xAxis, yAxis, zAxis);
  555. xAxis.normalize();
  556. yAxis = yAxis - (xAxis * xAxis.dot(yAxis));
  557. yAxis.normalize();
  558. zAxis = xAxis.cross(yAxis);
  559. setColumns(xAxis, yAxis, zAxis);
  560. }
  561. T getDet() const
  562. {
  563. const TMat3& m = *this;
  564. // For the accurate method see < r664
  565. return m(0, 0) * (m(1, 1) * m(2, 2)
  566. - m(1, 2) * m(2, 1)) - m(0, 1) * (m(1, 0)
  567. * m(2, 2) - m(1, 2) * m(2, 0)) + m(0, 2)
  568. * (m(0, 1) * m(2, 1) - m(1, 1) * m(2, 0));
  569. }
  570. TMat3 getInverse() const
  571. {
  572. // Using Gramer's method Inv(A) = (1 / getDet(A)) * Adj(A)
  573. const TMat3& m = *this;
  574. TMat3 r;
  575. // compute determinant
  576. T cofactor0 = m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1);
  577. T cofactor3 = m(0, 2) * m(2, 1) - m(0, 1) * m(2, 2);
  578. T cofactor6 = m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1);
  579. T det = m(0, 0) * cofactor0 + m(1, 0) * cofactor3
  580. + m(2, 0) * cofactor6;
  581. ANKI_ASSERT(!isZero<T>(det)); // Cannot invert det == 0
  582. // create adjoint matrix and multiply by 1/det to get inverse
  583. T invDet = 1.0 / det;
  584. r(0, 0) = invDet * cofactor0;
  585. r(0, 1) = invDet * cofactor3;
  586. r(0, 2) = invDet * cofactor6;
  587. r(1, 0) = invDet * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2));
  588. r(1, 1) = invDet * (m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0));
  589. r(1, 2) = invDet * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2));
  590. r(2, 0) = invDet * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0));
  591. r(2, 1) = invDet * (m(0, 1) * m(2, 0) - m(0, 0) * m(2, 1));
  592. r(2, 2) = invDet * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0));
  593. return r;
  594. }
  595. void invert()
  596. {
  597. (*this) = getInverse();
  598. }
  599. void setIdentity()
  600. {
  601. (*this) = getIdentity();
  602. }
  603. static const TMat3& getZero()
  604. {
  605. static const TMat3 zero(0.0);
  606. return zero;
  607. }
  608. static const TMat3& getIdentity()
  609. {
  610. static const TMat3 ident(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
  611. return ident;
  612. }
  613. /// @}
  614. private:
  615. /// @name Data members
  616. /// @{
  617. union
  618. {
  619. Array<T, 9> arr1;
  620. Array<Array<T, 3>, 3> arr2;
  621. T carr1[9]; ///< For easier debugging with gdb
  622. T carr2[3][3]; ///< For easier debugging with gdb
  623. };
  624. /// @}
  625. };
  626. template<typename T>
  627. TMat3<T> operator+(T f, const TMat3<T>& m3)
  628. {
  629. return m3 + f;
  630. }
  631. template<typename T>
  632. TMat3<T> operator-(T f, const TMat3<T>& m3)
  633. {
  634. TMat3<T> out;
  635. for(U i = 0; i < 9; i++)
  636. {
  637. out[i] = f - m3[i];
  638. }
  639. return out;
  640. }
  641. template<typename T>
  642. TMat3<T> operator*(T f, const TMat3<T>& m3)
  643. {
  644. return m3 * f;
  645. }
  646. template<typename T>
  647. TMat3<T> operator/(T f, const TMat3<T>& m3)
  648. {
  649. TMat3<T> out;
  650. for(U i = 0; i < 9; i++)
  651. {
  652. out[i] = f / m3[i];
  653. }
  654. return out;
  655. }
  656. /// F32 3x3 matrix
  657. typedef TMat3<F32> Mat3;
  658. static_assert(sizeof(Mat3) == sizeof(F32) * 3 * 3, "Incorrect size");
  659. /// @}
  660. } // end namespace anki
  661. #endif