From 86c58b8b8be2dd967f3311078d911d3382be41cf Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Thu, 10 Mar 2016 21:53:08 +0100 Subject: [PATCH] Added iround and uround to GTC_integer, fast round on positive values --- glm/gtc/integer.hpp | 13 +++++++++++++ glm/gtc/integer.inl | 19 ++++++++++++++++++- readme.md | 2 +- test/gtc/gtc_integer.cpp | 19 +++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/glm/gtc/integer.hpp b/glm/gtc/integer.hpp index ef0df86e..714e4c5a 100644 --- a/glm/gtc/integer.hpp +++ b/glm/gtc/integer.hpp @@ -99,6 +99,19 @@ namespace glm template class vecType> GLM_FUNC_DECL vecType mod(vecType const & x, vecType const & y); + /// 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. + /// @tparam vecType vector types. + /// + /// @see GLSL round man page + /// @see gtc_integer + template class vecType> + GLM_FUNC_DECL vecType iround(vecType 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. diff --git a/glm/gtc/integer.inl b/glm/gtc/integer.inl index d57f906e..2c4d7c40 100644 --- a/glm/gtc/integer.inl +++ b/glm/gtc/integer.inl @@ -62,11 +62,28 @@ 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 class vecType> + GLM_FUNC_QUALIFIER vecType iround(vecType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(all(lessThanEqual(vecType(0), x))); + + return vecType(x + static_cast(0.5)); + } template GLM_FUNC_QUALIFIER uint uround(genType x) { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + 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)); diff --git a/readme.md b/readme.md index d842fb7e..78c40184 100644 --- a/readme.md +++ b/readme.md @@ -61,7 +61,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate) - Added 16bit pack and unpack to GTC_packing - Added 8bit pack and unpack to GTC_packing - Added missing bvec* && and || operators -- Added uround to GTC_integer, fast round on positive values +- Added iround and uround to GTC_integer, fast round on positive values ##### Improvements: - Improved GTC_random linearRand documentation diff --git a/test/gtc/gtc_integer.cpp b/test/gtc/gtc_integer.cpp index 36bfc44e..4c320b0d 100644 --- a/test/gtc/gtc_integer.cpp +++ b/test/gtc/gtc_integer.cpp @@ -210,6 +210,24 @@ namespace log2_ } }//namespace log2_ +namespace iround +{ + int test() + { + int Error = 0; + + for(float f = 0.0f; f < 3.1f; f += 0.05f) + { + int RoundFast = glm::iround(f); + int RoundSTD = glm::round(f); + Error += RoundFast == RoundSTD ? 0 : 1; + assert(!Error); + } + + return Error; + } +}//namespace iround + namespace uround { int test() @@ -233,6 +251,7 @@ int main() int Error(0); Error += ::log2_::test(); + Error += ::iround::test(); Error += ::uround::test(); # ifdef NDEBUG