diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index d16e88823..e551f868c 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -142,6 +142,7 @@ template class Matrix: public RectangularMatrix { } #endif MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(size, size, Matrix) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(size, size, Matrix) }; /** @debugoperator{Magnum::Math::Matrix} */ diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index bb6ad65c6..e537de58a 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -96,6 +96,7 @@ template class Matrix3: public Matrix<3, T> { inline constexpr Matrix3(const RectangularMatrix<3, 3, T>& other): Matrix<3, T>(other) {} MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix3, Vector3, 3) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(3, 3, Matrix3) }; /** @debugoperator{Magnum::Math::Matrix3} */ diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 633376250..e0cfceb07 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -145,6 +145,7 @@ template class Matrix4: public Matrix<4, T> { } MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix4, Vector4, 4) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(4, 4, Matrix4) }; /** @debugoperator{Magnum::Math::Matrix4} */ diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index a5537d131..2ae79fea2 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -161,6 +161,50 @@ template class RectangularMatrix { return !operator==(other); } + /** + * @brief Add matrix + * + * @see operator+=() + */ + inline RectangularMatrix operator+(const RectangularMatrix& other) const { + return RectangularMatrix(*this)+=other; + } + + /** + * @brief Add and assign matrix + * + * More efficient than operator+(), because it does the computation + * in-place. + */ + RectangularMatrix& operator+=(const RectangularMatrix& other) { + for(size_t i = 0; i != cols*rows; ++i) + _data[i] += other._data[i]; + + return *this; + } + + /** + * @brief Subtract matrix + * + * @see operator-=() + */ + inline RectangularMatrix operator-(const RectangularMatrix& other) const { + return RectangularMatrix(*this)-=other; + } + + /** + * @brief Subtract and assign matrix + * + * More efficient than operator-(), because it does the computation + * in-place. + */ + RectangularMatrix& operator-=(const RectangularMatrix& other) { + for(size_t i = 0; i != cols*rows; ++i) + _data[i] -= other._data[i]; + + return *this; + } + /** @brief Multiply matrix */ template RectangularMatrix operator*(const RectangularMatrix& other) const { RectangularMatrix out; @@ -237,6 +281,22 @@ template Corrade::Utility::Debug operator<<(C RectangularMatrix::operator=(other); \ return *this; \ } + +#define MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(cols, rows, ...) \ + inline __VA_ARGS__ operator+(const RectangularMatrix& other) const { \ + return RectangularMatrix::operator+(other); \ + } \ + inline __VA_ARGS__& operator+=(const RectangularMatrix& other) { \ + RectangularMatrix::operator+=(other); \ + return *this; \ + } \ + inline __VA_ARGS__ operator-(const RectangularMatrix& other) const { \ + return RectangularMatrix::operator-(other); \ + } \ + inline __VA_ARGS__& operator-=(const RectangularMatrix& other) { \ + RectangularMatrix::operator-=(other); \ + return *this; \ + } #endif }} diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 0bf10e591..925ed8bd2 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -35,8 +35,12 @@ RectangularMatrixTest::RectangularMatrixTest() { &RectangularMatrixTest::constructFromVectors, &RectangularMatrixTest::constructZero, &RectangularMatrixTest::data, + + &RectangularMatrixTest::addSubtract, &RectangularMatrixTest::multiply, + &RectangularMatrixTest::transposed, + &RectangularMatrixTest::debug, &RectangularMatrixTest::configuration); } @@ -105,6 +109,24 @@ void RectangularMatrixTest::data() { CORRADE_COMPARE(m, expected); } +void RectangularMatrixTest::addSubtract() { + Matrix4x3 a(0.0f, 1.0f, 3.0f, + 4.0f, 5.0f, 7.0f, + 8.0f, 9.0f, 11.0f, + 12.0f, 13.0f, 15.0f); + Matrix4x3 b(-4.0f, 0.5f, 9.0f, + -9.0f, 11.0f, 0.25f, + 0.0f, -8.0f, 19.0f, + -3.0f, -5.0f, 2.0f); + Matrix4x3 e(-4.0f, 1.5f, 12.0f, + -5.0f, 16.0f, 7.25f, + 8.0f, 1.0f, 30.0f, + 9.0f, 8.0f, 17.0f); + + CORRADE_COMPARE(a + b, e); + CORRADE_COMPARE(e - b, a); +} + void RectangularMatrixTest::multiply() { RectangularMatrix<4, 6, int> left( -5, 27, 10, 33, 0, -15, diff --git a/src/Math/Test/RectangularMatrixTest.h b/src/Math/Test/RectangularMatrixTest.h index 058912598..f2fcfed0f 100644 --- a/src/Math/Test/RectangularMatrixTest.h +++ b/src/Math/Test/RectangularMatrixTest.h @@ -27,7 +27,10 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester { void dot(); void multiplyDivide(); void multiplyDivideComponentWise(); - void addSubtract(); void dotSelf(); void length(); void normalized(); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 7fa0dde1d..4b4bbfd2a 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -229,42 +229,6 @@ template class Vector: public RectangularMatrix<1, s, T> { return *this; } - /** @brief Add two vectors */ - inline Vector operator+(const Vector& other) const { - return Vector(*this)+=other; - } - - /** - * @brief Add and assign vector - * - * More efficient than operator+(), because it does the computation - * in-place. - */ - Vector& operator+=(const Vector& other) { - for(size_t i = 0; i != size; ++i) - (*this)[i] += other[i]; - - return *this; - } - - /** @brief Subtract two vectors */ - inline Vector operator-(const Vector& other) const { - return Vector(*this)-=other; - } - - /** - * @brief Subtract and assign vector - * - * More efficient than operator-(), because it does the computation - * in-place. - */ - Vector& operator-=(const Vector& other) { - for(size_t i = 0; i != size; ++i) - (*this)[i] -= other[i]; - - return *this; - } - /** @brief Negative vector */ Vector operator-() const { Vector out; @@ -344,6 +308,7 @@ template class Vector: public RectangularMatrix<1, s, T> { } MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(1, size, Vector) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, size, Vector) private: /* Hiding unused things from RectangularMatrix */ @@ -448,21 +413,6 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili return *this; \ } \ \ - inline Type operator+(const Vector& other) const { \ - return Vector::operator+(other); \ - } \ - inline Type& operator+=(const Vector& other) { \ - Vector::operator+=(other); \ - return *this; \ - } \ - inline Type operator-(const Vector& other) const { \ - return Vector::operator-(other); \ - } \ - inline Type& operator-=(const Vector& other) { \ - Vector::operator-=(other); \ - return *this; \ - } \ - \ inline Type operator-() const { return Vector::operator-(); } \ inline Type normalized() const { return Vector::normalized(); } diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index 569439c88..d67e8b0c7 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -88,6 +88,7 @@ template class Vector2: public Vector<2, T> { inline void setY(T value) { (*this)[1] = value; } /**< @brief Set Y component */ MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector2, 2) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 2, Vector2) }; MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Vector2, 2) diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index 826f28377..623bb2c33 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -140,6 +140,7 @@ template class Vector3: public Vector<3, T> { inline constexpr Vector2 xy() const { return Vector2::from(Vector<3, T>::data()); } MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector3, 3) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 3, Vector3) }; MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Vector3, 3) diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index eaebeac96..5adfe60ee 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -88,6 +88,7 @@ template class Vector4: public Vector<4, T> { inline constexpr Vector2 xy() const { return Vector2::from(Vector<4, T>::data()); } MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector4, 4) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 3, Vector4) }; MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Vector4, 4)