round.inl 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /// @ref gtc_round
  2. #include "../integer.hpp"
  3. #include "../ext/vector_integer.hpp"
  4. namespace glm{
  5. namespace detail
  6. {
  7. template<bool is_float, bool is_signed>
  8. struct compute_roundMultiple {};
  9. template<>
  10. struct compute_roundMultiple<true, true>
  11. {
  12. template<typename genType>
  13. GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
  14. {
  15. if (Source >= genType(0))
  16. return Source - std::fmod(Source, Multiple);
  17. else
  18. {
  19. genType Tmp = Source + genType(1);
  20. return Tmp - std::fmod(Tmp, Multiple) - Multiple;
  21. }
  22. }
  23. };
  24. template<>
  25. struct compute_roundMultiple<false, false>
  26. {
  27. template<typename genType>
  28. GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
  29. {
  30. if (Source >= genType(0))
  31. return Source - Source % Multiple;
  32. else
  33. {
  34. genType Tmp = Source + genType(1);
  35. return Tmp - Tmp % Multiple - Multiple;
  36. }
  37. }
  38. };
  39. template<>
  40. struct compute_roundMultiple<false, true>
  41. {
  42. template<typename genType>
  43. GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
  44. {
  45. if (Source >= genType(0))
  46. return Source - Source % Multiple;
  47. else
  48. {
  49. genType Tmp = Source + genType(1);
  50. return Tmp - Tmp % Multiple - Multiple;
  51. }
  52. }
  53. };
  54. }//namespace detail
  55. //////////////////
  56. // ceilPowerOfTwo
  57. template<typename genType>
  58. GLM_FUNC_QUALIFIER genType ceilPowerOfTwo(genType value)
  59. {
  60. return detail::compute_ceilPowerOfTwo<1, genType, defaultp, std::numeric_limits<genType>::is_signed>::call(vec<1, genType, defaultp>(value)).x;
  61. }
  62. template<length_t L, typename T, qualifier Q>
  63. GLM_FUNC_QUALIFIER vec<L, T, Q> ceilPowerOfTwo(vec<L, T, Q> const& v)
  64. {
  65. return detail::compute_ceilPowerOfTwo<L, T, Q, std::numeric_limits<T>::is_signed>::call(v);
  66. }
  67. ///////////////////
  68. // floorPowerOfTwo
  69. template<typename genType>
  70. GLM_FUNC_QUALIFIER genType floorPowerOfTwo(genType value)
  71. {
  72. return isPowerOfTwo(value) ? value : static_cast<genType>(1) << findMSB(value);
  73. }
  74. template<length_t L, typename T, qualifier Q>
  75. GLM_FUNC_QUALIFIER vec<L, T, Q> floorPowerOfTwo(vec<L, T, Q> const& v)
  76. {
  77. return detail::functor1<vec, L, T, T, Q>::call(floorPowerOfTwo, v);
  78. }
  79. ///////////////////
  80. // roundPowerOfTwo
  81. template<typename genIUType>
  82. GLM_FUNC_QUALIFIER genIUType roundPowerOfTwo(genIUType value)
  83. {
  84. if(isPowerOfTwo(value))
  85. return value;
  86. genIUType const prev = static_cast<genIUType>(1) << findMSB(value);
  87. genIUType const next = prev << static_cast<genIUType>(1);
  88. return (next - value) < (value - prev) ? next : prev;
  89. }
  90. template<length_t L, typename T, qualifier Q>
  91. GLM_FUNC_QUALIFIER vec<L, T, Q> roundPowerOfTwo(vec<L, T, Q> const& v)
  92. {
  93. return detail::functor1<vec, L, T, T, Q>::call(roundPowerOfTwo, v);
  94. }
  95. //////////////////////
  96. // ceilMultiple
  97. template<typename genType>
  98. GLM_FUNC_QUALIFIER genType ceilMultiple(genType Source, genType Multiple)
  99. {
  100. return detail::compute_ceilMultiple<std::numeric_limits<genType>::is_iec559, std::numeric_limits<genType>::is_signed>::call(Source, Multiple);
  101. }
  102. template<length_t L, typename T, qualifier Q>
  103. GLM_FUNC_QUALIFIER vec<L, T, Q> ceilMultiple(vec<L, T, Q> const& Source, vec<L, T, Q> const& Multiple)
  104. {
  105. return detail::functor2<vec, L, T, Q>::call(ceilMultiple, Source, Multiple);
  106. }
  107. //////////////////////
  108. // floorMultiple
  109. template<typename genType>
  110. GLM_FUNC_QUALIFIER genType floorMultiple(genType Source, genType Multiple)
  111. {
  112. return detail::compute_floorMultiple<std::numeric_limits<genType>::is_iec559, std::numeric_limits<genType>::is_signed>::call(Source, Multiple);
  113. }
  114. template<length_t L, typename T, qualifier Q>
  115. GLM_FUNC_QUALIFIER vec<L, T, Q> floorMultiple(vec<L, T, Q> const& Source, vec<L, T, Q> const& Multiple)
  116. {
  117. return detail::functor2<vec, L, T, Q>::call(floorMultiple, Source, Multiple);
  118. }
  119. //////////////////////
  120. // roundMultiple
  121. template<typename genType>
  122. GLM_FUNC_QUALIFIER genType roundMultiple(genType Source, genType Multiple)
  123. {
  124. return detail::compute_roundMultiple<std::numeric_limits<genType>::is_iec559, std::numeric_limits<genType>::is_signed>::call(Source, Multiple);
  125. }
  126. template<length_t L, typename T, qualifier Q>
  127. GLM_FUNC_QUALIFIER vec<L, T, Q> roundMultiple(vec<L, T, Q> const& Source, vec<L, T, Q> const& Multiple)
  128. {
  129. return detail::functor2<vec, L, T, Q>::call(roundMultiple, Source, Multiple);
  130. }
  131. }//namespace glm