From 097c1f7b90faf1130009047b5165a50d87cc72a1 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 26 Oct 2014 20:34:10 +0100 Subject: [PATCH] Updated GTC_integer --- glm/gtc/integer.hpp | 51 +++++++++++++++------ glm/gtc/integer.inl | 78 ++++++++++++++++++++++++++++++-- test/gtc/gtc_integer.cpp | 97 +++++++++++++++++++++++++++++++++++----- 3 files changed, 198 insertions(+), 28 deletions(-) diff --git a/glm/gtc/integer.hpp b/glm/gtc/integer.hpp index a072b5b5..0ec280e3 100644 --- a/glm/gtc/integer.hpp +++ b/glm/gtc/integer.hpp @@ -41,6 +41,7 @@ // Dependencies #include "../detail/setup.hpp" #include "../detail/precision.hpp" +#include "../vector_relational.hpp" #include #if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) @@ -55,8 +56,8 @@ namespace glm /// Return true if the value is a power of two number. /// /// @see gtc_integer - template - GLM_FUNC_DECL bool isPowerOfTwo(genType Value); + template + GLM_FUNC_DECL bool isPowerOfTwo(genIUType Value); /// Return true if the value is a power of two number. /// @@ -64,29 +65,53 @@ namespace glm template class vecType> GLM_FUNC_DECL vecType isPowerOfTwo(vecType const & value); - /// Find the highest bit set to 1 in a integer variable and return its value. + /// Find the highest bit set to 1 in a integer variable and return its value. /// /// @see gtc_integer - template - GLM_FUNC_DECL genType highestBitValue(genType const & value); + template + GLM_FUNC_DECL genIUType highestBitValue(genIUType Value); + + /// Find the highest bit set to 1 in a integer variable and return its value. + /// + /// @see gtc_integer + template class vecType> + GLM_FUNC_DECL vecType highestBitValue(vecType const & value); /// Return the power of two number which value is just higher the input value. /// /// @see gtc_integer - template - GLM_FUNC_DECL genType powerOfTwoAbove(genType const & value); + template + GLM_FUNC_DECL genIUType powerOfTwoAbove(genIUType Value); + + /// Return the power of two number which value is just higher the input value. + /// + /// @see gtc_integer + template class vecType> + GLM_FUNC_DECL vecType powerOfTwoAbove(vecType const & value); - /// Return the power of two number which value is just lower the input value. + /// Return the power of two number which value is just lower the input value. /// /// @see gtc_integer - template - GLM_FUNC_DECL genType powerOfTwoBelow(genType const & value); + template + GLM_FUNC_DECL genIUType powerOfTwoBelow(genIUType Value); - /// Return the power of two number which value is the closet to the input value. + /// Return the power of two number which value is just lower the input value. /// /// @see gtc_integer - template - GLM_FUNC_DECL genType powerOfTwoNearest(genType const & value); + template class vecType> + GLM_FUNC_DECL vecType powerOfTwoBelow(vecType const & value); + + /// Return the power of two number which value is the closet to the input value. + /// + /// @see gtc_integer + template + GLM_FUNC_DECL genIUType powerOfTwoNearest(genIUType Value); + + /// Return the power of two number which value is the closet to the input value. + /// + /// @see gtc_integer + template class vecType> + GLM_FUNC_DECL vecType powerOfTwoNearest(vecType const & value); /// @} } //namespace glm diff --git a/glm/gtc/integer.inl b/glm/gtc/integer.inl index db14286c..1e721447 100644 --- a/glm/gtc/integer.inl +++ b/glm/gtc/integer.inl @@ -39,9 +39,81 @@ namespace glm } template class vecType> - GLM_FUNC_QUALIFIER vecType isPowerOfTwo(vecType const & value) + GLM_FUNC_QUALIFIER vecType isPowerOfTwo(vecType const & Value) { - genType Result = glm::abs(Value); - return !(Result & (Result - 1)); + vecType Result(abs(Value)); + return equal(Result & (Result - 1), vecType(0)); + } + + /////////////////// + // highestBitValue + + template + GLM_FUNC_QUALIFIER genIUType highestBitValue(genIUType Value) + { + genIUType tmp = Value; + genIUType result = genIUType(0); + while(tmp) + { + result = (tmp & (~tmp + 1)); // grab lowest bit + tmp &= ~result; // clear lowest bit + } + return result; + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType highestBitValue(vecType const & v) + { + return detail::functor1::call(highestBitValue, v); + } + + /////////////////// + // powerOfTwoAbove + + template + GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType value) + { + return isPowerOfTwo(value) ? value : highestBitValue(value) << 1; + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType powerOfTwoAbove(vecType const & v) + { + return detail::functor1::call(powerOfTwoAbove, v); + } + + /////////////////// + // powerOfTwoBelow + + template + GLM_FUNC_QUALIFIER genType powerOfTwoBelow(genType value) + { + return isPowerOfTwo(value) ? value : highestBitValue(value); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType powerOfTwoBelow(vecType const & v) + { + return detail::functor1::call(powerOfTwoBelow, v); + } + + ///////////////////// + // powerOfTwoNearest + + template + GLM_FUNC_QUALIFIER genType powerOfTwoNearest(genType value) + { + if(isPowerOfTwo(value)) + return value; + + genType const prev = highestBitValue(value); + genType const next = prev << 1; + return (next - value) < (value - prev) ? next : prev; + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType powerOfTwoNearest(vecType const & v) + { + return detail::functor1::call(powerOfTwoNearest, v); } }//namespace glm diff --git a/test/gtc/gtc_integer.cpp b/test/gtc/gtc_integer.cpp index 2981897d..724f7db3 100644 --- a/test/gtc/gtc_integer.cpp +++ b/test/gtc/gtc_integer.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace isPowerOfTwo { @@ -19,9 +20,55 @@ namespace isPowerOfTwo bool Return; }; - int test_int() + int test_int16() { - type const DataI32[] = + type const Data[] = + { + {0x0001, true}, + {0x0002, true}, + {0x0004, true}, + {0x0080, true}, + {0x0000, true}, + {0x0003, false} + }; + + int Error(0); + + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } + + return Error; + } + + int test_uint16() + { + type const Data[] = + { + {0x0001, true}, + {0x0002, true}, + {0x0004, true}, + {0x0000, true}, + {0x0000, true}, + {0x0003, false} + }; + + int Error(0); + + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } + + return Error; + } + + int test_int32() + { + type const Data[] = { {0x00000001, true}, {0x00000002, true}, @@ -33,18 +80,42 @@ namespace isPowerOfTwo int Error(0); - for(std::size_t i = 0, n = sizeof(DataI32) / sizeof(type); i < n; ++i) + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; + } + + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + glm::bvec1 Result = glm::isPowerOfTwo(glm::ivec1(Data[i].Value)); + Error += glm::all(glm::equal(glm::bvec1(Data[i].Return), Result)) ? 0 : 1; + } + + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + glm::bvec2 Result = glm::isPowerOfTwo(glm::ivec2(Data[i].Value)); + Error += glm::all(glm::equal(glm::bvec2(Data[i].Return), Result)) ? 0 : 1; + } + + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) + { + glm::bvec3 Result = glm::isPowerOfTwo(glm::ivec3(Data[i].Value)); + Error += glm::all(glm::equal(glm::bvec3(Data[i].Return), Result)) ? 0 : 1; + } + + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) { - bool Result = glm::isPowerOfTwo(DataI32[i].Value); - Error += DataI32[i].Return == Result ? 0 : 1; + glm::bvec4 Result = glm::isPowerOfTwo(glm::ivec4(Data[i].Value)); + Error += glm::all(glm::equal(glm::bvec4(Data[i].Return), Result)) ? 0 : 1; } return Error; } - int test_uint() + int test_uint32() { - type const DataU32[] = + type const Data[] = { {0x00000001, true}, {0x00000002, true}, @@ -56,10 +127,10 @@ namespace isPowerOfTwo int Error(0); - for(std::size_t i = 0, n = sizeof(DataU32) / sizeof(type); i < n; ++i) + for(std::size_t i = 0, n = sizeof(Data) / sizeof(type); i < n; ++i) { - bool Result = glm::isPowerOfTwo(DataU32[i].Value); - Error += DataU32[i].Return == Result ? 0 : 1; + bool Result = glm::isPowerOfTwo(Data[i].Value); + Error += Data[i].Return == Result ? 0 : 1; } return Error; @@ -69,8 +140,10 @@ namespace isPowerOfTwo { int Error(0); - Error += test_int(); - Error += test_uint(); + Error += test_int16(); + Error += test_uint16(); + Error += test_int32(); + Error += test_uint32(); return Error; }