func_geometric.inl 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #include "../exponential.hpp"
  2. #include "../common.hpp"
  3. namespace glm{
  4. namespace detail
  5. {
  6. template<length_t L, typename T, qualifier Q, bool Aligned>
  7. struct compute_length
  8. {
  9. GLM_FUNC_QUALIFIER static T call(vec<L, T, Q> const& v)
  10. {
  11. return sqrt(dot(v, v));
  12. }
  13. };
  14. template<length_t L, typename T, qualifier Q, bool Aligned>
  15. struct compute_distance
  16. {
  17. GLM_FUNC_QUALIFIER static T call(vec<L, T, Q> const& p0, vec<L, T, Q> const& p1)
  18. {
  19. return length(p1 - p0);
  20. }
  21. };
  22. template<typename V, typename T, bool Aligned>
  23. struct compute_dot{};
  24. template<typename T, qualifier Q, bool Aligned>
  25. struct compute_dot<vec<1, T, Q>, T, Aligned>
  26. {
  27. GLM_FUNC_QUALIFIER static T call(vec<1, T, Q> const& a, vec<1, T, Q> const& b)
  28. {
  29. return a.x * b.x;
  30. }
  31. };
  32. template<typename T, qualifier Q, bool Aligned>
  33. struct compute_dot<vec<2, T, Q>, T, Aligned>
  34. {
  35. GLM_FUNC_QUALIFIER static T call(vec<2, T, Q> const& a, vec<2, T, Q> const& b)
  36. {
  37. vec<2, T, Q> tmp(a * b);
  38. return tmp.x + tmp.y;
  39. }
  40. };
  41. template<typename T, qualifier Q, bool Aligned>
  42. struct compute_dot<vec<3, T, Q>, T, Aligned>
  43. {
  44. GLM_FUNC_QUALIFIER static T call(vec<3, T, Q> const& a, vec<3, T, Q> const& b)
  45. {
  46. vec<3, T, Q> tmp(a * b);
  47. return tmp.x + tmp.y + tmp.z;
  48. }
  49. };
  50. template<typename T, qualifier Q, bool Aligned>
  51. struct compute_dot<vec<4, T, Q>, T, Aligned>
  52. {
  53. GLM_FUNC_QUALIFIER static T call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  54. {
  55. vec<4, T, Q> tmp(a * b);
  56. return (tmp.x + tmp.y) + (tmp.z + tmp.w);
  57. }
  58. };
  59. template<typename T, qualifier Q, bool Aligned>
  60. struct compute_cross
  61. {
  62. GLM_FUNC_QUALIFIER static vec<3, T, Q> call(vec<3, T, Q> const& x, vec<3, T, Q> const& y)
  63. {
  64. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'cross' accepts only floating-point inputs");
  65. return vec<3, T, Q>(
  66. x.y * y.z - y.y * x.z,
  67. x.z * y.x - y.z * x.x,
  68. x.x * y.y - y.x * x.y);
  69. }
  70. };
  71. template<length_t L, typename T, qualifier Q, bool Aligned>
  72. struct compute_normalize
  73. {
  74. GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v)
  75. {
  76. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'normalize' accepts only floating-point inputs");
  77. return v * inversesqrt(dot(v, v));
  78. }
  79. };
  80. template<length_t L, typename T, qualifier Q, bool Aligned>
  81. struct compute_faceforward
  82. {
  83. GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& N, vec<L, T, Q> const& I, vec<L, T, Q> const& Nref)
  84. {
  85. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'normalize' accepts only floating-point inputs");
  86. return dot(Nref, I) < static_cast<T>(0) ? N : -N;
  87. }
  88. };
  89. template<length_t L, typename T, qualifier Q, bool Aligned>
  90. struct compute_reflect
  91. {
  92. GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& I, vec<L, T, Q> const& N)
  93. {
  94. return I - N * dot(N, I) * static_cast<T>(2);
  95. }
  96. };
  97. template<length_t L, typename T, qualifier Q, bool Aligned>
  98. struct compute_refract
  99. {
  100. GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& I, vec<L, T, Q> const& N, T eta)
  101. {
  102. T const dotValue(dot(N, I));
  103. T const k(static_cast<T>(1) - eta * eta * (static_cast<T>(1) - dotValue * dotValue));
  104. vec<L, T, Q> const Result =
  105. (k >= static_cast<T>(0)) ? (eta * I - (eta * dotValue + std::sqrt(k)) * N) : vec<L, T, Q>(0);
  106. return Result;
  107. }
  108. };
  109. }//namespace detail
  110. // length
  111. template<typename genType>
  112. GLM_FUNC_QUALIFIER genType length(genType x)
  113. {
  114. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'length' accepts only floating-point inputs");
  115. return abs(x);
  116. }
  117. template<length_t L, typename T, qualifier Q>
  118. GLM_FUNC_QUALIFIER T length(vec<L, T, Q> const& v)
  119. {
  120. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'length' accepts only floating-point inputs");
  121. return detail::compute_length<L, T, Q, detail::is_aligned<Q>::value>::call(v);
  122. }
  123. // distance
  124. template<typename genType>
  125. GLM_FUNC_QUALIFIER genType distance(genType const& p0, genType const& p1)
  126. {
  127. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'distance' accepts only floating-point inputs");
  128. return length(p1 - p0);
  129. }
  130. template<length_t L, typename T, qualifier Q>
  131. GLM_FUNC_QUALIFIER T distance(vec<L, T, Q> const& p0, vec<L, T, Q> const& p1)
  132. {
  133. return detail::compute_distance<L, T, Q, detail::is_aligned<Q>::value>::call(p0, p1);
  134. }
  135. // dot
  136. template<typename T>
  137. GLM_FUNC_QUALIFIER T dot(T x, T y)
  138. {
  139. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
  140. return x * y;
  141. }
  142. template<length_t L, typename T, qualifier Q>
  143. GLM_FUNC_QUALIFIER T dot(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
  144. {
  145. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
  146. return detail::compute_dot<vec<L, T, Q>, T, detail::is_aligned<Q>::value>::call(x, y);
  147. }
  148. // cross
  149. template<typename T, qualifier Q>
  150. GLM_FUNC_QUALIFIER vec<3, T, Q> cross(vec<3, T, Q> const& x, vec<3, T, Q> const& y)
  151. {
  152. return detail::compute_cross<T, Q, detail::is_aligned<Q>::value>::call(x, y);
  153. }
  154. /*
  155. // normalize
  156. template<typename genType>
  157. GLM_FUNC_QUALIFIER genType normalize(genType const& x)
  158. {
  159. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'normalize' accepts only floating-point inputs");
  160. return x < genType(0) ? genType(-1) : genType(1);
  161. }
  162. */
  163. template<length_t L, typename T, qualifier Q>
  164. GLM_FUNC_QUALIFIER vec<L, T, Q> normalize(vec<L, T, Q> const& x)
  165. {
  166. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'normalize' accepts only floating-point inputs");
  167. return detail::compute_normalize<L, T, Q, detail::is_aligned<Q>::value>::call(x);
  168. }
  169. // faceforward
  170. template<typename genType>
  171. GLM_FUNC_QUALIFIER genType faceforward(genType const& N, genType const& I, genType const& Nref)
  172. {
  173. return dot(Nref, I) < static_cast<genType>(0) ? N : -N;
  174. }
  175. template<length_t L, typename T, qualifier Q>
  176. GLM_FUNC_QUALIFIER vec<L, T, Q> faceforward(vec<L, T, Q> const& N, vec<L, T, Q> const& I, vec<L, T, Q> const& Nref)
  177. {
  178. return detail::compute_faceforward<L, T, Q, detail::is_aligned<Q>::value>::call(N, I, Nref);
  179. }
  180. // reflect
  181. template<typename genType>
  182. GLM_FUNC_QUALIFIER genType reflect(genType const& I, genType const& N)
  183. {
  184. return I - N * dot(N, I) * genType(2);
  185. }
  186. template<length_t L, typename T, qualifier Q>
  187. GLM_FUNC_QUALIFIER vec<L, T, Q> reflect(vec<L, T, Q> const& I, vec<L, T, Q> const& N)
  188. {
  189. return detail::compute_reflect<L, T, Q, detail::is_aligned<Q>::value>::call(I, N);
  190. }
  191. // refract
  192. template<typename genType>
  193. GLM_FUNC_QUALIFIER genType refract(genType const& I, genType const& N, genType eta)
  194. {
  195. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'refract' accepts only floating-point inputs");
  196. genType const dotValue(dot(N, I));
  197. genType const k(static_cast<genType>(1) - eta * eta * (static_cast<genType>(1) - dotValue * dotValue));
  198. return (eta * I - (eta * dotValue + sqrt(k)) * N) * static_cast<genType>(k >= static_cast<genType>(0));
  199. }
  200. template<length_t L, typename T, qualifier Q>
  201. GLM_FUNC_QUALIFIER vec<L, T, Q> refract(vec<L, T, Q> const& I, vec<L, T, Q> const& N, T eta)
  202. {
  203. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'refract' accepts only floating-point inputs");
  204. return detail::compute_refract<L, T, Q, detail::is_aligned<Q>::value>::call(I, N, eta);
  205. }
  206. }//namespace glm
  207. #if GLM_CONFIG_SIMD == GLM_ENABLE
  208. # include "func_geometric_simd.inl"
  209. #endif