From b121e8758adedda960e28cece988430cb3dcac13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 8 Feb 2015 11:36:44 +0100 Subject: [PATCH] Math: added Vector::pad(). --- src/Magnum/Math/Test/Vector4Test.cpp | 12 ++++++++++++ src/Magnum/Math/Test/VectorTest.cpp | 25 +++++++++++++++++++++++++ src/Magnum/Math/Vector.h | 18 ++++++++++++++++++ src/Magnum/Math/Vector4.h | 15 +++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/src/Magnum/Math/Test/Vector4Test.cpp b/src/Magnum/Math/Test/Vector4Test.cpp index c60f86174..e340b4cd3 100644 --- a/src/Magnum/Math/Test/Vector4Test.cpp +++ b/src/Magnum/Math/Test/Vector4Test.cpp @@ -55,6 +55,7 @@ struct Vector4Test: Corrade::TestSuite::Tester { explicit Vector4Test(); void construct(); + void constructPad(); void constructDefault(); void constructOneValue(); void constructParts(); @@ -79,6 +80,7 @@ typedef Math::Vector2 Vector2; Vector4Test::Vector4Test() { addTests({&Vector4Test::construct, + &Vector4Test::constructPad, &Vector4Test::constructDefault, &Vector4Test::constructOneValue, &Vector4Test::constructParts, @@ -101,6 +103,16 @@ void Vector4Test::construct() { CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f))); } +void Vector4Test::constructPad() { + constexpr Vector<2, Float> a{3.0f, -1.0f}; + constexpr Vector4 b = Vector4::pad(a); + constexpr Vector4 c = Vector4::pad(a, 5.0f); + constexpr Vector4 d = Vector4::pad(a, 5.0f, 1.0f); + CORRADE_COMPARE(b, Vector4(3.0f, -1.0f, 0.0f, 0.0f)); + CORRADE_COMPARE(c, Vector4(3.0f, -1.0f, 5.0f, 5.0f)); + CORRADE_COMPARE(d, Vector4(3.0f, -1.0f, 5.0f, 1.0f)); +} + void Vector4Test::constructDefault() { constexpr Vector4 a; CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); diff --git a/src/Magnum/Math/Test/VectorTest.cpp b/src/Magnum/Math/Test/VectorTest.cpp index 426ffbe46..5980b2c44 100644 --- a/src/Magnum/Math/Test/VectorTest.cpp +++ b/src/Magnum/Math/Test/VectorTest.cpp @@ -56,6 +56,7 @@ struct VectorTest: Corrade::TestSuite::Tester { void construct(); void constructFromData(); + void constructPad(); void constructDefault(); void constructOneValue(); void constructOneComponent(); @@ -111,6 +112,7 @@ typedef Vector<4, Int> Vector4i; VectorTest::VectorTest() { addTests({&VectorTest::construct, &VectorTest::constructFromData, + &VectorTest::constructPad, &VectorTest::constructDefault, &VectorTest::constructOneValue, &VectorTest::constructOneComponent, @@ -168,6 +170,18 @@ void VectorTest::constructFromData() { CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f)); } +void VectorTest::constructPad() { + constexpr Vector<2, Float> a{1.0f, -1.0f}; + constexpr Vector4 b = Vector4::pad(a); + constexpr Vector4 c = Vector4::pad(a, 5.0f); + CORRADE_COMPARE(b, Vector4(1.0f, -1.0f, 0.0f, 0.0f)); + CORRADE_COMPARE(c, Vector4(1.0f, -1.0f, 5.0f, 5.0f)); + + constexpr Vector<5, Float> d{1.0f, -1.0f, 8.0f, 2.3f, -1.1f}; + constexpr Vector4 e = Vector4::pad(d); + CORRADE_COMPARE(e, Vector4(1.0f, -1.0f, 8.0f, 2.3f)); +} + void VectorTest::constructDefault() { constexpr Vector4 a; CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); @@ -451,6 +465,9 @@ void VectorTest::subclassTypes() { CORRADE_VERIFY((std::is_same::value)); CORRADE_VERIFY((std::is_same::value)); + Vector<1, Float> one; + CORRADE_VERIFY((std::is_same::value)); + /* Const operators */ const Vec2 c; const Vec2 c2; @@ -518,6 +535,14 @@ void VectorTest::subclass() { const Float cdata[] = {1.0f, -2.0f}; CORRADE_COMPARE(Vec2::from(cdata), Vec2(1.0f, -2.0f)); + { + constexpr Vector<1, Float> a = 5.0f; + constexpr Vec2 b = Vec2::pad(a); + constexpr Vec2 c = Vec2::pad(a, -1.0f); + CORRADE_COMPARE(b, Vec2(5.0f, 0.0f)); + CORRADE_COMPARE(c, Vec2(5.0f, -1.0f)); + } + CORRADE_COMPARE(Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f), Vec2(-1.0f, 2.0f)); CORRADE_COMPARE(Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f), Vec2(-3.0f, 8.0f)); diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index bbf78013e..d40ccb963 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -78,6 +78,17 @@ template class Vector { return *reinterpret_cast*>(data); } + /** + * @brief Pad vector + * + * If size of @p a is smaller than @ref Size, it is padded from right + * with @p value, otherwise it's cut. + * @see @ref Vector4::pad(const Vector&, T, T) + */ + template constexpr static Vector pad(const Vector& a, T value = T(0)) { + return padInternal(typename Implementation::GenerateSequence::Type(), a, value); + } + /** * @brief Dot product * @@ -505,6 +516,10 @@ template class Vector { /* Implementation for Vector::Vector(U) */ template constexpr explicit Vector(Implementation::Sequence, T value): _data{Implementation::repeat(value, sequence)...} {} + template constexpr static Vector padInternal(Implementation::Sequence, const Vector& a, T value) { + return {sequence < otherSize ? a[sequence] : value...}; + } + T _data[size]; }; @@ -1032,6 +1047,9 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit } \ static const Type& from(const T* data) { \ return *reinterpret_cast*>(data); \ + } \ + template constexpr static Type pad(const Math::Vector& a, T value = T(0)) { \ + return Math::Vector::pad(a, value); \ } \ \ Type& operator=(const Type& other) { \ diff --git a/src/Magnum/Math/Vector4.h b/src/Magnum/Math/Vector4.h index 07a5c648a..cb958154b 100644 --- a/src/Magnum/Math/Vector4.h +++ b/src/Magnum/Math/Vector4.h @@ -44,6 +44,21 @@ See @ref matrix-vector for brief introduction. */ template class Vector4: public Vector<4, T> { public: + /** + * @brief Pad vector to four-component one + * + * If size of @p a is smaller than 4, it is padded from right with + * @p xyz for first three component and @p w for fourth component, + * otherwise it's cut. + * @see @ref pad(const Vector&, T) + */ + template constexpr static Vector4 pad(const Vector& a, T xyz, T w) { + return {0 < otherSize ? a[0] : xyz, + 1 < otherSize ? a[1] : xyz, + 2 < otherSize ? a[2] : xyz, + 3 < otherSize ? a[3] : w}; + } + /** @copydoc Vector::Vector() */ constexpr /*implicit*/ Vector4() {}