Browse Source

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.
pull/120/head
Vladimír Vondruš 11 years ago
parent
commit
247d8dba6f
  1. 28
      src/Magnum/Math/Functions.h
  2. 7
      src/Magnum/Math/Test/FunctionsTest.cpp

28
src/Magnum/Math/Functions.h

@ -52,6 +52,9 @@ namespace Implementation {
template<class T> constexpr static T pow(T) { return 1; }
};
template<class> struct IsBoolVector: std::false_type {};
template<std::size_t size> struct IsBoolVector<BoolVector<size>>: 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<class T, class U> inline T lerp(const T& a, const T& b, U t);
#else
template<class T, class U> inline T lerp(T a, T b, U t) {
template<class T, class U> inline typename std::enable_if<!Implementation::IsBoolVector<U>::value, T>::type lerp(T a, T b, U t) {
return T((U(1) - t)*a + t*b);
}
template<std::size_t size, class T, class U> inline Vector<size, T> lerp(const Vector<size, T>& a, const Vector<size, T>& b, U t) {
template<std::size_t size, class T, class U> inline typename std::enable_if<!Implementation::IsBoolVector<U>::value, Vector<size, T>>::type lerp(const Vector<size, T>& a, const Vector<size, T>& 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<std::size_t size, class T> inline Vector<size, T> lerp(const Vector<size, T>& a, const Vector<size, T>& b, const BoolVector<size>& t) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = t[i] ? a[i] : b[i];
return out;
}
/** @overload */
template<std::size_t size> inline BoolVector<size> lerp(const BoolVector<size>& a, const BoolVector<size>& b, const BoolVector<size>& t) {
BoolVector<size> 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

7
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);

Loading…
Cancel
Save