func_exponential.inl 4.4 KB

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