rotate_vector.inl 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /// @ref gtx_rotate_vector
  2. namespace glm
  3. {
  4. template<typename T, qualifier Q>
  5. GLM_FUNC_QUALIFIER vec<3, T, Q> slerp
  6. (
  7. vec<3, T, Q> const& x,
  8. vec<3, T, Q> const& y,
  9. T const& a
  10. )
  11. {
  12. // get cosine of angle between vectors (-1 -> 1)
  13. T CosAlpha = dot(x, y);
  14. // get angle (0 -> pi)
  15. T Alpha = acos(CosAlpha);
  16. // get sine of angle between vectors (0 -> 1)
  17. T SinAlpha = sin(Alpha);
  18. // this breaks down when SinAlpha = 0, i.e. Alpha = 0 or pi
  19. T t1 = sin((static_cast<T>(1) - a) * Alpha) / SinAlpha;
  20. T t2 = sin(a * Alpha) / SinAlpha;
  21. // interpolate src vectors
  22. return x * t1 + y * t2;
  23. }
  24. template<typename T, qualifier Q>
  25. GLM_FUNC_QUALIFIER vec<2, T, Q> rotate
  26. (
  27. vec<2, T, Q> const& v,
  28. T const& angle
  29. )
  30. {
  31. vec<2, T, Q> Result;
  32. T const Cos(cos(angle));
  33. T const Sin(sin(angle));
  34. Result.x = v.x * Cos - v.y * Sin;
  35. Result.y = v.x * Sin + v.y * Cos;
  36. return Result;
  37. }
  38. template<typename T, qualifier Q>
  39. GLM_FUNC_QUALIFIER vec<3, T, Q> rotate
  40. (
  41. vec<3, T, Q> const& v,
  42. T const& angle,
  43. vec<3, T, Q> const& normal
  44. )
  45. {
  46. return mat<3, 3, T, Q>(glm::rotate(angle, normal)) * v;
  47. }
  48. /*
  49. template<typename T, qualifier Q>
  50. GLM_FUNC_QUALIFIER vec<3, T, Q> rotateGTX(
  51. const vec<3, T, Q>& x,
  52. T angle,
  53. const vec<3, T, Q>& normal)
  54. {
  55. const T Cos = cos(radians(angle));
  56. const T Sin = sin(radians(angle));
  57. return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin;
  58. }
  59. */
  60. template<typename T, qualifier Q>
  61. GLM_FUNC_QUALIFIER vec<4, T, Q> rotate
  62. (
  63. vec<4, T, Q> const& v,
  64. T const& angle,
  65. vec<3, T, Q> const& normal
  66. )
  67. {
  68. return rotate(angle, normal) * v;
  69. }
  70. template<typename T, qualifier Q>
  71. GLM_FUNC_QUALIFIER vec<3, T, Q> rotateX
  72. (
  73. vec<3, T, Q> const& v,
  74. T const& angle
  75. )
  76. {
  77. vec<3, T, Q> Result(v);
  78. T const Cos(cos(angle));
  79. T const Sin(sin(angle));
  80. Result.y = v.y * Cos - v.z * Sin;
  81. Result.z = v.y * Sin + v.z * Cos;
  82. return Result;
  83. }
  84. template<typename T, qualifier Q>
  85. GLM_FUNC_QUALIFIER vec<3, T, Q> rotateY
  86. (
  87. vec<3, T, Q> const& v,
  88. T const& angle
  89. )
  90. {
  91. vec<3, T, Q> Result = v;
  92. T const Cos(cos(angle));
  93. T const Sin(sin(angle));
  94. Result.x = v.x * Cos + v.z * Sin;
  95. Result.z = -v.x * Sin + v.z * Cos;
  96. return Result;
  97. }
  98. template<typename T, qualifier Q>
  99. GLM_FUNC_QUALIFIER vec<3, T, Q> rotateZ
  100. (
  101. vec<3, T, Q> const& v,
  102. T const& angle
  103. )
  104. {
  105. vec<3, T, Q> Result = v;
  106. T const Cos(cos(angle));
  107. T const Sin(sin(angle));
  108. Result.x = v.x * Cos - v.y * Sin;
  109. Result.y = v.x * Sin + v.y * Cos;
  110. return Result;
  111. }
  112. template<typename T, qualifier Q>
  113. GLM_FUNC_QUALIFIER vec<4, T, Q> rotateX
  114. (
  115. vec<4, T, Q> const& v,
  116. T const& angle
  117. )
  118. {
  119. vec<4, T, Q> Result = v;
  120. T const Cos(cos(angle));
  121. T const Sin(sin(angle));
  122. Result.y = v.y * Cos - v.z * Sin;
  123. Result.z = v.y * Sin + v.z * Cos;
  124. return Result;
  125. }
  126. template<typename T, qualifier Q>
  127. GLM_FUNC_QUALIFIER vec<4, T, Q> rotateY
  128. (
  129. vec<4, T, Q> const& v,
  130. T const& angle
  131. )
  132. {
  133. vec<4, T, Q> Result = v;
  134. T const Cos(cos(angle));
  135. T const Sin(sin(angle));
  136. Result.x = v.x * Cos + v.z * Sin;
  137. Result.z = -v.x * Sin + v.z * Cos;
  138. return Result;
  139. }
  140. template<typename T, qualifier Q>
  141. GLM_FUNC_QUALIFIER vec<4, T, Q> rotateZ
  142. (
  143. vec<4, T, Q> const& v,
  144. T const& angle
  145. )
  146. {
  147. vec<4, T, Q> Result = v;
  148. T const Cos(cos(angle));
  149. T const Sin(sin(angle));
  150. Result.x = v.x * Cos - v.y * Sin;
  151. Result.y = v.x * Sin + v.y * Cos;
  152. return Result;
  153. }
  154. template<typename T, qualifier Q>
  155. GLM_FUNC_QUALIFIER mat<4, 4, T, Q> orientation
  156. (
  157. vec<3, T, Q> const& Normal,
  158. vec<3, T, Q> const& Up
  159. )
  160. {
  161. if(all(equal(Normal, Up, epsilon<T>())))
  162. return mat<4, 4, T, Q>(static_cast<T>(1));
  163. vec<3, T, Q> RotationAxis = cross(Up, Normal);
  164. T Angle = acos(dot(Normal, Up));
  165. return rotate(Angle, RotationAxis);
  166. }
  167. }//namespace glm