From 247d8dba6f9fcbaf313e695d516c082ac70fb410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 13 Nov 2015 00:36:23 +0100 Subject: [PATCH] Math: added lerp(T, T, BoolVector). In GLSL this is called mix() and I thought this is there for a long time, but apparently it got included only in GL 4.5 / ES 3.1. --- src/Magnum/Math/Functions.h | 28 ++++++++++++++++++++++++-- src/Magnum/Math/Test/FunctionsTest.cpp | 7 +++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 3c70d30f7..5663f0631 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -52,6 +52,9 @@ namespace Implementation { template constexpr static T pow(T) { return 1; } }; + + template struct IsBoolVector: std::false_type {}; + template struct IsBoolVector>: std::true_type {}; } /** @@ -409,14 +412,35 @@ The interpolation for vectors is done as in following, similarly for scalars: @f #ifdef DOXYGEN_GENERATING_OUTPUT template inline T lerp(const T& a, const T& b, U t); #else -template inline T lerp(T a, T b, U t) { +template inline typename std::enable_if::value, T>::type lerp(T a, T b, U t) { return T((U(1) - t)*a + t*b); } -template inline Vector lerp(const Vector& a, const Vector& b, U t) { +template inline typename std::enable_if::value, Vector>::type lerp(const Vector& a, const Vector& b, U t) { return (U(1) - t)*a + t*b; } #endif +/** +@overload + +Similar to the above, but instead of multiplication and addition it just does +component-wise selection from either @p a or @p b based on values in @p t. +*/ +template inline Vector lerp(const Vector& a, const Vector& b, const BoolVector& t) { + Vector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out[i] = t[i] ? a[i] : b[i]; + return out; +} + +/** @overload */ +template inline BoolVector lerp(const BoolVector& a, const BoolVector& b, const BoolVector& t) { + BoolVector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out.set(i, t[i] ? a[i] : b[i]); + return out; +} + /** @brief Inverse linear interpolation of two values @param a First value diff --git a/src/Magnum/Math/Test/FunctionsTest.cpp b/src/Magnum/Math/Test/FunctionsTest.cpp index 95275e652..103ae285e 100644 --- a/src/Magnum/Math/Test/FunctionsTest.cpp +++ b/src/Magnum/Math/Test/FunctionsTest.cpp @@ -52,6 +52,7 @@ struct FunctionsTest: Corrade::TestSuite::Tester { void sqrt(); void sqrtInverted(); void lerp(); + void lerpBool(); void lerpInverted(); void fma(); void normalizeUnsigned(); @@ -99,6 +100,7 @@ FunctionsTest::FunctionsTest() { &FunctionsTest::sqrt, &FunctionsTest::sqrtInverted, &FunctionsTest::lerp, + &FunctionsTest::lerpBool, &FunctionsTest::lerpInverted, &FunctionsTest::fma, &FunctionsTest::normalizeUnsigned, @@ -242,6 +244,11 @@ void FunctionsTest::lerp() { CORRADE_COMPARE(Math::lerp(a, b, Vector3(0.25f, 0.5f, 0.75f)), Vector3(0.0f, 0.0f, 9.0f)); } +void FunctionsTest::lerpBool() { + CORRADE_COMPARE(Math::lerp(Vector3i{1, 2, 3}, Vector3i{5, 6, 7}, BoolVector<3>(5)), (Vector3i{1, 6, 3})); + CORRADE_COMPARE(Math::lerp(BoolVector<3>{false}, BoolVector<3>{true}, BoolVector<3>(5)), BoolVector<3>{2}); +} + void FunctionsTest::lerpInverted() { /* Floating-point scalar */ CORRADE_COMPARE(Math::lerpInverted(2.0f, 5.0f, 3.5f), 0.5f);