Browse Source

Math: added lerp(T, T, bool).

Last missing piece for fully orthogonal functionality. There was a
lerp(T, T, BoolVector) before, but not a scalar version. This also makes
scalar interpolation phase in select() working with arbitrary types.
pull/191/head
Vladimír Vondruš 8 years ago
parent
commit
da7d443b67
  1. 14
      src/Magnum/Math/Functions.h
  2. 16
      src/Magnum/Math/Test/FunctionsTest.cpp

14
src/Magnum/Math/Functions.h

@ -53,8 +53,9 @@ namespace Implementation {
template<class T> constexpr static T pow(T) { return T(1); }
};
template<class> struct IsBoolVector: std::false_type {};
template<std::size_t size> struct IsBoolVector<BoolVector<size>>: std::true_type {};
template<class> struct IsBoolVectorOrScalar: std::false_type {};
template<> struct IsBoolVectorOrScalar<bool>: std::true_type {};
template<std::size_t size> struct IsBoolVectorOrScalar<BoolVector<size>>: std::true_type {};
template<class T> struct IsVectorOrScalar: std::is_arithmetic<T>::type {};
template<template<class> class Derived, class T> struct IsVectorOrScalar<Unit<Derived, T>>: std::true_type {};
@ -562,7 +563,7 @@ See @ref select() for constant interpolation using the same API.
*/
template<class T, class U> inline
#ifndef DOXYGEN_GENERATING_OUTPUT
typename std::enable_if<Implementation::IsVectorOrScalar<T>::value && !Implementation::IsBoolVector<U>::value, T>::type
typename std::enable_if<Implementation::IsVectorOrScalar<T>::value && !Implementation::IsBoolVectorOrScalar<U>::value, T>::type
#else
T
#endif
@ -570,6 +571,13 @@ lerp(const T& a, const T& b, U t) {
return Implementation::lerp(a, b, t);
}
/** @overload
@m_keyword{mix(),GLSL mix(),}
*/
template<class T> inline T lerp(const T& a, const T& b, bool t) {
return t ? b : a;
}
/** @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.

16
src/Magnum/Math/Test/FunctionsTest.cpp

@ -27,7 +27,7 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/Functions.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/Math/Vector4.h"
namespace Magnum { namespace Math { namespace Test {
@ -59,6 +59,7 @@ struct FunctionsTest: Corrade::TestSuite::Tester {
void lerpBool();
void lerpInverted();
void select();
void selectBool();
void fma();
void logIntegral();
@ -77,6 +78,7 @@ typedef Math::Deg<Float> Deg;
typedef Math::Rad<Float> Rad;
typedef Math::Vector2<Float> Vector2;
typedef Math::Vector3<Float> Vector3;
typedef Math::Vector4<Float> Vector4;
typedef Math::Vector3<UnsignedByte> Vector3ub;
typedef Math::Vector3<Byte> Vector3b;
typedef Math::Vector3<Int> Vector3i;
@ -107,6 +109,7 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::lerpBool,
&FunctionsTest::lerpInverted,
&FunctionsTest::select,
&FunctionsTest::selectBool,
&FunctionsTest::fma,
&FunctionsTest::logIntegral,
@ -292,6 +295,11 @@ void FunctionsTest::lerp() {
}
void FunctionsTest::lerpBool() {
/* Scalar interpolation phase */
CORRADE_COMPARE(Math::lerp(Vector3i{1, 2, 3}, Vector3i{5, 6, 7}, true), (Vector3i{5, 6, 7}));
CORRADE_COMPARE(Math::lerp(BoolVector<3>{5}, BoolVector<3>{true}, false), BoolVector<3>{5});
/* Vector interpolation phase */
CORRADE_COMPARE(Math::lerp(Vector3i{1, 2, 3}, Vector3i{5, 6, 7}, BoolVector<3>(5)), (Vector3i{5, 2, 7}));
CORRADE_COMPARE(Math::lerp(BoolVector<3>{false}, BoolVector<3>{true}, BoolVector<3>(5)), BoolVector<3>{5});
}
@ -323,6 +331,12 @@ void FunctionsTest::select() {
CORRADE_COMPARE(Math::select(a, b, Vector3(0.25f, 1.5f, 1.0f)), Vector3(-1.0f, -2.0f, 11.0f));
}
void FunctionsTest::selectBool() {
CORRADE_COMPARE(Math::select(true, false, 0.5f), true);
CORRADE_COMPARE(Math::select(Math::BoolVector<4>{0xa}, Math::BoolVector<4>{0x5}, 1.1f), Math::BoolVector<4>{0x5});
CORRADE_COMPARE(Math::select(Math::BoolVector<4>{0xa}, Math::BoolVector<4>{0x5}, Vector4{1.1f, -1.0f, 1.3f, 0.5f}), Math::BoolVector<4>{0xf});
}
void FunctionsTest::fma() {
CORRADE_COMPARE(Math::fma(2.0f, 3.0f, 0.75f), 6.75f);
CORRADE_COMPARE(Math::fma(Vector3( 2.0f, 1.5f, 0.5f),

Loading…
Cancel
Save