diff --git a/glm/ext/scalar_common.hpp b/glm/ext/scalar_common.hpp index aa5a1807..2cf7e2d5 100644 --- a/glm/ext/scalar_common.hpp +++ b/glm/ext/scalar_common.hpp @@ -151,6 +151,30 @@ namespace glm template GLM_FUNC_DECL genType mirrorRepeat(genType const& Texcoord); + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL int iround(genType const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL uint uround(genType const& x); + /// @} }//namespace glm diff --git a/glm/ext/scalar_common.inl b/glm/ext/scalar_common.inl index 7d9207af..2807a372 100644 --- a/glm/ext/scalar_common.inl +++ b/glm/ext/scalar_common.inl @@ -149,4 +149,22 @@ namespace glm genType const Mirror = Clamp + Rest; return mix(Rest, static_cast(1) - Rest, Mirror >= static_cast(1)); } + + template + GLM_FUNC_QUALIFIER int iround(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(static_cast(0.0) <= x); + + return static_cast(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER uint uround(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); + assert(static_cast(0.0) <= x); + + return static_cast(x + static_cast(0.5)); + } }//namespace glm diff --git a/glm/ext/vector_common.hpp b/glm/ext/vector_common.hpp index 521ec01e..c0a2858c 100644 --- a/glm/ext/vector_common.hpp +++ b/glm/ext/vector_common.hpp @@ -198,6 +198,30 @@ namespace glm template GLM_FUNC_DECL vec mirrorRepeat(vec const& Texcoord); + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec iround(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec uround(vec const& x); + /// @} }//namespace glm diff --git a/glm/ext/vector_common.inl b/glm/ext/vector_common.inl index 82d2c902..67817fc5 100644 --- a/glm/ext/vector_common.inl +++ b/glm/ext/vector_common.inl @@ -126,4 +126,22 @@ namespace glm vec const Mirror = Clamp + Rest; return mix(Rest, vec(1) - Rest, glm::greaterThanEqual(Mirror, vec(1))); } + + template + GLM_FUNC_QUALIFIER vec iround(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(all(lessThanEqual(vec(0), x))); + + return vec(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER vec uround(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); + assert(all(lessThanEqual(vec(0), x))); + + return vec(x + static_cast(0.5)); + } }//namespace glm diff --git a/glm/gtc/integer.hpp b/glm/gtc/integer.hpp index 64ce10bb..a2a5bf6e 100644 --- a/glm/gtc/integer.hpp +++ b/glm/gtc/integer.hpp @@ -19,6 +19,8 @@ #include "../common.hpp" #include "../integer.hpp" #include "../exponential.hpp" +#include "../ext/scalar_common.hpp" +#include "../ext/vector_common.hpp" #include #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) @@ -35,30 +37,6 @@ namespace glm template GLM_FUNC_DECL genIUType log2(genIUType x); - /// Returns a value equal to the nearest integer to x. - /// The fraction 0.5 will round in a direction chosen by the - /// implementation, presumably the direction that is fastest. - /// - /// @param x The values of the argument must be greater or equal to zero. - /// @tparam T floating point scalar types. - /// - /// @see GLSL round man page - /// @see gtc_integer - template - GLM_FUNC_DECL vec iround(vec const& x); - - /// Returns a value equal to the nearest integer to x. - /// The fraction 0.5 will round in a direction chosen by the - /// implementation, presumably the direction that is fastest. - /// - /// @param x The values of the argument must be greater or equal to zero. - /// @tparam T floating point scalar types. - /// - /// @see GLSL round man page - /// @see gtc_integer - template - GLM_FUNC_DECL vec uround(vec const& x); - /// @} } //namespace glm diff --git a/glm/gtc/integer.inl b/glm/gtc/integer.inl index f0a8b4f2..5f66dfe2 100644 --- a/glm/gtc/integer.inl +++ b/glm/gtc/integer.inl @@ -30,39 +30,4 @@ namespace detail }; # endif//GLM_HAS_BITSCAN_WINDOWS }//namespace detail - template - GLM_FUNC_QUALIFIER int iround(genType x) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); - assert(static_cast(0.0) <= x); - - return static_cast(x + static_cast(0.5)); - } - - template - GLM_FUNC_QUALIFIER vec iround(vec const& x) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); - assert(all(lessThanEqual(vec(0), x))); - - return vec(x + static_cast(0.5)); - } - - template - GLM_FUNC_QUALIFIER uint uround(genType x) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); - assert(static_cast(0.0) <= x); - - return static_cast(x + static_cast(0.5)); - } - - template - GLM_FUNC_QUALIFIER vec uround(vec const& x) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); - assert(all(lessThanEqual(vec(0), x))); - - return vec(x + static_cast(0.5)); - } }//namespace glm diff --git a/readme.md b/readme.md index 14ab327c..ee1ef937 100644 --- a/readme.md +++ b/readme.md @@ -57,6 +57,7 @@ glm::mat4 camera(float Translate, glm::vec2 const& Rotate) #### Features: - Added *GLM_EXT_scalar_reciprocal* with tests - Added *GLM_EXT_vector_reciprocal* with tests +- Added `glm::iround` and `glm::uround` to *GLM_EXT_scalar_common* and *GLM_EXT_vector_common* #### Improvements: - Added `constexpr` qualifier for `cross` product #1040 diff --git a/test/ext/ext_scalar_common.cpp b/test/ext/ext_scalar_common.cpp index d3d22fb2..917a242e 100644 --- a/test/ext/ext_scalar_common.cpp +++ b/test/ext/ext_scalar_common.cpp @@ -298,6 +298,36 @@ static int test_mirrorRepeat() return Error; } +static int test_iround() +{ + int Error = 0; + + for(float f = 0.0f; f < 3.1f; f += 0.05f) + { + int RoundFast = static_cast(glm::iround(f)); + int RoundSTD = static_cast(glm::round(f)); + Error += RoundFast == RoundSTD ? 0 : 1; + assert(!Error); + } + + return Error; +} + +static int test_uround() +{ + int Error = 0; + + for(float f = 0.0f; f < 3.1f; f += 0.05f) + { + int RoundFast = static_cast(glm::uround(f)); + int RoundSTD = static_cast(glm::round(f)); + Error += RoundFast == RoundSTD ? 0 : 1; + assert(!Error); + } + + return Error; +} + int main() { int Error = 0; @@ -323,5 +353,8 @@ int main() Error += test_mirrorClamp(); Error += test_mirrorRepeat(); + Error += test_iround(); + Error += test_uround(); + return Error; } diff --git a/test/ext/ext_vector_common.cpp b/test/ext/ext_vector_common.cpp index 344b669b..211003fc 100644 --- a/test/ext/ext_vector_common.cpp +++ b/test/ext/ext_vector_common.cpp @@ -303,6 +303,36 @@ static int test_mirrorRepeat() return Error; } +static int test_iround() +{ + int Error = 0; + + for(float f = 0.0f; f < 3.1f; f += 0.05f) + { + int RoundFast = static_cast(glm::iround(f)); + int RoundSTD = static_cast(glm::round(f)); + Error += RoundFast == RoundSTD ? 0 : 1; + assert(!Error); + } + + return Error; +} + +static int test_uround() +{ + int Error = 0; + + for(float f = 0.0f; f < 3.1f; f += 0.05f) + { + int RoundFast = static_cast(glm::uround(f)); + int RoundSTD = static_cast(glm::round(f)); + Error += RoundFast == RoundSTD ? 0 : 1; + assert(!Error); + } + + return Error; +} + int main() { int Error = 0; @@ -328,5 +358,8 @@ int main() Error += test_mirrorClamp(); Error += test_mirrorRepeat(); + Error += test_iround(); + Error += test_uround(); + return Error; }