Transform.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. namespace anki
  8. {
  9. /// @addtogroup math
  10. /// @{
  11. /// Transformation
  12. template<typename T>
  13. class TTransform
  14. {
  15. public:
  16. /// @name Constructors
  17. /// @{
  18. TTransform()
  19. {
  20. }
  21. TTransform(const TTransform& b)
  22. : m_origin(b.m_origin)
  23. , m_rotation(b.m_rotation)
  24. , m_scale(b.m_scale)
  25. {
  26. checkW();
  27. }
  28. explicit TTransform(const Mat4& m4)
  29. {
  30. m_rotation = TMat3x4<T>(m4.getRotationPart());
  31. m_origin = m4.getTranslationPart().xyz0();
  32. m_scale = 1.0;
  33. checkW();
  34. }
  35. TTransform(
  36. const TVec4<T>& origin, const TMat3x4<T>& rotation, const T scale)
  37. : m_origin(origin)
  38. , m_rotation(rotation)
  39. , m_scale(scale)
  40. {
  41. checkW();
  42. }
  43. /// @}
  44. /// @name Accessors
  45. /// @{
  46. const TVec4<T>& getOrigin() const
  47. {
  48. return m_origin;
  49. }
  50. TVec4<T>& getOrigin()
  51. {
  52. return m_origin;
  53. }
  54. void setOrigin(const TVec4<T>& o)
  55. {
  56. m_origin = o;
  57. checkW();
  58. }
  59. const TMat3x4<T>& getRotation() const
  60. {
  61. return m_rotation;
  62. }
  63. TMat3x4<T>& getRotation()
  64. {
  65. return m_rotation;
  66. }
  67. void setRotation(const TMat3x4<T>& r)
  68. {
  69. m_rotation = r;
  70. }
  71. T getScale() const
  72. {
  73. return m_scale;
  74. }
  75. T& getScale()
  76. {
  77. return m_scale;
  78. }
  79. void setScale(const T s)
  80. {
  81. m_scale = s;
  82. }
  83. /// @}
  84. /// @name Operators with same type
  85. /// @{
  86. TTransform& operator=(const TTransform& b)
  87. {
  88. m_origin = b.m_origin;
  89. m_rotation = b.m_rotation;
  90. m_scale = b.m_scale;
  91. checkW();
  92. return *this;
  93. }
  94. Bool operator==(const TTransform& b) const
  95. {
  96. return m_origin == b.m_origin && m_rotation == b.m_rotation
  97. && m_scale == b.m_scale;
  98. }
  99. Bool operator!=(const TTransform& b) const
  100. {
  101. return !operator==(b);
  102. }
  103. /// @}
  104. /// @name Other
  105. /// @{
  106. void setIdentity()
  107. {
  108. (*this) = getIdentity();
  109. }
  110. static const TTransform& getIdentity()
  111. {
  112. static const TTransform ident(
  113. TVec4<T>(0.0), TMat3x4<T>::getIdentity(), 1.0);
  114. return ident;
  115. }
  116. /// @copybrief combineTTransformations
  117. TTransform combineTransformations(const TTransform& b) const
  118. {
  119. checkW();
  120. const TTransform& a = *this;
  121. TTransform out;
  122. out.m_origin =
  123. TVec4<T>(a.m_rotation * (b.m_origin * a.m_scale), 0.0) + a.m_origin;
  124. out.m_rotation = a.m_rotation.combineTransformations(b.m_rotation);
  125. out.m_scale = a.m_scale * b.m_scale;
  126. return out;
  127. }
  128. /// Get the inverse transformation. Its faster that inverting a Mat4
  129. TTransform getInverse() const
  130. {
  131. checkW();
  132. TTransform o;
  133. o.m_rotation = m_rotation;
  134. o.m_rotation.transposeRotationPart();
  135. o.m_scale = 1.0 / m_scale;
  136. o.m_origin = -((o.m_rotation * o.m_scale) * m_origin).xyz0();
  137. return o;
  138. }
  139. void invert()
  140. {
  141. m_rotation.transposeRotationPart();
  142. m_scale = 1.0 / m_scale;
  143. m_origin = -((m_rotation * m_scale) * m_origin);
  144. }
  145. /// Transform a TVec3
  146. TVec3<T> transform(const TVec3<T>& b) const
  147. {
  148. checkW();
  149. return (m_rotation.getRotationPart() * (b * m_scale)) + m_origin.xyz();
  150. }
  151. /// Transform a TVec4. SIMD optimized
  152. TVec4<T> transform(const TVec4<T>& b) const
  153. {
  154. checkW();
  155. TVec4<T> out = TVec4<T>(m_rotation * (b * m_scale), 0.0) + m_origin;
  156. return out;
  157. }
  158. template<typename TAlloc>
  159. String toString(TAlloc alloc) const
  160. {
  161. ANKI_ASSERT(0 && "TODO");
  162. return String();
  163. }
  164. /// @}
  165. private:
  166. /// @name Data
  167. /// @{
  168. TVec4<T> m_origin; ///< The rotation
  169. TMat3x4<T> m_rotation; ///< The translation
  170. T m_scale; ///< The uniform scaling
  171. /// @}
  172. void checkW() const
  173. {
  174. ANKI_ASSERT(m_origin.w() == 0.0);
  175. }
  176. };
  177. /// F32 transformation
  178. typedef TTransform<F32> Transform;
  179. /// @}
  180. } // end namespace anki