diff --git a/glm/gtc/integer.inl b/glm/gtc/integer.inl index e8933284..8ddf1238 100644 --- a/glm/gtc/integer.inl +++ b/glm/gtc/integer.inl @@ -61,14 +61,5 @@ namespace detail } }; # endif//GLM_HAS_BITSCAN_WINDOWS - - template class vecType, typename genType> - struct compute_mod - { - GLM_FUNC_QUALIFIER static vecType call(vecType const & a, genType const & b) - { - return a % b; - } - }; }//namespace detail }//namespace glm diff --git a/glm/gtx/common.hpp b/glm/gtx/common.hpp index 27a00fda..0c11f843 100644 --- a/glm/gtx/common.hpp +++ b/glm/gtx/common.hpp @@ -68,6 +68,14 @@ namespace glm template GLM_FUNC_DECL typename genType::bool_type isdenormal(genType const & x); + /// Similiar to 'mod' but with a different rounding and integer support. + /// Returns 'x - y * trunc(x/y)' instead of 'x - y * floor(x/y)' + /// + /// @see GLSL mod vs HLSL fmod + /// @see GLSL mod man page + template class vecType> + GLM_FUNC_DECL vecType fmod(vecType const & v); + /// @} }//namespace glm diff --git a/glm/gtx/common.inl b/glm/gtx/common.inl index 05e02d67..337abfeb 100644 --- a/glm/gtx/common.inl +++ b/glm/gtx/common.inl @@ -32,8 +32,28 @@ #include -namespace glm +namespace glm{ +namespace detail { + template class vecType, bool isFloat = true> + struct compute_fmod + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & a, vecType const & b) + { + return detail::functor2::call(std::fmod, a, b); + } + }; + + template class vecType> + struct compute_fmod + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & a, vecType const & b) + { + return a % b; + } + }; +}//namespace detail + template GLM_FUNC_QUALIFIER bool isdenormal(T const & x) { @@ -99,4 +119,23 @@ namespace glm isdenormal(x.z), isdenormal(x.w)); } + + // fmod + template + GLM_FUNC_QUALIFIER genType fmod(genType x, genType y) + { + return fmod(tvec1(x), y).x; + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType fmod(vecType const & x, T y) + { + return detail::compute_fmod::is_iec559>::call(x, vecType(y)); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType fmod(vecType const & x, vecType const & y) + { + return detail::compute_fmod::is_iec559>::call(x, y); + } }//namespace glm diff --git a/readme.txt b/readme.txt index 2d92abc4..b28ce762 100644 --- a/readme.txt +++ b/readme.txt @@ -67,12 +67,16 @@ http://glm.g-truc.net/glm.pdf GLM 0.9.7.0: 2015-XX-XX -------------------------------------------------------------------------------- Features: -- Added GTC_color: rgbToSrgb and srgbToRgb functions +- Added GTC_color: convertRgbToSrgb and convertSrgbToRgb functions +- Added 'fmod' overload to GTX_common with tests #308 Improvements: - Changed usage of __has_include to support Intel compiler #307 - Specialized integer implementation of YCoCg-R #310 +Deprecation: +- Removed integer specification for 'mod' in GTC_integer #308 + ================================================================================ GLM 0.9.6.2: 2015-02-15 -------------------------------------------------------------------------------- diff --git a/test/core/core_func_trigonometric.cpp b/test/core/core_func_trigonometric.cpp index 494d9967..fa391151 100644 --- a/test/core/core_func_trigonometric.cpp +++ b/test/core/core_func_trigonometric.cpp @@ -30,7 +30,13 @@ /////////////////////////////////////////////////////////////////////////////////// #include - +/* +float sin(float x) { + float temp; + temp = (x + M_PI) / ((2 * M_PI) - M_PI); + return limited_sin((x + M_PI) - ((2 * M_PI) - M_PI) * temp)); +} +*/ int main() { int Failed = 0; diff --git a/test/gtc/gtc_integer.cpp b/test/gtc/gtc_integer.cpp index 6f7d4654..64d9377c 100644 --- a/test/gtc/gtc_integer.cpp +++ b/test/gtc/gtc_integer.cpp @@ -42,6 +42,7 @@ #include #include #include +#include namespace log2_ { @@ -210,70 +211,11 @@ namespace log2_ } }//namespace log2_ -namespace mod_ -{ - int test() - { - int Error(0); - - { - float A(3.0); - float B(2.0f); - float C = glm::mod(A, B); - - Error += glm::abs(C - 1.0f) < 0.00001f ? 0 : 1; - } - - { - glm::vec4 A(3.0); - float B(2.0f); - glm::vec4 C = glm::mod(A, B); - - Error += glm::all(glm::epsilonEqual(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1; - } - - { - glm::vec4 A(3.0); - glm::vec4 B(2.0f); - glm::vec4 C = glm::mod(A, B); - - Error += glm::all(glm::epsilonEqual(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1; - } - - { - int A(3); - int B(2); - int C = glm::mod(A, B); - - Error += C == 1 ? 0 : 1; - } - - { - glm::ivec4 A(3); - int B(2); - glm::ivec4 C = glm::mod(A, B); - - Error += glm::all(glm::equal(C, glm::ivec4(1))) ? 0 : 1; - } - - { - glm::ivec4 A(3); - glm::ivec4 B(2); - glm::ivec4 C = glm::mod(A, B); - - Error += glm::all(glm::equal(C, glm::ivec4(1))) ? 0 : 1; - } - - return Error; - } -}//namespace mod_ - int main() { int Error(0); Error += ::log2_::test(); - Error += ::mod_::test(); # ifdef NDEBUG Error += ::log2_::perf(); diff --git a/test/gtx/gtx_common.cpp b/test/gtx/gtx_common.cpp index 08358bce..37819aa5 100644 --- a/test/gtx/gtx_common.cpp +++ b/test/gtx/gtx_common.cpp @@ -30,6 +30,109 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include +#include +#include +#include + +namespace fmod_ +{ + template + GLM_FUNC_QUALIFIER genType modTrunc(genType a, genType b) + { + return a - b * trunc(a / b); + } + + int test() + { + int Error(0); + + { + float A0(3.0); + float B0(2.0f); + float C0 = glm::fmod(A0, B0); + + Error += glm::abs(C0 - 1.0f) < 0.00001f ? 0 : 1; + + glm::vec4 A1(3.0); + float B1(2.0f); + glm::vec4 C1 = glm::fmod(A1, B1); + + Error += glm::all(glm::epsilonEqual(C1, glm::vec4(1.0f), 0.00001f)) ? 0 : 1; + + glm::vec4 A2(3.0); + glm::vec4 B2(2.0f); + glm::vec4 C2 = glm::fmod(A2, B2); + + Error += glm::all(glm::epsilonEqual(C2, glm::vec4(1.0f), 0.00001f)) ? 0 : 1; + + glm::ivec4 A3(3); + int B3(2); + glm::ivec4 C3 = glm::fmod(A3, B3); + + Error += glm::all(glm::equal(C3, glm::ivec4(1))) ? 0 : 1; + + glm::ivec4 A4(3); + glm::ivec4 B4(2); + glm::ivec4 C4 = glm::fmod(A4, B4); + + Error += glm::all(glm::equal(C4, glm::ivec4(1))) ? 0 : 1; + } + + { + float A0(22.0); + float B0(-10.0f); + float C0 = glm::fmod(A0, B0); + + Error += glm::abs(C0 - 2.0f) < 0.00001f ? 0 : 1; + + glm::vec4 A1(22.0); + float B1(-10.0f); + glm::vec4 C1 = glm::fmod(A1, B1); + + Error += glm::all(glm::epsilonEqual(C1, glm::vec4(2.0f), 0.00001f)) ? 0 : 1; + + glm::vec4 A2(22.0); + glm::vec4 B2(-10.0f); + glm::vec4 C2 = glm::fmod(A2, B2); + + Error += glm::all(glm::epsilonEqual(C2, glm::vec4(2.0f), 0.00001f)) ? 0 : 1; + + glm::ivec4 A3(22); + int B3(-10); + glm::ivec4 C3 = glm::fmod(A3, B3); + + Error += glm::all(glm::equal(C3, glm::ivec4(2))) ? 0 : 1; + + glm::ivec4 A4(22); + glm::ivec4 B4(-10); + glm::ivec4 C4 = glm::fmod(A4, B4); + + Error += glm::all(glm::equal(C4, glm::ivec4(2))) ? 0 : 1; + } + + // http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod + { + for (float y = -10.0f; y < 10.0f; y += 0.1f) + for (float x = -10.0f; x < 10.0f; x += 0.1f) + { + float const A(std::fmod(x, y)); + //float const B(std::remainder(x, y)); + float const C(glm::fmod(x, y)); + float const D(modTrunc(x, y)); + + //Error += glm::epsilonEqual(A, B, 0.0001f) ? 0 : 1; + //assert(!Error); + Error += glm::epsilonEqual(A, C, 0.0001f) ? 0 : 1; + assert(!Error); + Error += glm::epsilonEqual(A, D, 0.00001f) ? 0 : 1; + assert(!Error); + } + } + + return Error; + } +}//namespace fmod_ int test_isdenormal() { @@ -49,6 +152,7 @@ int main() int Error(0); Error += test_isdenormal(); + Error += ::fmod_::test(); return Error; } diff --git a/test/gtx/gtx_fast_trigonometry.cpp b/test/gtx/gtx_fast_trigonometry.cpp index 440e6a15..eb73157b 100644 --- a/test/gtx/gtx_fast_trigonometry.cpp +++ b/test/gtx/gtx_fast_trigonometry.cpp @@ -61,6 +61,14 @@ namespace fastCos namespace fastSin { + /* + float sin(float x) { + float temp; + temp = (x + M_PI) / ((2 * M_PI) - M_PI); + return limited_sin((x + M_PI) - ((2 * M_PI) - M_PI) * temp)); + } + */ + int perf() { const float begin = -glm::pi();