func_exponential.inl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /// @ref core
  2. /// @file glm/detail/func_exponential.inl
  3. #include "func_vector_relational.hpp"
  4. #include "_vectorize.hpp"
  5. #include <limits>
  6. #include <cmath>
  7. #include <cassert>
  8. namespace glm{
  9. namespace detail
  10. {
  11. # if GLM_HAS_CXX11_STL
  12. using std::log2;
  13. # else
  14. template<typename genType>
  15. genType log2(genType Value)
  16. {
  17. return std::log(Value) * static_cast<genType>(1.4426950408889634073599246810019);
  18. }
  19. # endif
  20. template<length_t L, typename T, qualifier P, bool isFloat, bool Aligned>
  21. struct compute_log2
  22. {
  23. GLM_FUNC_QUALIFIER static vec<L, T, P> call(vec<L, T, P> const& v)
  24. {
  25. return detail::functor1<L, T, T, P>::call(log2, v);
  26. }
  27. };
  28. template<length_t L, typename T, qualifier P, bool Aligned>
  29. struct compute_sqrt
  30. {
  31. GLM_FUNC_QUALIFIER static vec<L, T, P> call(vec<L, T, P> const& x)
  32. {
  33. return detail::functor1<L, T, T, P>::call(std::sqrt, x);
  34. }
  35. };
  36. template<length_t L, typename T, qualifier P, bool Aligned>
  37. struct compute_inversesqrt
  38. {
  39. GLM_FUNC_QUALIFIER static vec<L, T, P> call(vec<L, T, P> const& x)
  40. {
  41. return static_cast<T>(1) / sqrt(x);
  42. }
  43. };
  44. template<length_t L, bool Aligned>
  45. struct compute_inversesqrt<L, float, lowp, Aligned>
  46. {
  47. GLM_FUNC_QUALIFIER static vec<L, float, lowp> call(vec<L, float, lowp> const& x)
  48. {
  49. vec<L, float, lowp> tmp(x);
  50. vec<L, float, lowp> xhalf(tmp * 0.5f);
  51. vec<L, uint, lowp>* p = reinterpret_cast<vec<L, uint, lowp>*>(const_cast<vec<L, float, lowp>*>(&x));
  52. vec<L, uint, lowp> i = vec<L, uint, lowp>(0x5f375a86) - (*p >> vec<L, uint, lowp>(1));
  53. vec<L, float, lowp>* ptmp = reinterpret_cast<vec<L, float, lowp>*>(&i);
  54. tmp = *ptmp;
  55. tmp = tmp * (1.5f - xhalf * tmp * tmp);
  56. return tmp;
  57. }
  58. };
  59. }//namespace detail
  60. // pow
  61. using std::pow;
  62. template<length_t L, typename T, qualifier P>
  63. GLM_FUNC_QUALIFIER vec<L, T, P> pow(vec<L, T, P> const& base, vec<L, T, P> const& exponent)
  64. {
  65. return detail::functor2<L, T, P>::call(pow, base, exponent);
  66. }
  67. // exp
  68. using std::exp;
  69. template<length_t L, typename T, qualifier P>
  70. GLM_FUNC_QUALIFIER vec<L, T, P> exp(vec<L, T, P> const& x)
  71. {
  72. return detail::functor1<L, T, T, P>::call(exp, x);
  73. }
  74. // log
  75. using std::log;
  76. template<length_t L, typename T, qualifier P>
  77. GLM_FUNC_QUALIFIER vec<L, T, P> log(vec<L, T, P> const& x)
  78. {
  79. return detail::functor1<L, T, T, P>::call(log, x);
  80. }
  81. //exp2, ln2 = 0.69314718055994530941723212145818f
  82. template<typename genType>
  83. GLM_FUNC_QUALIFIER genType exp2(genType x)
  84. {
  85. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'exp2' only accept floating-point inputs");
  86. return std::exp(static_cast<genType>(0.69314718055994530941723212145818) * x);
  87. }
  88. template<length_t L, typename T, qualifier P>
  89. GLM_FUNC_QUALIFIER vec<L, T, P> exp2(vec<L, T, P> const& x)
  90. {
  91. return detail::functor1<L, T, T, P>::call(exp2, x);
  92. }
  93. // log2, ln2 = 0.69314718055994530941723212145818f
  94. template<typename genType>
  95. GLM_FUNC_QUALIFIER genType log2(genType x)
  96. {
  97. return log2(vec<1, genType>(x)).x;
  98. }
  99. template<length_t L, typename T, qualifier P>
  100. GLM_FUNC_QUALIFIER vec<L, T, P> log2(vec<L, T, P> const& x)
  101. {
  102. return detail::compute_log2<L, T, P, std::numeric_limits<T>::is_iec559, detail::is_aligned<P>::value>::call(x);
  103. }
  104. // sqrt
  105. using std::sqrt;
  106. template<length_t L, typename T, qualifier P>
  107. GLM_FUNC_QUALIFIER vec<L, T, P> sqrt(vec<L, T, P> const& x)
  108. {
  109. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'sqrt' only accept floating-point inputs");
  110. return detail::compute_sqrt<L, T, P, detail::is_aligned<P>::value>::call(x);
  111. }
  112. // inversesqrt
  113. template<typename genType>
  114. GLM_FUNC_QUALIFIER genType inversesqrt(genType x)
  115. {
  116. return static_cast<genType>(1) / sqrt(x);
  117. }
  118. template<length_t L, typename T, qualifier P>
  119. GLM_FUNC_QUALIFIER vec<L, T, P> inversesqrt(vec<L, T, P> const& x)
  120. {
  121. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'inversesqrt' only accept floating-point inputs");
  122. return detail::compute_inversesqrt<L, T, P, detail::is_aligned<P>::value>::call(x);
  123. }
  124. }//namespace glm
  125. #if GLM_ARCH != GLM_ARCH_PURE && GLM_HAS_UNRESTRICTED_UNIONS
  126. # include "func_exponential_simd.inl"
  127. #endif