Skip to content

Commit

Permalink
[WIP] Math: add separate units for C++14 Vector{,4}
Browse files Browse the repository at this point in the history
  • Loading branch information
sthalik committed Oct 10, 2022
1 parent e0c32cf commit c478e62
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 55 deletions.
7 changes: 7 additions & 0 deletions src/Magnum/Math/Test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ corrade_add_test(MathVectorTest VectorTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVector2Test Vector2Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVector3Test Vector3Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVector4Test Vector4Test.cpp LIBRARIES MagnumMathTestLib)

foreach(_test VectorTest Vector4Test)
corrade_add_test(Cpp14Math${_test} ${_test}.cpp LIBRARIES MagnumMathTestLib)
set_target_properties(Cpp14Math${_test} PROPERTIES CORRADE_CXX_STANDARD 14)
target_compile_definitions(Cpp14Math${_test} PRIVATE TESTING_CONSTEXPR)
endforeach()

corrade_add_test(MathColorTest ColorTest.cpp LIBRARIES MagnumMathTestLib)

corrade_add_test(MathRectangularMatrixTest RectangularMatrixTest.cpp LIBRARIES MagnumMathTestLib)
Expand Down
54 changes: 38 additions & 16 deletions src/Magnum/Math/Test/Vector4Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
#include "Magnum/Math/StrictWeakOrdering.h"
#include "Magnum/Math/Swizzle.h"

#define CE
#ifdef TESTING_CONSTEXPR
#if __cpp_constexpr >= 201304
#undef CE
#define CE constexpr
#else
#define SKIP_TESTING
#endif
#endif

struct Vec4 {
float x, y, z, w;
};
Expand Down Expand Up @@ -86,7 +96,9 @@ typedef Math::Vector3<Float> Vector3;
typedef Math::Vector2<Float> Vector2;

Vector4Test::Vector4Test() {
addTests({&Vector4Test::construct,
addTests({
#ifndef SKIP_TESTING
&Vector4Test::construct,
&Vector4Test::constructPad,
&Vector4Test::constructDefault,
&Vector4Test::constructNoInit,
Expand All @@ -106,9 +118,14 @@ Vector4Test::Vector4Test() {
&Vector4Test::strictWeakOrdering,

&Vector4Test::swizzleType,
&Vector4Test::debug});
&Vector4Test::debug
#else
&Vector4Test::skipTesting
#endif
});
}

#ifndef SKIP_TESTING
void Vector4Test::construct() {
constexpr Vector4 a = {1.0f, -2.5f, 3.0f, 4.1f};
CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f)));
Expand Down Expand Up @@ -228,7 +245,7 @@ void Vector4Test::convert() {
}

void Vector4Test::access() {
Vector4 vec(1.0f, -2.0f, 5.0f, 0.5f);
CE Vector4 vec(1.0f, -2.0f, 5.0f, 0.5f);
CORRADE_COMPARE(vec.x(), 1.0f);
CORRADE_COMPARE(vec.r(), 1.0f);
CORRADE_COMPARE(vec.y(), -2.0f);
Expand Down Expand Up @@ -258,7 +275,7 @@ void Vector4Test::access() {
}

void Vector4Test::threeComponent() {
Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CE Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CORRADE_COMPARE(a.xyz(), Vector3(1.0f, 2.0f, 3.0f));
CORRADE_COMPARE(a.rgb(), Vector3(1.0f, 2.0f, 3.0f));

Expand All @@ -270,7 +287,7 @@ void Vector4Test::threeComponent() {
}

void Vector4Test::twoComponent() {
Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CE Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CORRADE_COMPARE(a.xy(), Vector2(1.0f, 2.0f));

constexpr Vector4 b(1.0f, 2.0f, 3.0f, 4.0f);
Expand All @@ -281,9 +298,9 @@ void Vector4Test::twoComponent() {
}

void Vector4Test::planeEquationThreePoints() {
const Vector3 a{1.0f, 0.5f, 3.0f};
const Vector3 b{1.5f, 1.5f, 2.5f};
const Vector3 c{2.0f, 1.5f, 1.0f};
CE const Vector3 a{1.0f, 0.5f, 3.0f};
CE const Vector3 b{1.5f, 1.5f, 2.5f};
CE const Vector3 c{2.0f, 1.5f, 1.0f};
const Vector4 eq = Math::planeEquation(a, b, c);

CORRADE_COMPARE(Math::dot(a, eq.xyz()) + eq.w(), 0.0f);
Expand All @@ -296,12 +313,12 @@ void Vector4Test::planeEquationThreePoints() {
}

void Vector4Test::planeEquationNormalPoint() {
const Vector3 a{1.0f, 0.5f, 3.0f};
const Vector3 normal{-0.9045340f, 0.3015113f, -0.3015113f};
const Vector4 eq = Math::planeEquation(normal, a);
CE const Vector3 a{1.0f, 0.5f, 3.0f};
CE const Vector3 normal{-0.9045340f, 0.3015113f, -0.3015113f};
CE const Vector4 eq = Math::planeEquation(normal, a);

const Vector3 b{1.5f, 1.5f, 2.5f};
const Vector3 c{2.0f, 1.5f, 1.0f};
CE const Vector3 b{1.5f, 1.5f, 2.5f};
CE const Vector3 c{2.0f, 1.5f, 1.0f};
CORRADE_COMPARE(Math::dot(a, eq.xyz()) + eq.w(), 0.0f);
CORRADE_COMPARE(Math::dot(b, eq.xyz()) + eq.w(), 0.0f);
CORRADE_COMPARE(Math::dot(c, eq.xyz()) + eq.w(), 0.0f);
Expand All @@ -310,9 +327,9 @@ void Vector4Test::planeEquationNormalPoint() {

void Vector4Test::strictWeakOrdering() {
StrictWeakOrdering o;
const Vector4 v4a{1.0f, 2.0f, 3.0f, 4.0f};
const Vector4 v4b{2.0f, 3.0f, 4.0f, 5.0f};
const Vector4 v4c{1.0f, 2.0f, 3.0f, 5.0f};
CE const Vector4 v4a{1.0f, 2.0f, 3.0f, 4.0f};
CE const Vector4 v4b{2.0f, 3.0f, 4.0f, 5.0f};
CE const Vector4 v4c{1.0f, 2.0f, 3.0f, 5.0f};

CORRADE_VERIFY( o(v4a, v4b));
CORRADE_VERIFY(!o(v4b, v4a));
Expand All @@ -335,6 +352,11 @@ void Vector4Test::debug() {
Debug(&o) << Vector4(0.5f, 15.0f, 1.0f, 1.0f);
CORRADE_COMPARE(o.str(), "Vector(0.5, 15, 1, 1)\n");
}
#else
void VectorTest::skipTesting() {
CORRADE_SKIP("Relaxed constexpr not supported by the compiler.");
}
#endif

}}}}

Expand Down
104 changes: 65 additions & 39 deletions src/Magnum/Math/Test/VectorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@
#include "Magnum/Math/Vector.h"
#include "Magnum/Math/StrictWeakOrdering.h"

#define CE
#ifdef TESTING_CONSTEXPR
#if __cpp_constexpr >= 201304
#undef CE
#define CE constexpr
#else
#define SKIP_TESTING
#endif
#endif

struct Vec3 {
float x, y, z;
};
Expand Down Expand Up @@ -119,6 +129,8 @@ struct VectorTest: Corrade::TestSuite::Tester {

void debug();
void debugPacked();

[[maybe_unused]] void skipTesting();
};

typedef Math::Constants<Float> Constants;
Expand All @@ -133,7 +145,9 @@ typedef Vector<4, Int> Vector4i;
using namespace Literals;

VectorTest::VectorTest() {
addTests({&VectorTest::construct,
addTests({
#ifndef SKIP_TESTING
&VectorTest::construct,
&VectorTest::constructFromData,
&VectorTest::constructPad,
&VectorTest::constructPadDefaultHalf,
Expand Down Expand Up @@ -193,9 +207,14 @@ VectorTest::VectorTest() {
&VectorTest::strictWeakOrdering,

&VectorTest::debug,
&VectorTest::debugPacked});
&VectorTest::debugPacked
#else
&VectorTest::skipTesting
#endif
});
}

#ifndef SKIP_TESTING
void VectorTest::construct() {
constexpr Vector4 a = {1.0f, 2.0f, -3.0f, 4.5f};
CORRADE_COMPARE(a, Vector4(1.0f, 2.0f, -3.0f, 4.5f));
Expand Down Expand Up @@ -378,9 +397,9 @@ void VectorTest::compareComponentWise() {
typedef BitVector<3> BitVector3;
typedef BitVector<4> BitVector4;

Vector4 a{1.0f, -3.5f, 5.0f, -10.0f};
Vector4 b{1.0f + TypeTraits<Float>::epsilon()/2, -3.5f, 5.0f - TypeTraits<Float>::epsilon()*2, -10.0f};
Vector4 c{1.0f + TypeTraits<Float>::epsilon()*2, -3.5f, 5.0f - TypeTraits<Float>::epsilon()*10, -10.0f};
CE Vector4 a{1.0f, -3.5f, 5.0f, -10.0f};
CE Vector4 b{1.0f + TypeTraits<Float>::epsilon()/2, -3.5f, 5.0f - TypeTraits<Float>::epsilon()*2, -10.0f};
CE Vector4 c{1.0f + TypeTraits<Float>::epsilon()*2, -3.5f, 5.0f - TypeTraits<Float>::epsilon()*10, -10.0f};
CORRADE_COMPARE(equal(a, b), BitVector4{0xf});
CORRADE_COMPARE(equal(a, c), BitVector4{0xa});
CORRADE_COMPARE(notEqual(a, b), BitVector4{0x0});
Expand All @@ -400,31 +419,31 @@ void VectorTest::promotedNegated() {
}

void VectorTest::addSubtract() {
Vector4 a(1.0f, -3.0f, 5.0f, -10.0f);
Vector4 b(7.5f, 33.0f, -15.0f, 0.0f);
Vector4 c(8.5f, 30.0f, -10.0f, -10.0f);
CE Vector4 a(1.0f, -3.0f, 5.0f, -10.0f);
CE Vector4 b(7.5f, 33.0f, -15.0f, 0.0f);
CE Vector4 c(8.5f, 30.0f, -10.0f, -10.0f);

CORRADE_COMPARE(a + b, c);
CORRADE_COMPARE(c - b, a);
}

void VectorTest::multiplyDivide() {
Vector4 vector(1.0f, 2.0f, 3.0f, 4.0f);
Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f);
CE Vector4 vector(1.0f, 2.0f, 3.0f, 4.0f);
CE Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f);

CORRADE_COMPARE(vector*-1.5f, multiplied);
CORRADE_COMPARE(-1.5f*vector, multiplied);
CORRADE_COMPARE(multiplied/-1.5f, vector);

/* Divide vector with number and invert */
Vector4 divisor(1.0f, 2.0f, -4.0f, 8.0f);
Vector4 result(1.0f, 0.5f, -0.25f, 0.125f);
CE Vector4 divisor(1.0f, 2.0f, -4.0f, 8.0f);
CE Vector4 result(1.0f, 0.5f, -0.25f, 0.125f);
CORRADE_COMPARE(1.0f/divisor, result);
}

void VectorTest::multiplyDivideIntegral() {
Vector4i vector(32, 10, -6, 2);
Vector4i multiplied(-48, -15, 9, -3);
CE Vector4i vector(32, 10, -6, 2);
CE Vector4i multiplied(-48, -15, 9, -3);

CORRADE_COMPARE(vector*-1.5f, multiplied);
CORRADE_COMPARE(-1.5f*vector, multiplied);
Expand All @@ -434,18 +453,18 @@ void VectorTest::multiplyDivideIntegral() {
}

void VectorTest::multiplyDivideComponentWise() {
Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f);
Vector4 multiplier(7.0f, -4.0f, -1.5f, 1.0f);
Vector4 multiplied(7.0f, -8.0f, -4.5f, 4.0f);
CE Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f);
CE Vector4 multiplier(7.0f, -4.0f, -1.5f, 1.0f);
CE Vector4 multiplied(7.0f, -8.0f, -4.5f, 4.0f);

CORRADE_COMPARE(vec*multiplier, multiplied);
CORRADE_COMPARE(multiplied/multiplier, vec);
}

void VectorTest::multiplyDivideComponentWiseIntegral() {
Vector4i vec(7, 2, -16, -1);
Vector4 multiplier(2.0f, -1.5f, 0.5f, 10.0f);
Vector4i multiplied(14, -3, -8, -10);
CE Vector4i vec(7, 2, -16, -1);
CE Vector4 multiplier(2.0f, -1.5f, 0.5f, 10.0f);
CE Vector4i multiplied(14, -3, -8, -10);

CORRADE_COMPARE(vec*multiplier, multiplied);
CORRADE_COMPARE(multiplier*vec, multiplied);
Expand All @@ -457,23 +476,23 @@ void VectorTest::multiplyDivideComponentWiseIntegral() {
void VectorTest::modulo() {
typedef Math::Vector<2, Int> Vector2i;

const Vector2i a(4, 13);
const Vector2i b(2, 5);
CE const Vector2i a(4, 13);
CE const Vector2i b(2, 5);
CORRADE_COMPARE(a % 2, Vector2i(0, 1));
CORRADE_COMPARE(a % b, Vector2i(0, 3));
}

void VectorTest::bitwise() {
typedef Math::Vector<2, Int> Vector2i;

const Vector2i a(85, 240);
const Vector2i b(170, 85);
CE const Vector2i a(85, 240);
CE const Vector2i b(170, 85);
CORRADE_COMPARE(~a, Vector2i(-86, -241));
CORRADE_COMPARE(a & b, Vector2i(0, 80));
CORRADE_COMPARE(a | b, Vector2i(255, 245));
CORRADE_COMPARE(a ^ b, Vector2i(255, 165));

const Vector2i c(7, 32);
CE const Vector2i c(7, 32);
CORRADE_COMPARE(c << 2, Vector2i(28, 128));
CORRADE_COMPARE(c >> 2, Vector2i(1, 8));
}
Expand All @@ -487,11 +506,13 @@ void VectorTest::dotSelf() {
}

void VectorTest::length() {
CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).length(), 5.4772256f);
CE const Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CORRADE_COMPARE(a.length(), 5.4772256f);
}

void VectorTest::lengthInverted() {
CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).lengthInverted(), 0.182574f);
CE const Vector4 a(1.0f, 2.0f, 3.0f, 4.0f);
CORRADE_COMPARE(a.lengthInverted(), 0.182574f);
}

void VectorTest::normalized() {
Expand Down Expand Up @@ -525,7 +546,7 @@ void VectorTest::max() {
}

void VectorTest::minmax() {
const auto expected = std::make_pair(-3.0f, 2.0f);
CE const auto expected = std::make_pair(-3.0f, 2.0f);
CORRADE_COMPARE((Vector3{-1.0f, 2.0f, -3.0f}.minmax()), expected);
CORRADE_COMPARE((Vector3{-1.0f, -3.0f, 2.0f}.minmax()), expected);
CORRADE_COMPARE((Vector3{2.0f, -1.0f, -3.0f}.minmax()), expected);
Expand All @@ -535,9 +556,9 @@ void VectorTest::minmax() {
}

void VectorTest::nanIgnoring() {
Vector3 oneNan{1.0f, Constants::nan(), -3.0f};
Vector3 firstNan{Constants::nan(), 1.0f, -3.0f};
Vector3 allNan{Constants::nan(), Constants::nan(), Constants::nan()};
CE Vector3 oneNan{1.0f, Constants::nan(), -3.0f};
CE Vector3 firstNan{Constants::nan(), 1.0f, -3.0f};
CE Vector3 allNan{Constants::nan(), Constants::nan(), Constants::nan()};

CORRADE_COMPARE(oneNan.min(), -3.0f);
CORRADE_COMPARE(firstNan.min(), -3.0f);
Expand All @@ -555,16 +576,16 @@ void VectorTest::nanIgnoring() {
}

void VectorTest::projected() {
Vector3 line(1.0f, -1.0f, 0.5f);
Vector3 projected = Vector3(1.0f, 2.0f, 3.0f).projected(line);
CE Vector3 line(1.0f, -1.0f, 0.5f);
CE Vector3 projected = Vector3(1.0f, 2.0f, 3.0f).projected(line);

CORRADE_COMPARE(projected, Vector3(0.222222f, -0.222222f, 0.111111f));
CORRADE_COMPARE(projected.normalized(), line.normalized());
}

void VectorTest::projectedOntoNormalized() {
Vector3 vector(1.0f, 2.0f, 3.0f);
Vector3 line(1.0f, -1.0f, 0.5f);
CE Vector3 vector(1.0f, 2.0f, 3.0f);
CE Vector3 line(1.0f, -1.0f, 0.5f);

Vector3 projected = vector.projectedOntoNormalized(line.normalized());
CORRADE_COMPARE(projected, Vector3(0.222222f, -0.222222f, 0.111111f));
Expand Down Expand Up @@ -610,7 +631,7 @@ void VectorTest::angleNormalizedButOver1() {
/* This vector *is* normalized, but its length is larger than 1, which
would cause acos() to return a NaN. Ensure it's clamped to correct range
before passing it there. */
Vector3 a{1.0f + Math::TypeTraits<Float>::epsilon()/2, 0.0f, 0.0f};
CE Vector3 a{1.0f + Math::TypeTraits<Float>::epsilon()/2, 0.0f, 0.0f};
CORRADE_VERIFY(a.isNormalized());

CORRADE_COMPARE(Math::angle(a, a), 0.0_radf);
Expand Down Expand Up @@ -648,12 +669,12 @@ void VectorTest::subclassTypes() {
CORRADE_VERIFY(std::is_same<decltype(Vec2::from(data)), Vec2&>::value);
CORRADE_VERIFY(std::is_same<decltype(Vec2::from(cdata)), const Vec2&>::value);

Vector<1, Float> one;
CE Vector<1, Float> one;
CORRADE_VERIFY(std::is_same<decltype(Vec2::pad(one)), Vec2>::value);

/* Const operators */
const Vec2 c;
const Vec2 c2;
CE const Vec2 c;
CE const Vec2 c2;
CORRADE_VERIFY(std::is_same<decltype(+c), Vec2>::value);
CORRADE_VERIFY(std::is_same<decltype(-c), Vec2>::value);
CORRADE_VERIFY(std::is_same<decltype(c + c), Vec2>::value);
Expand Down Expand Up @@ -859,6 +880,11 @@ void VectorTest::debugPacked() {
Debug{&out} << Debug::packed << Vector4(0.5f, 15.0f, 1.0f, 1.0f) << Vector4();
CORRADE_COMPARE(out.str(), "{0.5, 15, 1, 1} Vector(0, 0, 0, 0)\n");
}
#else
void VectorTest::skipTesting() {
CORRADE_SKIP("Relaxed constexpr not supported by the compiler.");
}
#endif

}}}}

Expand Down

0 comments on commit c478e62

Please sign in to comment.