Euler.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. #ifndef ANKI_MATH_EULER_H
  6. #define ANKI_MATH_EULER_H
  7. #include "anki/math/CommonIncludes.h"
  8. namespace anki {
  9. /// @addtogroup math
  10. /// @{
  11. /// Euler angles. Used for rotations. It cannot describe a rotation
  12. /// accurately though
  13. template<typename T>
  14. class TEuler
  15. {
  16. public:
  17. /// @name Constructors
  18. /// @{
  19. explicit TEuler()
  20. {
  21. x() = y() = z() = 0.0;
  22. }
  23. explicit TEuler(const T x_, const T y_, const T z_)
  24. {
  25. x() = x_;
  26. y() = y_;
  27. z() = z_;
  28. }
  29. TEuler(const TEuler& b)
  30. {
  31. x() = b.x();
  32. y() = b.y();
  33. z() = b.z();
  34. }
  35. explicit TEuler(const TQuat<T>& q)
  36. {
  37. T test = q.x() * q.y() + q.z() * q.w();
  38. if(test > 0.499)
  39. {
  40. y() = 2.0 * atan2<T>(q.x(), q.w());
  41. z() = getPi<T>() / 2.0;
  42. x() = 0.0;
  43. return;
  44. }
  45. if(test < -0.499)
  46. {
  47. y() = -2.0 * atan2<T>(q.x(), q.w());
  48. z() = -getPi<T>() / 2.0;
  49. x() = 0.0;
  50. return;
  51. }
  52. T sqx = q.x() * q.x();
  53. T sqy = q.y() * q.y();
  54. T sqz = q.z() * q.z();
  55. y() = atan2<T>(2.0 * q.y() * q.w() - 2.0 * q.x() * q.z(),
  56. 1.0 - 2.0 * sqy - 2.0 * sqz);
  57. z() = asin<T>(2.0 * test);
  58. x() = atan2<T>(2.0 * q.x() * q.w() - 2.0 * q.y() * q.z(),
  59. 1.0 - 2.0 * sqx - 2.0 * sqz);
  60. }
  61. explicit TEuler(const TMat3<T>& m3)
  62. {
  63. T cx, sx;
  64. T cy, sy;
  65. T cz, sz;
  66. sy = m3(0, 2);
  67. cy = sqrt<T>(1.0 - sy * sy);
  68. // normal case
  69. if (!isZero<T>(cy))
  70. {
  71. T factor = 1.0 / cy;
  72. sx = -m3(1, 2) * factor;
  73. cx = m3(2, 2) * factor;
  74. sz = -m3(0, 1) * factor;
  75. cz = m3(0, 0) * factor;
  76. }
  77. // x and z axes aligned
  78. else
  79. {
  80. sz = 0.0;
  81. cz = 1.0;
  82. sx = m3(2, 1);
  83. cx = m3(1, 1);
  84. }
  85. z() = atan2<T>(sz, cz);
  86. y() = atan2<T>(sy, cy);
  87. x() = atan2<T>(sx, cx);
  88. }
  89. /// @}
  90. /// @name Accessors
  91. /// @{
  92. T& operator [](const U i)
  93. {
  94. return m_arr[i];
  95. }
  96. T operator [](const U i) const
  97. {
  98. return m_arr[i];
  99. }
  100. T& x()
  101. {
  102. return m_vec.m_x;
  103. }
  104. T x() const
  105. {
  106. return m_vec.m_x;
  107. }
  108. T& y()
  109. {
  110. return m_vec.m_y;
  111. }
  112. T y() const
  113. {
  114. return m_vec.m_y;
  115. }
  116. T& z()
  117. {
  118. return m_vec.m_z;
  119. }
  120. T z() const
  121. {
  122. return m_vec.m_z;
  123. }
  124. /// @}
  125. /// @name Operators with same type
  126. /// @{
  127. TEuler& operator=(const TEuler& b)
  128. {
  129. x() = b.x();
  130. y() = b.y();
  131. z() = b.z();
  132. return *this;
  133. }
  134. /// @}
  135. /// @name Other
  136. /// @{
  137. template<typename TAlloc>
  138. StringBase<TAlloc> toString(
  139. typename StringBase<TAlloc>::Allocator& alloc) const
  140. {
  141. StringBase<TAlloc> s(alloc);
  142. s = StringBase<TAlloc>::toString(x(), alloc) + CString(" ")
  143. + StringBase<TAlloc>::toString(y(), alloc) + CString(" ")
  144. + StringBase<TAlloc>::toString(z(), alloc);
  145. return s;
  146. }
  147. /// @}
  148. private:
  149. /// @name Data
  150. /// @{
  151. struct Vec
  152. {
  153. T m_x, m_y, m_z;
  154. };
  155. union
  156. {
  157. Vec m_vec;
  158. Array<T, 3> m_arr;
  159. };
  160. /// @}
  161. };
  162. /// F32 Euler angles
  163. typedef TEuler<F32> Euler;
  164. /// @}
  165. } // end namespace anki
  166. #endif