Euler.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. String toString(TAlloc alloc) const
  139. {
  140. String s;
  141. Error err = s.sprintf("%f %f %f", x(), y(), z());
  142. (void)err;
  143. return s;
  144. }
  145. /// @}
  146. private:
  147. /// @name Data
  148. /// @{
  149. struct Vec
  150. {
  151. T m_x, m_y, m_z;
  152. };
  153. union
  154. {
  155. Vec m_vec;
  156. Array<T, 3> m_arr;
  157. };
  158. /// @}
  159. };
  160. /// F32 Euler angles
  161. typedef TEuler<F32> Euler;
  162. /// @}
  163. } // end namespace anki
  164. #endif