Browse Source

Math: properly test constexpr in all Matrix classes.

* Merged constExpressions() into other test cases, reducing duplicates
   and simplifying the checks.
 * Fixed old-and-forgotten operator[] overload in Matrix subclasses, it
   was reinterpret_cast on T* array, it is now sufficient to do only
   static_cast. Constexpr operator[] overload returns const copy to make
   constexpr operations working even on returned value, e.g.:

    constexpr Matrix4 a;
    constexpr Vector3 b = a[2].xyz();
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
677aa8485e
  1. 6
      src/Math/Matrix.h
  2. 4
      src/Math/Matrix3.h
  3. 4
      src/Math/Matrix4.h
  4. 123
      src/Math/Test/Matrix3Test.cpp
  5. 148
      src/Math/Test/Matrix4Test.cpp
  6. 67
      src/Math/Test/MatrixTest.cpp
  7. 142
      src/Math/Test/RectangularMatrixTest.cpp

6
src/Math/Matrix.h

@ -186,10 +186,10 @@ template<std::size_t size, class T> inline Corrade::Utility::Debug operator<<(Co
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
#define MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Type, VectorType, size) \ #define MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Type, VectorType, size) \
inline VectorType<T>& operator[](std::size_t col) { \ inline VectorType<T>& operator[](std::size_t col) { \
return VectorType<T>::from(Matrix<size, T>::data()+col*size); \ return static_cast<VectorType<T>&>(Matrix<size, T>::operator[](col)); \
} \ } \
inline constexpr const VectorType<T>& operator[](std::size_t col) const { \ inline constexpr const VectorType<T> operator[](std::size_t col) const { \
return VectorType<T>::from(Matrix<size, T>::data()+col*size); \ return VectorType<T>(Matrix<size, T>::operator[](col)); \
} \ } \
\ \
inline Type<T> operator*(const Matrix<size, T>& other) const { \ inline Type<T> operator*(const Matrix<size, T>& other) const { \

4
src/Math/Matrix3.h

@ -111,7 +111,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* *
* @see rotationScaling() const, translation() const * @see rotationScaling() const, translation() const
*/ */
static Matrix3<T> from(const Matrix<2, T>& rotationScaling, const Vector2<T>& translation) { inline constexpr static Matrix3<T> from(const Matrix<2, T>& rotationScaling, const Vector2<T>& translation) {
return {{rotationScaling[0], T(0)}, return {{rotationScaling[0], T(0)},
{rotationScaling[1], T(0)}, {rotationScaling[1], T(0)},
{ translation, T(1)}}; { translation, T(1)}};
@ -150,7 +150,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @see from(const Matrix<2, T>&, const Vector2&), rotation() const, * @see from(const Matrix<2, T>&, const Vector2&), rotation() const,
* rotation(T), Matrix4::rotationScaling() const * rotation(T), Matrix4::rotationScaling() const
*/ */
inline Matrix<2, T> rotationScaling() const { inline constexpr Matrix<2, T> rotationScaling() const {
return {(*this)[0].xy(), return {(*this)[0].xy(),
(*this)[1].xy()}; (*this)[1].xy()};
} }

4
src/Math/Matrix4.h

@ -240,7 +240,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* *
* @see rotationScaling() const, translation() const * @see rotationScaling() const, translation() const
*/ */
static Matrix4<T> from(const Matrix<3, T>& rotationScaling, const Vector3<T>& translation) { inline constexpr static Matrix4<T> from(const Matrix<3, T>& rotationScaling, const Vector3<T>& translation) {
return {{rotationScaling[0], T(0)}, return {{rotationScaling[0], T(0)},
{rotationScaling[1], T(0)}, {rotationScaling[1], T(0)},
{rotationScaling[2], T(0)}, {rotationScaling[2], T(0)},
@ -281,7 +281,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @see from(const Matrix<3, T>&, const Vector3&), rotation() const, * @see from(const Matrix<3, T>&, const Vector3&), rotation() const,
* rotation(T, const Vector3&), Matrix3::rotationScaling() const * rotation(T, const Vector3&), Matrix3::rotationScaling() const
*/ */
inline Matrix<3, T> rotationScaling() const { inline constexpr Matrix<3, T> rotationScaling() const {
/* Not Matrix3, because it is for affine 2D transformations */ /* Not Matrix3, because it is for affine 2D transformations */
return {(*this)[0].xyz(), return {(*this)[0].xyz(),
(*this)[1].xyz(), (*this)[1].xyz(),

123
src/Math/Test/Matrix3Test.cpp

@ -25,7 +25,11 @@ class Matrix3Test: public Corrade::TestSuite::Tester {
public: public:
Matrix3Test(); Matrix3Test();
void construct();
void constructIdentity(); void constructIdentity();
void constructZero();
void constructConversion();
void constructCopy();
void translation(); void translation();
void scaling(); void scaling();
@ -45,11 +49,16 @@ class Matrix3Test: public Corrade::TestSuite::Tester {
typedef Math::Deg<Float> Deg; typedef Math::Deg<Float> Deg;
typedef Math::Matrix3<Float> Matrix3; typedef Math::Matrix3<Float> Matrix3;
typedef Math::Matrix3<Int> Matrix3i;
typedef Math::Matrix<2, Float> Matrix2; typedef Math::Matrix<2, Float> Matrix2;
typedef Math::Vector2<Float> Vector2; typedef Math::Vector2<Float> Vector2;
Matrix3Test::Matrix3Test() { Matrix3Test::Matrix3Test() {
addTests(&Matrix3Test::constructIdentity, addTests(&Matrix3Test::construct,
&Matrix3Test::constructIdentity,
&Matrix3Test::constructZero,
&Matrix3Test::constructConversion,
&Matrix3Test::constructCopy,
&Matrix3Test::translation, &Matrix3Test::translation,
&Matrix3Test::scaling, &Matrix3Test::scaling,
@ -67,10 +76,19 @@ Matrix3Test::Matrix3Test() {
&Matrix3Test::configuration); &Matrix3Test::configuration);
} }
void Matrix3Test::construct() {
constexpr Matrix3 a({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f});
CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f}));
}
void Matrix3Test::constructIdentity() { void Matrix3Test::constructIdentity() {
Matrix3 identity; constexpr Matrix3 identity;
Matrix3 identity2(Matrix3::Identity); constexpr Matrix3 identity2(Matrix3::Identity);
Matrix3 identity3(Matrix3::Identity, 4.0f); constexpr Matrix3 identity3(Matrix3::Identity, 4.0f);
Matrix3 identityExpected({1.0f, 0.0f, 0.0f}, Matrix3 identityExpected({1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f},
@ -85,20 +103,49 @@ void Matrix3Test::constructIdentity() {
CORRADE_COMPARE(identity3, identity3Expected); CORRADE_COMPARE(identity3, identity3Expected);
} }
void Matrix3Test::translation() { void Matrix3Test::constructZero() {
Matrix3 matrix({1.0f, 0.0f, 0.0f}, constexpr Matrix3 a(Matrix3::Zero);
{0.0f, 1.0f, 0.0f}, CORRADE_COMPARE(a, Matrix3({0.0f, 0.0f, 0.0f},
{3.0f, 1.0f, 1.0f}); {0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f}));
}
CORRADE_COMPARE(Matrix3::translation({3.0f, 1.0f}), matrix); void Matrix3Test::constructConversion() {
constexpr Matrix3 a({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f});
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Matrix3i b(a);
#else
Matrix3i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Matrix3i({3, 5, 8},
{4, 4, 7},
{7, -1, 8}));
} }
void Matrix3Test::scaling() { void Matrix3Test::constructCopy() {
Matrix3 matrix({3.0f, 0.0f, 0.0f}, constexpr Matrix3 a({3.0f, 5.0f, 8.0f},
{0.0f, 1.5f, 0.0f}, {4.5f, 4.0f, 7.0f},
{0.0f, 0.0f, 1.0f}); {7.9f, -1.0f, 8.0f});
constexpr Matrix3 b(a);
CORRADE_COMPARE(b, Matrix3({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f}));
}
void Matrix3Test::translation() {
constexpr Matrix3 a = Matrix3::translation({3.0f, 1.0f});
CORRADE_COMPARE(a, Matrix3({1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{3.0f, 1.0f, 1.0f}));
}
CORRADE_COMPARE(Matrix3::scaling({3.0f, 1.5f}), matrix); void Matrix3Test::scaling() {
constexpr Matrix3 a = Matrix3::scaling({3.0f, 1.5f});
CORRADE_COMPARE(a, Matrix3({3.0f, 0.0f, 0.0f},
{0.0f, 1.5f, 0.0f},
{0.0f, 0.0f, 1.0f}));
} }
void Matrix3Test::rotation() { void Matrix3Test::rotation() {
@ -137,27 +184,24 @@ void Matrix3Test::projection() {
} }
void Matrix3Test::fromParts() { void Matrix3Test::fromParts() {
Matrix2 rotationScaling(Vector2(3.0f, 5.0f), constexpr Matrix2 rotationScaling(Vector2(3.0f, 5.0f),
Vector2(4.0f, 4.0f)); Vector2(4.0f, 4.0f));
constexpr Vector2 translation(7.0f, -1.0f);
Vector2 translation(7.0f, -1.0f); constexpr Matrix3 a = Matrix3::from(rotationScaling, translation);
Matrix3 expected({3.0f, 5.0f, 0.0f}, CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 0.0f},
{4.0f, 4.0f, 0.0f}, {4.0f, 4.0f, 0.0f},
{7.0f, -1.0f, 1.0f}); {7.0f, -1.0f, 1.0f}));
CORRADE_COMPARE(Matrix3::from(rotationScaling, translation), expected);
} }
void Matrix3Test::rotationScalingPart() { void Matrix3Test::rotationScalingPart() {
Matrix3 m({3.0f, 5.0f, 8.0f}, constexpr Matrix3 a({3.0f, 5.0f, 8.0f},
{4.0f, 4.0f, 7.0f}, {4.0f, 4.0f, 7.0f},
{7.0f, -1.0f, 8.0f}); {7.0f, -1.0f, 8.0f});
constexpr Matrix2 b = a.rotationScaling();
Matrix2 expected(Vector2(3.0f, 5.0f), CORRADE_COMPARE(b, Matrix2(Vector2(3.0f, 5.0f),
Vector2(4.0f, 4.0f)); Vector2(4.0f, 4.0f)));
CORRADE_COMPARE(m.rotationScaling(), expected);
} }
void Matrix3Test::rotationPart() { void Matrix3Test::rotationPart() {
@ -190,13 +234,16 @@ void Matrix3Test::rotationPart() {
} }
void Matrix3Test::vectorParts() { void Matrix3Test::vectorParts() {
Matrix3 m({15.0f, 0.0f, 0.0f}, constexpr Matrix3 a({15.0f, 0.0f, 0.0f},
{ 0.0f, -3.0f, 0.0f}, { 0.0f, -3.0f, 0.0f},
{-5.0f, 12.0f, 1.0f}); {-5.0f, 12.0f, 1.0f});
constexpr Vector2 right = a.right();
CORRADE_COMPARE(m.right(), Vector2::xAxis(15.0f)); constexpr Vector2 up = a.up();
CORRADE_COMPARE(m.up(), Vector2::yAxis(-3.0f)); constexpr Vector2 translation = a.translation();
CORRADE_COMPARE(m.translation(), Vector2(-5.0f, 12.0f));
CORRADE_COMPARE(right, Vector2::xAxis(15.0f));
CORRADE_COMPARE(up, Vector2::yAxis(-3.0f));
CORRADE_COMPARE(translation, Vector2(-5.0f, 12.0f));
} }
void Matrix3Test::invertedEuclidean() { void Matrix3Test::invertedEuclidean() {

148
src/Math/Test/Matrix4Test.cpp

@ -25,7 +25,11 @@ class Matrix4Test: public Corrade::TestSuite::Tester {
public: public:
Matrix4Test(); Matrix4Test();
void construct();
void constructIdentity(); void constructIdentity();
void constructZero();
void constructConversion();
void constructCopy();
void translation(); void translation();
void scaling(); void scaling();
@ -51,11 +55,16 @@ class Matrix4Test: public Corrade::TestSuite::Tester {
typedef Math::Deg<Float> Deg; typedef Math::Deg<Float> Deg;
typedef Math::Rad<Float> Rad; typedef Math::Rad<Float> Rad;
typedef Math::Matrix4<Float> Matrix4; typedef Math::Matrix4<Float> Matrix4;
typedef Math::Matrix4<Int> Matrix4i;
typedef Math::Matrix<3, Float> Matrix3; typedef Math::Matrix<3, Float> Matrix3;
typedef Math::Vector3<Float> Vector3; typedef Math::Vector3<Float> Vector3;
Matrix4Test::Matrix4Test() { Matrix4Test::Matrix4Test() {
addTests(&Matrix4Test::constructIdentity, addTests(&Matrix4Test::construct,
&Matrix4Test::constructIdentity,
&Matrix4Test::constructZero,
&Matrix4Test::constructConversion,
&Matrix4Test::constructCopy,
&Matrix4Test::translation, &Matrix4Test::translation,
&Matrix4Test::scaling, &Matrix4Test::scaling,
@ -78,10 +87,21 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::configuration); &Matrix4Test::configuration);
} }
void Matrix4Test::construct() {
constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f},
{4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f});
CORRADE_COMPARE(a, Matrix4({3.0f, 5.0f, 8.0f, -3.0f},
{4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f}));
}
void Matrix4Test::constructIdentity() { void Matrix4Test::constructIdentity() {
Matrix4 identity; constexpr Matrix4 identity;
Matrix4 identity2(Matrix4::Identity); constexpr Matrix4 identity2(Matrix4::Identity);
Matrix4 identity3(Matrix4::Identity, 4.0f); constexpr Matrix4 identity3(Matrix4::Identity, 4.0f);
Matrix4 identityExpected({1.0f, 0.0f, 0.0f, 0.0f}, Matrix4 identityExpected({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f},
@ -98,22 +118,57 @@ void Matrix4Test::constructIdentity() {
CORRADE_COMPARE(identity3, identity3Expected); CORRADE_COMPARE(identity3, identity3Expected);
} }
void Matrix4Test::translation() { void Matrix4Test::constructZero() {
Matrix4 matrix({1.0f, 0.0f, 0.0f, 0.0f}, /* Zero constructor */
{0.0f, 1.0f, 0.0f, 0.0f}, constexpr Matrix4 a(Matrix4::Zero);
{0.0f, 0.0f, 1.0f, 0.0f}, CORRADE_COMPARE(a, Matrix4({0.0f, 0.0f, 0.0f, 0.0f},
{3.0f, 1.0f, 2.0f, 1.0f}); {0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f}));
}
CORRADE_COMPARE(Matrix4::translation({3.0f, 1.0f, 2.0f}), matrix); void Matrix4Test::constructConversion() {
constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f},
{4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f});
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Matrix4i b(a);
#else
Matrix4i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Matrix4i({3, 5, 8, -3},
{4, 4, 7, 2},
{1, 2, 3, -1},
{7, -1, 8, -1}));
} }
void Matrix4Test::scaling() { void Matrix4Test::constructCopy() {
Matrix4 matrix({3.0f, 0.0f, 0.0f, 0.0f}, constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f},
{0.0f, 1.5f, 0.0f, 0.0f}, {4.5f, 4.0f, 7.0f, 2.0f},
{0.0f, 0.0f, 2.0f, 0.0f}, {1.0f, 2.0f, 3.0f, -1.0f},
{0.0f, 0.0f, 0.0f, 1.0f}); {7.9f, -1.0f, 8.0f, -1.5f});
constexpr Matrix4 b(a);
CORRADE_COMPARE(b, Matrix4({3.0f, 5.0f, 8.0f, -3.0f},
{4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f}));
}
CORRADE_COMPARE(Matrix4::scaling({3.0f, 1.5f, 2.0f}), matrix); void Matrix4Test::translation() {
constexpr Matrix4 a = Matrix4::translation({3.0f, 1.0f, 2.0f});
CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{3.0f, 1.0f, 2.0f, 1.0f}));
}
void Matrix4Test::scaling() {
constexpr Matrix4 a = Matrix4::scaling({3.0f, 1.5f, 2.0f});
CORRADE_COMPARE(a, Matrix4({3.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.5f, 0.0f, 0.0f},
{0.0f, 0.0f, 2.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}));
} }
void Matrix4Test::rotation() { void Matrix4Test::rotation() {
@ -202,29 +257,28 @@ void Matrix4Test::perspectiveProjectionFov() {
} }
void Matrix4Test::fromParts() { void Matrix4Test::fromParts() {
Matrix3 rotationScaling(Vector3(3.0f, 5.0f, 8.0f), constexpr Matrix3 rotationScaling(Vector3(3.0f, 5.0f, 8.0f),
Vector3(4.0f, 4.0f, 7.0f), Vector3(4.0f, 4.0f, 7.0f),
Vector3(7.0f, -1.0f, 8.0f)); Vector3(7.0f, -1.0f, 8.0f));
constexpr Vector3 translation(9.0f, 4.0f, 5.0f);
Vector3 translation(9.0f, 4.0f, 5.0f); constexpr Matrix4 a = Matrix4::from(rotationScaling, translation);
Matrix4 expected({3.0f, 5.0f, 8.0f, 0.0f}, CORRADE_COMPARE(a, Matrix4({3.0f, 5.0f, 8.0f, 0.0f},
{4.0f, 4.0f, 7.0f, 0.0f}, {4.0f, 4.0f, 7.0f, 0.0f},
{7.0f, -1.0f, 8.0f, 0.0f}, {7.0f, -1.0f, 8.0f, 0.0f},
{9.0f, 4.0f, 5.0f, 1.0f}); {9.0f, 4.0f, 5.0f, 1.0f}));
CORRADE_COMPARE(Matrix4::from(rotationScaling, translation), expected);
} }
void Matrix4Test::rotationScalingPart() { void Matrix4Test::rotationScalingPart() {
Matrix4 m({3.0f, 5.0f, 8.0f, 4.0f}, constexpr Matrix4 a({3.0f, 5.0f, 8.0f, 4.0f},
{4.0f, 4.0f, 7.0f, 3.0f}, {4.0f, 4.0f, 7.0f, 3.0f},
{7.0f, -1.0f, 8.0f, 0.0f}, {7.0f, -1.0f, 8.0f, 0.0f},
{9.0f, 4.0f, 5.0f, 9.0f}); {9.0f, 4.0f, 5.0f, 9.0f});
constexpr Matrix3 b = a.rotationScaling();
Matrix3 expected(Vector3(3.0f, 5.0f, 8.0f),
Vector3(4.0f, 4.0f, 7.0f), CORRADE_COMPARE(b, Matrix3(Vector3(3.0f, 5.0f, 8.0f),
Vector3(7.0f, -1.0f, 8.0f)); Vector3(4.0f, 4.0f, 7.0f),
CORRADE_COMPARE(m.rotationScaling(), expected); Vector3(7.0f, -1.0f, 8.0f)));
} }
void Matrix4Test::rotationPart() { void Matrix4Test::rotationPart() {
@ -258,15 +312,19 @@ void Matrix4Test::rotationPart() {
} }
void Matrix4Test::vectorParts() { void Matrix4Test::vectorParts() {
Matrix4 m({-1.0f, 0.0f, 0.0f, 0.0f}, constexpr Matrix4 a({-1.0f, 0.0f, 0.0f, 0.0f},
{ 0.0f, 12.0f, 0.0f, 0.0f}, { 0.0f, 12.0f, 0.0f, 0.0f},
{ 0.0f, 0.0f, 35.0f, 0.0f}, { 0.0f, 0.0f, 35.0f, 0.0f},
{-5.0f, 12.0f, 0.5f, 1.0f}); {-5.0f, 12.0f, 0.5f, 1.0f});
constexpr Vector3 right = a.right();
CORRADE_COMPARE(m.right(), Vector3::xAxis(-1.0f)); constexpr Vector3 up = a.up();
CORRADE_COMPARE(m.up(), Vector3::yAxis(12.0f)); constexpr Vector3 backward = a.backward();
CORRADE_COMPARE(m.backward(), Vector3::zAxis(35.0f)); constexpr Vector3 translation = a.translation();
CORRADE_COMPARE(m.translation(), Vector3(-5.0f, 12.0f, 0.5f));
CORRADE_COMPARE(right, Vector3::xAxis(-1.0f));
CORRADE_COMPARE(up, Vector3::yAxis(12.0f));
CORRADE_COMPARE(backward, Vector3::zAxis(35.0f));
CORRADE_COMPARE(translation, Vector3(-5.0f, 12.0f, 0.5f));
} }
void Matrix4Test::invertedEuclidean() { void Matrix4Test::invertedEuclidean() {

67
src/Math/Test/MatrixTest.cpp

@ -28,6 +28,9 @@ class MatrixTest: public Corrade::TestSuite::Tester {
void construct(); void construct();
void constructIdentity(); void constructIdentity();
void constructZero(); void constructZero();
void constructConversion();
void constructCopy();
void trace(); void trace();
void ij(); void ij();
void determinant(); void determinant();
@ -38,14 +41,19 @@ class MatrixTest: public Corrade::TestSuite::Tester {
}; };
typedef Matrix<4, Float> Matrix4; typedef Matrix<4, Float> Matrix4;
typedef Matrix<4, Int> Matrix4i;
typedef Matrix<3, Float> Matrix3; typedef Matrix<3, Float> Matrix3;
typedef Vector<4, Float> Vector4; typedef Vector<4, Float> Vector4;
typedef Vector<4, Int> Vector4i;
typedef Vector<3, Float> Vector3; typedef Vector<3, Float> Vector3;
MatrixTest::MatrixTest() { MatrixTest::MatrixTest() {
addTests(&MatrixTest::construct, addTests(&MatrixTest::construct,
&MatrixTest::constructIdentity, &MatrixTest::constructIdentity,
&MatrixTest::constructZero, &MatrixTest::constructZero,
&MatrixTest::constructConversion,
&MatrixTest::constructCopy,
&MatrixTest::trace, &MatrixTest::trace,
&MatrixTest::ij, &MatrixTest::ij,
&MatrixTest::determinant, &MatrixTest::determinant,
@ -55,19 +63,15 @@ MatrixTest::MatrixTest() {
} }
void MatrixTest::construct() { void MatrixTest::construct() {
Float m[] = { /* Value constructor */
3.0f, 5.0f, 8.0f, 4.0f, constexpr Matrix4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
4.0f, 4.0f, 7.0f, 3.0f, Vector4(4.5f, 4.0f, 7.0f, 2.0f),
7.0f, -1.0f, 8.0f, 0.0f, Vector4(1.0f, 2.0f, 3.0f, -1.0f),
9.0f, 4.0f, 5.0f, 9.0f Vector4(7.9f, -1.0f, 8.0f, -1.5f));
}; CORRADE_COMPARE(a, Matrix4(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Matrix4 expected(Vector4(3.0f, 5.0f, 8.0f, 4.0f), Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(4.0f, 4.0f, 7.0f, 3.0f), Vector4(7.9f, -1.0f, 8.0f, -1.5f)));
Vector4(7.0f, -1.0f, 8.0f, 0.0f),
Vector4(9.0f, 4.0f, 5.0f, 9.0f));
CORRADE_COMPARE(Matrix4::from(m), expected);
} }
void MatrixTest::constructIdentity() { void MatrixTest::constructIdentity() {
@ -91,14 +95,39 @@ void MatrixTest::constructIdentity() {
} }
void MatrixTest::constructZero() { void MatrixTest::constructZero() {
Matrix4 zero(Matrix4::Zero); constexpr Matrix4 a(Matrix4::Zero);
CORRADE_COMPARE(a, Matrix4(Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
}
Matrix4 zeroExpected(Vector4(0.0f, 0.0f, 0.0f, 0.0f), void MatrixTest::constructConversion() {
Vector4(0.0f, 0.0f, 0.0f, 0.0f), constexpr Matrix4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f)); Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(7.9f, -1.0f, 8.0f, -1.5f));
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Matrix4i b(a);
#else
Matrix4i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Matrix4i(Vector4i(3, 5, 8, -3),
Vector4i(4, 4, 7, 2),
Vector4i(1, 2, 3, -1),
Vector4i(7, -1, 8, -1)));
}
CORRADE_COMPARE(zero, zeroExpected); void MatrixTest::constructCopy() {
constexpr Matrix4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(7.9f, -1.0f, 8.0f, -1.5f));
constexpr Matrix4 b(a);
CORRADE_COMPARE(b, Matrix4(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(7.9f, -1.0f, 8.0f, -1.5f)));
} }
void MatrixTest::trace() { void MatrixTest::trace() {

142
src/Math/Test/RectangularMatrixTest.cpp

@ -25,15 +25,14 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester {
public: public:
RectangularMatrixTest(); RectangularMatrixTest();
void constructFromData(); void construct();
void constructDefault(); void constructDefault();
void constructConversion(); void constructConversion();
void constructFromVectors(); void constructFromData();
void constructFromDiagonal(); void constructFromDiagonal();
void constructCopy();
void data(); void data();
void constExpressions();
void compare(); void compare();
void negative(); void negative();
@ -65,15 +64,14 @@ typedef Vector<2, Float> Vector2;
typedef Vector<2, Int> Vector2i; typedef Vector<2, Int> Vector2i;
RectangularMatrixTest::RectangularMatrixTest() { RectangularMatrixTest::RectangularMatrixTest() {
addTests(&RectangularMatrixTest::constructFromData, addTests(&RectangularMatrixTest::construct,
&RectangularMatrixTest::constructDefault, &RectangularMatrixTest::constructDefault,
&RectangularMatrixTest::constructConversion, &RectangularMatrixTest::constructConversion,
&RectangularMatrixTest::constructFromVectors, &RectangularMatrixTest::constructFromData,
&RectangularMatrixTest::constructFromDiagonal, &RectangularMatrixTest::constructFromDiagonal,
&RectangularMatrixTest::constructCopy,
&RectangularMatrixTest::data, &RectangularMatrixTest::data,
&RectangularMatrixTest::constExpressions,
&RectangularMatrixTest::compare, &RectangularMatrixTest::compare,
&RectangularMatrixTest::negative, &RectangularMatrixTest::negative,
@ -95,6 +93,36 @@ RectangularMatrixTest::RectangularMatrixTest() {
&RectangularMatrixTest::configuration); &RectangularMatrixTest::configuration);
} }
void RectangularMatrixTest::construct() {
constexpr Matrix3x4 a(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f));
CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f)));
}
void RectangularMatrixTest::constructDefault() {
constexpr Matrix4x3 a;
CORRADE_COMPARE(a, Matrix4x3(Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f)));
}
void RectangularMatrixTest::constructConversion() {
constexpr Matrix2 a(Vector2( 1.3f, 2.7f),
Vector2(-15.0f, 7.0f));
#ifndef CORRADE_GCC46_COMPATIBILITY
constexpr Matrix2i b(a);
#else
Matrix2i b(a); /* Not constexpr under GCC < 4.7 */
#endif
CORRADE_COMPARE(b, Matrix2i(Vector2i( 1, 2),
Vector2i(-15, 7)));
}
void RectangularMatrixTest::constructFromData() { void RectangularMatrixTest::constructFromData() {
Float m[] = { Float m[] = {
3.0f, 5.0f, 8.0f, 4.0f, 3.0f, 5.0f, 8.0f, 4.0f,
@ -109,41 +137,6 @@ void RectangularMatrixTest::constructFromData() {
CORRADE_COMPARE(Matrix3x4::from(m), expected); CORRADE_COMPARE(Matrix3x4::from(m), expected);
} }
void RectangularMatrixTest::constructDefault() {
Matrix4x3 zero;
Matrix4x3 zeroExpected(Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f));
CORRADE_COMPARE(zero, zeroExpected);
}
void RectangularMatrixTest::constructConversion() {
Matrix2 FloatingPoint(Vector2( 1.3f, 2.7f),
Vector2(-15.0f, 7.0f));
Matrix2 FloatingPointRounded(Vector2(1.0f, 2.0f),
Vector2(-15.0f, 7.0f));
Matrix2i integral(Vector2i( 1, 2),
Vector2i(-15, 7));
CORRADE_COMPARE(Matrix2i(FloatingPoint), integral);
CORRADE_COMPARE(Matrix2(integral), FloatingPointRounded);
}
void RectangularMatrixTest::constructFromVectors() {
Matrix3x4 actual(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f));
Matrix3x4 expected(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f));
CORRADE_COMPARE(actual, expected);
}
void RectangularMatrixTest::constructFromDiagonal() { void RectangularMatrixTest::constructFromDiagonal() {
Vector3 diagonal(-1.0f, 5.0f, 11.0f); Vector3 diagonal(-1.0f, 5.0f, 11.0f);
@ -159,6 +152,16 @@ void RectangularMatrixTest::constructFromDiagonal() {
CORRADE_COMPARE(Matrix4x3::fromDiagonal(diagonal), expectedB); CORRADE_COMPARE(Matrix4x3::fromDiagonal(diagonal), expectedB);
} }
void RectangularMatrixTest::constructCopy() {
constexpr Matrix3x4 a(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f));
constexpr Matrix3x4 b(a);
CORRADE_COMPARE(b, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f)));
}
void RectangularMatrixTest::data() { void RectangularMatrixTest::data() {
Matrix3x4 m; Matrix3x4 m;
Vector4 vector(4.0f, 5.0f, 6.0f, 7.0f); Vector4 vector(4.0f, 5.0f, 6.0f, 7.0f);
@ -171,51 +174,20 @@ void RectangularMatrixTest::data() {
CORRADE_COMPARE(m[0][2], 1.5f); CORRADE_COMPARE(m[0][2], 1.5f);
CORRADE_COMPARE(m[2], vector); CORRADE_COMPARE(m[2], vector);
Matrix3x4 expected(Vector4(0.0f, 0.0f, 1.5f, 0.0f), CORRADE_COMPARE(m, Matrix3x4(Vector4(0.0f, 0.0f, 1.5f, 0.0f),
Vector4(0.0f, 1.0f, 0.0f, 0.0f), Vector4(0.0f, 1.0f, 0.0f, 0.0f),
Vector4(4.0f, 5.0f, 6.0f, 7.0f)); Vector4(4.0f, 5.0f, 6.0f, 7.0f)));
CORRADE_COMPARE(m, expected);
}
void RectangularMatrixTest::constExpressions() {
/* Default constructor */
constexpr Matrix3x4 a;
CORRADE_COMPARE(a, Matrix3x4(Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
/* Value constructor */ /* Pointer chasings, i.e. *(b.data()[1]), are not possible */
constexpr Matrix3x4 b(Vector4(3.0f, 5.0f, 8.0f, 4.0f), constexpr Matrix3x4 a(Vector4(3.0f, 5.0f, 8.0f, 4.0f),
Vector4(4.5f, 4.0f, 7.0f, 3.0f), Vector4(4.5f, 4.0f, 7.0f, 3.0f),
Vector4(7.0f, -1.7f, 8.0f, 0.0f)); Vector4(7.0f, -1.7f, 8.0f, 0.0f));
CORRADE_COMPARE(b, Matrix3x4(Vector4(3.0f, 5.0f, 8.0f, 4.0f), constexpr Vector4 b = a[2];
Vector4(4.5f, 4.0f, 7.0f, 3.0f), constexpr Float c = a[1][2];
Vector4(7.0f, -1.7f, 8.0f, 0.0f))); constexpr Float d = *a.data();
CORRADE_COMPARE(b, Vector4(7.0f, -1.7f, 8.0f, 0.0f));
/* Conversion constructor, not constexpr under GCC < 4.7 */ CORRADE_COMPARE(c, 7.0f);
#ifndef CORRADE_GCC46_COMPATIBILITY CORRADE_COMPARE(d, 3.0f);
typedef RectangularMatrix<3, 4, Int> Matrix3x4i;
typedef Vector<4, Int> Vector4i;
constexpr Matrix3x4i c(b);
CORRADE_COMPARE(c, Matrix3x4i(Vector4i(3, 5, 8, 4),
Vector4i(4, 4, 7, 3),
Vector4i(7, -1, 8, 0)));
#endif
/* Copy constructor */
constexpr Matrix3x4 d(b);
CORRADE_COMPARE(d, Matrix3x4(Vector4(3.0f, 5.0f, 8.0f, 4.0f),
Vector4(4.5f, 4.0f, 7.0f, 3.0f),
Vector4(7.0f, -1.7f, 8.0f, 0.0f)));
/* Data access, pointer chasings, i.e. *(b.data()[1]), are not possible */
constexpr Vector4 e = b[2];
constexpr Float f = b[1][2];
constexpr Float g = *b.data();
CORRADE_COMPARE(e, Vector4(7.0f, -1.7f, 8.0f, 0.0f));
CORRADE_COMPARE(f, 7.0f);
CORRADE_COMPARE(g, 3.0f);
} }
void RectangularMatrixTest::compare() { void RectangularMatrixTest::compare() {

Loading…
Cancel
Save