Transform.h 3.6 KB

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