Browse Source

Math: ability to create matrices with one value for all components.

In order to do that with the previous API, one had to write an
abomination like

    auto a = Matrix4x4::fromVector(Math::Vector<16, Float>{0.5f});

Ugh.
pull/196/head
Vladimír Vondruš 9 years ago
parent
commit
aa69bbcc19
  1. 3
      src/Magnum/Math/Matrix.h
  2. 3
      src/Magnum/Math/Matrix3.h
  3. 3
      src/Magnum/Math/Matrix4.h
  4. 7
      src/Magnum/Math/RectangularMatrix.h
  5. 14
      src/Magnum/Math/Test/Matrix3Test.cpp
  6. 15
      src/Magnum/Math/Test/Matrix4Test.cpp
  7. 31
      src/Magnum/Math/Test/MatrixTest.cpp
  8. 31
      src/Magnum/Math/Test/RectangularMatrixTest.cpp

3
src/Magnum/Math/Matrix.h

@ -112,6 +112,9 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
/** @brief Construct matrix from column vectors */
template<class ...U> constexpr /*implicit*/ Matrix(const Vector<size, T>& first, const U&... next) noexcept: RectangularMatrix<size, size, T>(first, next...) {}
/** @brief Construct matrix with one value for all elements */
constexpr explicit Matrix(T value) noexcept: RectangularMatrix<size, size, T>{typename Implementation::GenerateSequence<size>::Type(), value} {}
/**
* @brief Construct matrix from another of different type
*

3
src/Magnum/Math/Matrix3.h

@ -230,6 +230,9 @@ template<class T> class Matrix3: public Matrix3x3<T> {
/** @brief Construct matrix from column vectors */
constexpr /*implicit*/ Matrix3(const Vector3<T>& first, const Vector3<T>& second, const Vector3<T>& third) noexcept: Matrix3x3<T>(first, second, third) {}
/** @brief Construct matrix with one value for all elements */
constexpr explicit Matrix3(T value) noexcept: Matrix3x3<T>{value} {}
/** @copydoc Matrix::Matrix(const RectangularMatrix<size, size, U>&) */
template<class U> constexpr explicit Matrix3(const RectangularMatrix<3, 3, U>& other) noexcept: Matrix3x3<T>(other) {}

3
src/Magnum/Math/Matrix4.h

@ -401,6 +401,9 @@ template<class T> class Matrix4: public Matrix4x4<T> {
/** @brief Construct matrix from column vectors */
constexpr /*implicit*/ Matrix4(const Vector4<T>& first, const Vector4<T>& second, const Vector4<T>& third, const Vector4<T>& fourth) noexcept: Matrix4x4<T>(first, second, third, fourth) {}
/** @brief Construct matrix with one value for all elements */
constexpr explicit Matrix4(T value) noexcept: Matrix4x4<T>{value} {}
/** @copydoc Matrix::Matrix(const RectangularMatrix<size, size, U>&) */
template<class U> constexpr explicit Matrix4(const RectangularMatrix<4, 4, U>& other) noexcept: Matrix4x4<T>(other) {}

7
src/Magnum/Math/RectangularMatrix.h

@ -130,6 +130,9 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to RectangularMatrix constructor");
}
/** @brief Construct matrix with one value for all components */
constexpr explicit RectangularMatrix(T value) noexcept: RectangularMatrix{typename Implementation::GenerateSequence<cols>::Type(), value} {}
/**
* @brief Construct matrix from another of different type
*
@ -435,6 +438,10 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/* Implementation for RectangularMatrix<cols, rows, T>::fromDiagonal() and Matrix<size, T>(IdentityInitT, T) */
template<std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, const Vector<DiagonalSize, T>& diagonal);
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(T) and Matrix<size, T>(T) */
/* MSVC 2015 can't handle {} here */
template<std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, T value) noexcept: _data{Vector<rows, T>((static_cast<void>(sequence), value))...} {}
private:
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(const RectangularMatrix<cols, rows, U>&) */
template<class U, std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, const RectangularMatrix<cols, rows, U>& matrix) noexcept: _data{Vector<rows, T>(matrix[sequence])...} {}

14
src/Magnum/Math/Test/Matrix3Test.cpp

@ -63,6 +63,7 @@ struct Matrix3Test: Corrade::TestSuite::Tester {
void constructIdentity();
void constructZero();
void constructNoInit();
void constructOneValue();
void constructConversion();
void constructCopy();
void convert();
@ -102,6 +103,7 @@ Matrix3Test::Matrix3Test() {
&Matrix3Test::constructIdentity,
&Matrix3Test::constructZero,
&Matrix3Test::constructNoInit,
&Matrix3Test::constructOneValue,
&Matrix3Test::constructConversion,
&Matrix3Test::constructCopy,
&Matrix3Test::convert,
@ -190,6 +192,18 @@ void Matrix3Test::constructNoInit() {
CORRADE_VERIFY(!(std::is_convertible<NoInitT, Matrix3>::value));
}
void Matrix3Test::constructOneValue() {
constexpr Matrix3 a{1.5f};
CORRADE_COMPARE(a, (Matrix3{Vector3{1.5f, 1.5f, 1.5f},
Vector3{1.5f, 1.5f, 1.5f},
Vector3{1.5f, 1.5f, 1.5f}}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Matrix3>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, Float>::value));
}
void Matrix3Test::constructConversion() {
constexpr Matrix3 a({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f},

15
src/Magnum/Math/Test/Matrix4Test.cpp

@ -66,6 +66,7 @@ struct Matrix4Test: Corrade::TestSuite::Tester {
void constructIdentity();
void constructZero();
void constructNoInit();
void constructOneValue();
void constructConversion();
void constructCopy();
void convert();
@ -118,6 +119,7 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::constructIdentity,
&Matrix4Test::constructZero,
&Matrix4Test::constructNoInit,
&Matrix4Test::constructOneValue,
&Matrix4Test::constructConversion,
&Matrix4Test::constructCopy,
&Matrix4Test::convert,
@ -224,6 +226,19 @@ void Matrix4Test::constructNoInit() {
CORRADE_VERIFY(!(std::is_convertible<NoInitT, Matrix4>::value));
}
void Matrix4Test::constructOneValue() {
constexpr Matrix4 a{1.5f};
CORRADE_COMPARE(a, (Matrix4{{1.5f, 1.5f, 1.5f, 1.5f},
{1.5f, 1.5f, 1.5f, 1.5f},
{1.5f, 1.5f, 1.5f, 1.5f},
{1.5f, 1.5f, 1.5f, 1.5f}}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Matrix4>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, Float>::value));
}
void Matrix4Test::constructConversion() {
constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f},
{4.5f, 4.0f, 7.0f, 2.0f},

31
src/Magnum/Math/Test/MatrixTest.cpp

@ -63,6 +63,8 @@ struct MatrixTest: Corrade::TestSuite::Tester {
void constructIdentity();
void constructZero();
void constructNoInit();
void constructOneValue();
void constructOneComponent();
void constructConversion();
void constructCopy();
void convert();
@ -95,6 +97,8 @@ MatrixTest::MatrixTest() {
&MatrixTest::constructIdentity,
&MatrixTest::constructZero,
&MatrixTest::constructNoInit,
&MatrixTest::constructOneValue,
&MatrixTest::constructOneComponent,
&MatrixTest::constructConversion,
&MatrixTest::constructCopy,
&MatrixTest::convert,
@ -182,6 +186,33 @@ void MatrixTest::constructNoInit() {
CORRADE_VERIFY(!(std::is_convertible<NoInitT, Matrix4x4>::value));
}
void MatrixTest::constructOneValue() {
constexpr Matrix3x3 a{1.5f};
CORRADE_COMPARE(a, (Matrix3x3{Vector3{1.5f, 1.5f, 1.5f},
Vector3{1.5f, 1.5f, 1.5f},
Vector3{1.5f, 1.5f, 1.5f}}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Matrix3x3>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3x3, Float>::value));
}
void MatrixTest::constructOneComponent() {
typedef Math::Matrix<1, Float> Matrix1x1;
typedef Math::Vector<1, Float> Vector1;
constexpr Matrix1x1 a{1.5f};
constexpr Matrix1x1 b{Vector1{1.5f}};
CORRADE_COMPARE(a, b);
/* Implicit constructor must work */
constexpr Matrix1x1 c = Vector1{1.5f};
CORRADE_COMPARE(c, Matrix1x1{Vector1{1.5f}});
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix1x1, Vector1>::value));
}
void MatrixTest::constructConversion() {
constexpr Matrix4x4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f),
Vector4(4.5f, 4.0f, 7.0f, 2.0f),

31
src/Magnum/Math/Test/RectangularMatrixTest.cpp

@ -60,6 +60,8 @@ struct RectangularMatrixTest: Corrade::TestSuite::Tester {
void construct();
void constructDefault();
void constructNoInit();
void constructOneValue();
void constructOneComponent();
void constructConversion();
void constructFromData();
void constructFromDiagonal();
@ -110,6 +112,8 @@ RectangularMatrixTest::RectangularMatrixTest() {
addTests({&RectangularMatrixTest::construct,
&RectangularMatrixTest::constructDefault,
&RectangularMatrixTest::constructNoInit,
&RectangularMatrixTest::constructOneValue,
&RectangularMatrixTest::constructOneComponent,
&RectangularMatrixTest::constructConversion,
&RectangularMatrixTest::constructFromData,
&RectangularMatrixTest::constructFromDiagonal,
@ -189,6 +193,33 @@ void RectangularMatrixTest::constructNoInit() {
CORRADE_VERIFY(!(std::is_convertible<NoInitT, Matrix3x4>::value));
}
void RectangularMatrixTest::constructOneValue() {
constexpr Matrix3x4 a{1.5f};
CORRADE_COMPARE(a, (Matrix3x4{Vector4{1.5f, 1.5f, 1.5f, 1.5f},
Vector4{1.5f, 1.5f, 1.5f, 1.5f},
Vector4{1.5f, 1.5f, 1.5f, 1.5f}}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Matrix3x4>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3x4, Float>::value));
}
void RectangularMatrixTest::constructOneComponent() {
typedef Math::RectangularMatrix<1, 1, Float> Matrix1x1;
typedef Math::Vector<1, Float> Vector1;
constexpr Matrix1x1 a{1.5f};
constexpr Matrix1x1 b{Vector1{1.5f}};
CORRADE_COMPARE(a, b);
/* Implicit constructor must work */
constexpr Matrix1x1 c = Vector1{1.5f};
CORRADE_COMPARE(c, Matrix1x1{Vector1{1.5f}});
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix1x1, Vector1>::value));
}
void RectangularMatrixTest::constructConversion() {
constexpr Matrix2x2 a(Vector2( 1.3f, 2.7f),
Vector2(-15.0f, 7.0f));

Loading…
Cancel
Save