Mat3.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/math/CommonIncludes.h>
  7. #include <anki/math/Mat.h>
  8. namespace anki
  9. {
  10. /// @addtogroup math
  11. /// @{
  12. /// 3x3 Matrix. Mainly used for rotations. It includes many helpful member
  13. /// functions. Its row major. The columns are the x,y,z axis
  14. /// @note TMat3*TMat3: 27 muls 18 adds
  15. template<typename T>
  16. class TMat3 : public TMat<T, 3, 3, Array<T, 9>, TMat3<T>, TVec3<T>, TVec3<T>>
  17. {
  18. /// @name Friends
  19. /// @{
  20. template<typename Y>
  21. friend TMat3<Y> operator+(Y f, const TMat3<Y>& m3);
  22. template<typename Y>
  23. friend TMat3<Y> operator-(Y f, const TMat3<Y>& m3);
  24. template<typename Y>
  25. friend TMat3<Y> operator*(Y f, const TMat3<Y>& m3);
  26. template<typename Y>
  27. friend TMat3<Y> operator/(Y f, const TMat3<Y>& m3);
  28. /// @}
  29. public:
  30. using Base = TMat<T, 3, 3, Array<T, 9>, TMat3<T>, TVec3<T>, TVec3<T>>;
  31. using Base::setRotationPart;
  32. /// @name Constructors
  33. /// @{
  34. TMat3()
  35. : Base()
  36. {
  37. }
  38. TMat3(const TMat3& b)
  39. : Base(b)
  40. {
  41. }
  42. TMat3(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
  43. {
  44. TMat3& m = *this;
  45. m(0, 0) = m00;
  46. m(0, 1) = m01;
  47. m(0, 2) = m02;
  48. m(1, 0) = m10;
  49. m(1, 1) = m11;
  50. m(1, 2) = m12;
  51. m(2, 0) = m20;
  52. m(2, 1) = m21;
  53. m(2, 2) = m22;
  54. }
  55. explicit TMat3(const T f)
  56. : Base(f)
  57. {
  58. }
  59. explicit TMat3(const T arr[])
  60. : Base(arr)
  61. {
  62. }
  63. explicit TMat3(const TQuat<T>& q)
  64. {
  65. setRotationPart(q);
  66. }
  67. explicit TMat3(const TEuler<T>& e)
  68. {
  69. setRotationPart(e);
  70. }
  71. explicit TMat3(const TAxisang<T>& axisang)
  72. {
  73. setRotationPart(axisang);
  74. }
  75. /// @}
  76. /// @name Other
  77. /// @{
  78. T getDet() const
  79. {
  80. const TMat3& m = *this;
  81. // For the accurate method see < r664
  82. return m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1))
  83. - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0))
  84. + m(0, 2) * (m(0, 1) * m(2, 1) - m(1, 1) * m(2, 0));
  85. }
  86. TMat3 getInverse() const
  87. {
  88. // Using Gramer's method Inv(A) = (1 / getDet(A)) * Adj(A)
  89. const TMat3& m = *this;
  90. TMat3 r;
  91. // compute determinant
  92. T cofactor0 = m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1);
  93. T cofactor3 = m(0, 2) * m(2, 1) - m(0, 1) * m(2, 2);
  94. T cofactor6 = m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1);
  95. T det = m(0, 0) * cofactor0 + m(1, 0) * cofactor3 + m(2, 0) * cofactor6;
  96. ANKI_ASSERT(!isZero<T>(det)); // Cannot invert det == 0
  97. // create adjoint matrix and multiply by 1/det to get inverse
  98. T invDet = 1.0 / det;
  99. r(0, 0) = invDet * cofactor0;
  100. r(0, 1) = invDet * cofactor3;
  101. r(0, 2) = invDet * cofactor6;
  102. r(1, 0) = invDet * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2));
  103. r(1, 1) = invDet * (m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0));
  104. r(1, 2) = invDet * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2));
  105. r(2, 0) = invDet * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0));
  106. r(2, 1) = invDet * (m(0, 1) * m(2, 0) - m(0, 0) * m(2, 1));
  107. r(2, 2) = invDet * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0));
  108. return r;
  109. }
  110. void invert()
  111. {
  112. (*this) = getInverse();
  113. }
  114. void setIdentity()
  115. {
  116. (*this) = getIdentity();
  117. }
  118. static const TMat3& getZero()
  119. {
  120. static const TMat3 zero(0.0);
  121. return zero;
  122. }
  123. static const TMat3& getIdentity()
  124. {
  125. static const TMat3 ident(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
  126. return ident;
  127. }
  128. /// @}
  129. };
  130. /// @memberof TMat3
  131. template<typename T>
  132. TMat3<T> operator+(T f, const TMat3<T>& m3)
  133. {
  134. return m3 + f;
  135. }
  136. /// @memberof TMat3
  137. template<typename T>
  138. TMat3<T> operator-(T f, const TMat3<T>& m3)
  139. {
  140. TMat3<T> out;
  141. for(U i = 0; i < 9; i++)
  142. {
  143. out[i] = f - m3[i];
  144. }
  145. return out;
  146. }
  147. /// @memberof TMat3
  148. template<typename T>
  149. TMat3<T> operator*(T f, const TMat3<T>& m3)
  150. {
  151. return m3 * f;
  152. }
  153. /// @memberof TMat3
  154. template<typename T>
  155. TMat3<T> operator/(T f, const TMat3<T>& m3)
  156. {
  157. TMat3<T> out;
  158. for(U i = 0; i < 9; i++)
  159. {
  160. ANKI_ASSERT(m3[i] != T(0));
  161. out[i] = f / m3[i];
  162. }
  163. return out;
  164. }
  165. /// F32 3x3 matrix
  166. typedef TMat3<F32> Mat3;
  167. static_assert(sizeof(Mat3) == sizeof(F32) * 3 * 3, "Incorrect size");
  168. /// @}
  169. } // end namespace anki