Mat3x4.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. /// Template struct that gives the type of the TMat4 SIMD
  13. template<typename T>
  14. class TMat3x4Simd
  15. {
  16. public:
  17. using Type = Array<T, 12>;
  18. };
  19. #if ANKI_SIMD == ANKI_SIMD_SSE
  20. // Specialize for F32
  21. template<>
  22. class TMat3x4Simd<F32>
  23. {
  24. public:
  25. using Type = Array<__m128, 3>;
  26. };
  27. #endif
  28. /// 3x4 Matrix. Mainly used for transformations. It includes many helpful member
  29. /// functions. Its row major. The columns are the x,y,z axis
  30. template<typename T>
  31. class alignas(16) TMat3x4 : public TMat<T,
  32. 3,
  33. 4,
  34. typename TMat3x4Simd<T>::Type,
  35. TMat3x4<T>,
  36. TVec4<T>,
  37. TVec3<T>>
  38. {
  39. public:
  40. using Base = TMat<T,
  41. 3,
  42. 4,
  43. typename TMat3x4Simd<T>::Type,
  44. TMat3x4<T>,
  45. TVec4<T>,
  46. TVec3<T>>;
  47. using Base::Base;
  48. /// @name Constructors
  49. /// @{
  50. TMat3x4()
  51. : Base()
  52. {
  53. }
  54. TMat3x4(const TMat3x4& b)
  55. : Base(b)
  56. {
  57. }
  58. TMat3x4(T m00,
  59. T m01,
  60. T m02,
  61. T m03,
  62. T m10,
  63. T m11,
  64. T m12,
  65. T m13,
  66. T m20,
  67. T m21,
  68. T m22,
  69. T m23)
  70. {
  71. TMat3x4& m = *this;
  72. m(0, 0) = m00;
  73. m(0, 1) = m01;
  74. m(0, 2) = m02;
  75. m(0, 3) = m03;
  76. m(1, 0) = m10;
  77. m(1, 1) = m11;
  78. m(1, 2) = m12;
  79. m(1, 3) = m13;
  80. m(2, 0) = m20;
  81. m(2, 1) = m21;
  82. m(2, 2) = m22;
  83. m(2, 3) = m23;
  84. }
  85. explicit TMat3x4(const T f)
  86. : Base(f)
  87. {
  88. }
  89. explicit TMat3x4(const TMat3<T>& m3)
  90. {
  91. TMat3x4& m = *this;
  92. m(0, 0) = m3(0, 0);
  93. m(0, 1) = m3(0, 1);
  94. m(0, 2) = m3(0, 2);
  95. m(0, 3) = static_cast<T>(0);
  96. m(1, 0) = m3(1, 0);
  97. m(1, 1) = m3(1, 1);
  98. m(1, 2) = m3(1, 2);
  99. m(1, 3) = static_cast<T>(0);
  100. m(2, 0) = m3(2, 0);
  101. m(2, 1) = m3(2, 1);
  102. m(2, 2) = m3(2, 2);
  103. m(2, 3) = static_cast<T>(0);
  104. }
  105. explicit TMat3x4(const TMat4<T>& m3)
  106. {
  107. TMat3x4& m = *this;
  108. m(0, 0) = m3(0, 0);
  109. m(0, 1) = m3(0, 1);
  110. m(0, 2) = m3(0, 2);
  111. m(0, 3) = m3(0, 3);
  112. m(1, 0) = m3(1, 0);
  113. m(1, 1) = m3(1, 1);
  114. m(1, 2) = m3(1, 2);
  115. m(1, 3) = m3(1, 3);
  116. m(2, 0) = m3(2, 0);
  117. m(2, 1) = m3(2, 1);
  118. m(2, 2) = m3(2, 2);
  119. m(2, 3) = m3(2, 3);
  120. }
  121. explicit TMat3x4(const TVec3<T>& v)
  122. {
  123. TMat3x4& m = *this;
  124. m(0, 0) = static_cast<T>(1);
  125. m(0, 1) = static_cast<T>(0);
  126. m(0, 2) = static_cast<T>(0);
  127. m(0, 3) = v.x();
  128. m(1, 0) = static_cast<T>(0);
  129. m(1, 1) = static_cast<T>(1);
  130. m(1, 2) = static_cast<T>(0);
  131. m(1, 3) = v.y();
  132. m(2, 0) = static_cast<T>(0);
  133. m(2, 1) = static_cast<T>(0);
  134. m(2, 2) = static_cast<T>(1);
  135. m(2, 3) = v.z();
  136. }
  137. explicit TMat3x4(const TQuat<T>& q)
  138. {
  139. Base::setRotationPart(TMat3<T>(q));
  140. Base::setTranslationPart(TVec3<T>(static_cast<T>(0)));
  141. }
  142. explicit TMat3x4(const TEuler<T>& b)
  143. {
  144. Base::setRotationPart(TMat3<T>(b));
  145. Base::setTranslationPart(TVec3<T>(static_cast<T>(0)));
  146. }
  147. explicit TMat3x4(const TAxisang<T>& b)
  148. {
  149. Base::setRotationPart(TAxisang<T>(b));
  150. Base::setTranslationPart(TVec3<T>(static_cast<T>(0)));
  151. }
  152. TMat3x4(const TVec3<T>& transl, const TMat3<T>& rot)
  153. {
  154. Base::setRotationPart(rot);
  155. Base::setTranslationPart(transl);
  156. }
  157. TMat3x4(const TVec3<T>& transl, const TMat3<T>& rot, const T scale)
  158. {
  159. if(isZero<T>(scale - static_cast<T>(1)))
  160. {
  161. Base::setRotationPart(rot);
  162. }
  163. else
  164. {
  165. setRotationPart(rot * scale);
  166. }
  167. Base::setTranslationPart(transl);
  168. }
  169. explicit TMat3x4(const TTransform<T>& t)
  170. {
  171. (*this) = TMat3x4(t.getOrigin(), t.getRotation(), t.getScale());
  172. }
  173. /// @}
  174. /// @name Other
  175. /// @{
  176. /// Create a new matrix that is equivalent to Mat4(this)*Mat4(b)
  177. TMat3x4 combineTransformations(const TMat3x4& b) const
  178. {
  179. const TMat3x4& a = *static_cast<const TMat3x4*>(this);
  180. TMat3x4 c;
  181. c(0, 0) = a(0, 0) * b(0, 0) + a(0, 1) * b(1, 0) + a(0, 2) * b(2, 0);
  182. c(0, 1) = a(0, 0) * b(0, 1) + a(0, 1) * b(1, 1) + a(0, 2) * b(2, 1);
  183. c(0, 2) = a(0, 0) * b(0, 2) + a(0, 1) * b(1, 2) + a(0, 2) * b(2, 2);
  184. c(1, 0) = a(1, 0) * b(0, 0) + a(1, 1) * b(1, 0) + a(1, 2) * b(2, 0);
  185. c(1, 1) = a(1, 0) * b(0, 1) + a(1, 1) * b(1, 1) + a(1, 2) * b(2, 1);
  186. c(1, 2) = a(1, 0) * b(0, 2) + a(1, 1) * b(1, 2) + a(1, 2) * b(2, 2);
  187. c(2, 0) = a(2, 0) * b(0, 0) + a(2, 1) * b(1, 0) + a(2, 2) * b(2, 0);
  188. c(2, 1) = a(2, 0) * b(0, 1) + a(2, 1) * b(1, 1) + a(2, 2) * b(2, 1);
  189. c(2, 2) = a(2, 0) * b(0, 2) + a(2, 1) * b(1, 2) + a(2, 2) * b(2, 2);
  190. c(0, 3) =
  191. a(0, 0) * b(0, 3) + a(0, 1) * b(1, 3) + a(0, 2) * b(2, 3) + a(0, 3);
  192. c(1, 3) =
  193. a(1, 0) * b(0, 3) + a(1, 1) * b(1, 3) + a(1, 2) * b(2, 3) + a(1, 3);
  194. c(2, 3) =
  195. a(2, 0) * b(0, 3) + a(2, 1) * b(1, 3) + a(2, 2) * b(2, 3) + a(2, 3);
  196. return c;
  197. }
  198. void setIdentity()
  199. {
  200. (*this) = getIdentity();
  201. }
  202. static const TMat3x4& getIdentity()
  203. {
  204. static const TMat3x4 ident(
  205. 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  206. return ident;
  207. }
  208. /// @}
  209. };
  210. #if ANKI_SIMD == ANKI_SIMD_SSE
  211. // Forward declare specializations
  212. template<>
  213. TMat3x4<F32>::Base::TMat(const TMat3x4<F32>::Base& b);
  214. template<>
  215. TMat3x4<F32>::Base::TMat(const F32 f);
  216. template<>
  217. inline TVec3<F32> TMat3x4<F32>::Base::operator*(const TVec4<F32>& b) const;
  218. template<>
  219. TMat3x4<F32> TMat3x4<F32>::combineTransformations(const TMat3x4<F32>& b) const;
  220. #elif ANKI_SIMD == ANKI_SIMD_NEON
  221. #error "TODO"
  222. #endif
  223. /// F32 4x4 matrix
  224. typedef TMat3x4<F32> Mat3x4;
  225. static_assert(sizeof(Mat3x4) == sizeof(F32) * 3 * 4, "Incorrect size");
  226. /// @}
  227. } // end namespace anki
  228. #include <anki/math/Mat3x4.inl.h>