You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
4.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2005-12-21
  5. // Updated : 2008-11-27
  6. // Licence : This source is under MIT License
  7. // File : glm/gtx/quaternion.inl
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include <limits>
  10. namespace glm
  11. {
  12. template <typename valType>
  13. GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
  14. (
  15. detail::tvec3<valType> const & v,
  16. detail::tquat<valType> const & q
  17. )
  18. {
  19. return inverse(q) * v;
  20. }
  21. template <typename valType>
  22. GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
  23. (
  24. detail::tquat<valType> const & q,
  25. detail::tvec3<valType> const & v
  26. )
  27. {
  28. return q * v;
  29. }
  30. template <typename T>
  31. GLM_FUNC_QUALIFIER detail::tquat<T> squad
  32. (
  33. detail::tquat<T> const & q1,
  34. detail::tquat<T> const & q2,
  35. detail::tquat<T> const & s1,
  36. detail::tquat<T> const & s2,
  37. T const & h)
  38. {
  39. return mix(mix(q1, q2, h), mix(s1, s2, h), T(2) * (T(1) - h) * h);
  40. }
  41. template <typename T>
  42. GLM_FUNC_QUALIFIER detail::tquat<T> intermediate
  43. (
  44. detail::tquat<T> const & prev,
  45. detail::tquat<T> const & curr,
  46. detail::tquat<T> const & next
  47. )
  48. {
  49. detail::tquat<T> invQuat = inverse(curr);
  50. return exp((log(next + invQuat) + log(prev + invQuat)) / T(-4)) * curr;
  51. }
  52. template <typename T>
  53. GLM_FUNC_QUALIFIER detail::tquat<T> exp
  54. (
  55. detail::tquat<T> const & q
  56. )
  57. {
  58. detail::tvec3<T> u(q.x, q.y, q.z);
  59. float Angle = glm::length(u);
  60. detail::tvec3<T> v(u / Angle);
  61. return detail::tquat<T>(cos(Angle), sin(Angle) * v);
  62. }
  63. template <typename T>
  64. GLM_FUNC_QUALIFIER detail::tquat<T> log
  65. (
  66. detail::tquat<T> const & q
  67. )
  68. {
  69. if((q.x == T(0)) && (q.y == T(0)) && (q.z == T(0)))
  70. {
  71. if(q.w > T(0))
  72. return detail::tquat<T>(log(q.w), T(0), T(0), T(0));
  73. else if(q.w < T(0))
  74. return detail::tquat<T>(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0));
  75. else
  76. return detail::tquat<T>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
  77. }
  78. else
  79. {
  80. T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
  81. T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w);
  82. T t = atan(Vec3Len, T(q.w)) / Vec3Len;
  83. return detail::tquat<T>(t * q.x, t * q.y, t * q.z, log(QuatLen));
  84. }
  85. }
  86. template <typename T>
  87. GLM_FUNC_QUALIFIER detail::tquat<T> pow
  88. (
  89. detail::tquat<T> const & x,
  90. T const & y
  91. )
  92. {
  93. if(abs(x.w) > T(0.9999))
  94. return x;
  95. float Angle = acos(y);
  96. float NewAngle = Angle * y;
  97. float Div = sin(NewAngle) / sin(Angle);
  98. return detail::tquat<T>(
  99. cos(NewAngle),
  100. x.x * Div,
  101. x.y * Div,
  102. x.z * Div);
  103. }
  104. //template <typename T>
  105. //GLM_FUNC_QUALIFIER detail::tquat<T> sqrt
  106. //(
  107. // detail::tquat<T> const & q
  108. //)
  109. //{
  110. // T q0 = T(1) - dot(q, q);
  111. // return T(2) * (T(1) + q0) * q;
  112. //}
  113. template <typename T>
  114. GLM_FUNC_QUALIFIER detail::tvec3<T> rotate
  115. (
  116. detail::tquat<T> const & q,
  117. detail::tvec3<T> const & v
  118. )
  119. {
  120. return q * v;
  121. }
  122. template <typename T>
  123. GLM_FUNC_QUALIFIER detail::tvec4<T> rotate
  124. (
  125. detail::tquat<T> const & q,
  126. detail::tvec4<T> const & v
  127. )
  128. {
  129. return q * v;
  130. }
  131. template <typename T>
  132. GLM_FUNC_QUALIFIER T extractRealComponent
  133. (
  134. detail::tquat<T> const & q
  135. )
  136. {
  137. T w = T(1.0) - q.x * q.x - q.y * q.y - q.z * q.z;
  138. if(w < T(0))
  139. return T(0);
  140. else
  141. return -sqrt(w);
  142. }
  143. template <typename T>
  144. GLM_FUNC_QUALIFIER detail::tquat<T> shortMix
  145. (
  146. detail::tquat<T> const & x,
  147. detail::tquat<T> const & y,
  148. T const & a
  149. )
  150. {
  151. if(a <= typename detail::tquat<T>::value_type(0)) return x;
  152. if(a >= typename detail::tquat<T>::value_type(1)) return y;
  153. T fCos = dot(x, y);
  154. detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
  155. if(fCos < T(0))
  156. {
  157. y2 = -y;
  158. fCos = -fCos;
  159. }
  160. //if(fCos > 1.0f) // problem
  161. T k0, k1;
  162. if(fCos > T(0.9999))
  163. {
  164. k0 = T(1) - a;
  165. k1 = T(0) + a; //BUG!!! 1.0f + a;
  166. }
  167. else
  168. {
  169. T fSin = sqrt(T(1) - fCos * fCos);
  170. T fAngle = atan(fSin, fCos);
  171. T fOneOverSin = T(1) / fSin;
  172. k0 = sin((T(1) - a) * fAngle) * fOneOverSin;
  173. k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
  174. }
  175. return detail::tquat<T>(
  176. k0 * x.w + k1 * y2.w,
  177. k0 * x.x + k1 * y2.x,
  178. k0 * x.y + k1 * y2.y,
  179. k0 * x.z + k1 * y2.z);
  180. }
  181. template <typename T>
  182. GLM_FUNC_QUALIFIER detail::tquat<T> fastMix
  183. (
  184. detail::tquat<T> const & x,
  185. detail::tquat<T> const & y,
  186. T const & a
  187. )
  188. {
  189. return glm::normalize(x * (T(1) - a) + (y * a));
  190. }
  191. }//namespace glm