From b6ac0125dc2ac214e2a56f34bb62a8edc4b818c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 27 Feb 2012 13:30:41 +0100 Subject: [PATCH] "Initializer-list" constructor also for Matrix. --- src/Camera.cpp | 10 +-- src/Math/Matrix.h | 9 +++ src/Math/Matrix3.h | 3 + src/Math/Matrix4.h | 34 ++++----- src/Math/Test/Matrix3Test.cpp | 12 ++-- src/Math/Test/Matrix4Test.cpp | 32 ++++----- src/Math/Test/MatrixTest.cpp | 132 +++++++++++++++++++--------------- src/Math/Test/MatrixTest.h | 1 + 8 files changed, 131 insertions(+), 102 deletions(-) diff --git a/src/Camera.cpp b/src/Camera.cpp index 81bbb5061..0c9aa0dc1 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -45,11 +45,11 @@ void Camera::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { rawProjectionMatrix = Matrix4::translation(Vector3::zAxis(2*far*near/(far+near))); /* Then apply magic perspective matrix (with reversed Z) */ - static GLfloat a[] = { 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, -1, -1, - 0, 0, 0, 0 }; - rawProjectionMatrix = Matrix4(a)*rawProjectionMatrix; + static Matrix4 a(1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, -1.0f, + 0.0f, 0.0f, 0.0f, 0.0f); + rawProjectionMatrix = a*rawProjectionMatrix; /* Then scale the volume down so it fits in (-1, 1) in all directions */ GLfloat xyScale = 1/tan(fov/2); diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index 2d4c71907..b2e8ea696 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -41,6 +41,15 @@ template class Matrix { _data[size*i+i] = static_cast(1); } + /** + * @brief Initializer-list constructor + * @param first First value + * @param next Next values + * + * Note that the values are in column-major order. + */ + template inline Matrix(T first, U&&... next): _data{first, std::forward(next)...} {} + /** * @brief Constructor * @param data One-dimensional array of @c size*size length in column-major order. diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index 6ce34b804..7309e3441 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -30,6 +30,9 @@ template class Matrix3: public Matrix { /** @copydoc Matrix::Matrix(bool) */ inline Matrix3(bool identity = true): Matrix(identity) {} + /** @copydoc Matrix::Matrix(T, U&&...) */ + template inline Matrix3(T first, U&&... next): Matrix(first, std::forward(next)...) {} + /** @copydoc Matrix::Matrix(const T*) */ inline Matrix3(const T* data): Matrix(data) {} diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 84159f04d..7bc0eeaa3 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -76,27 +76,29 @@ template class Matrix4: public Matrix { T yz = vn.y()*vn.z(); T zz = vn.z()*vn.z(); - /* Not creating identity matrix, as nearly all ones would be - overwritten */ - Matrix4 out(false); - out.set(3, 3, T(1)); - - out.set(0, 0, cosine + xx*oneMinusCosine); - out.set(0, 1, xy*oneMinusCosine - vn.z()*sine); - out.set(0, 2, xz*oneMinusCosine + vn.y()*sine); - out.set(1, 0, xy*oneMinusCosine + vn.z()*sine); - out.set(1, 1, cosine + yy*oneMinusCosine); - out.set(1, 2, yz*oneMinusCosine - vn.x()*sine); - out.set(2, 0, xz*oneMinusCosine - vn.y()*sine); - out.set(2, 1, yz*oneMinusCosine + vn.x()*sine); - out.set(2, 2, cosine + zz*oneMinusCosine); - - return out; + return Matrix4( /* Column-major! */ + cosine + xx*oneMinusCosine, + xy*oneMinusCosine + vn.z()*sine, + xz*oneMinusCosine - vn.y()*sine, + T(0), + xy*oneMinusCosine - vn.z()*sine, + cosine + yy*oneMinusCosine, + yz*oneMinusCosine + vn.x()*sine, + T(0), + xz*oneMinusCosine + vn.y()*sine, + yz*oneMinusCosine - vn.x()*sine, + cosine + zz*oneMinusCosine, + T(0), + T(0), T(0), T(0), T(1) + ); } /** @copydoc Matrix::Matrix(bool) */ inline Matrix4(bool identity = true): Matrix(identity) {} + /** @copydoc Matrix::Matrix(T, U&&...) */ + template inline Matrix4(T first, U&&... next): Matrix(first, std::forward(next)...) {} + /** @copydoc Matrix::Matrix(const T*) */ inline Matrix4(const T* data): Matrix(data) {} diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index 870f47bea..fb9b7881a 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -30,14 +30,14 @@ namespace Magnum { namespace Math { namespace Test { typedef Math::Matrix3 Matrix3; void Matrix3Test::debug() { - float m[] = { - 3, 5, 8, - 4, 4, 7, - 7, -1, 8, - }; + Matrix3 m( + 3.0f, 5.0f, 8.0f, + 4.0f, 4.0f, 7.0f, + 7.0f, -1.0f, 8.0f + ); ostringstream o; - Debug(&o) << Matrix3(m); + Debug(&o) << m; QCOMPARE(QString::fromStdString(o.str()), QString("Matrix(3, 4, 7,\n" " 5, 4, -1,\n" " 8, 7, 8)\n")); diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index 0da2b4af4..ea0f25b35 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -31,48 +31,48 @@ namespace Magnum { namespace Math { namespace Test { typedef Math::Matrix4 Matrix4; void Matrix4Test::translation() { - float matrix[] = { + Matrix4 matrix( 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 - }; + ); - QVERIFY(Matrix4::translation({3.0f, 1.0f, 2.0f}) == Matrix4(matrix)); + QVERIFY(Matrix4::translation({3.0f, 1.0f, 2.0f}) == matrix); } void Matrix4Test::scaling() { - float matrix[] = { + Matrix4 matrix( 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 - }; + ); - QVERIFY(Matrix4::scaling({3.0f, 1.5f, 2.0f}) == Matrix4(matrix)); + QVERIFY(Matrix4::scaling({3.0f, 1.5f, 2.0f}) == matrix); } void Matrix4Test::rotation() { - float matrix[] = { + Matrix4 matrix( 0.35612214f, -0.80181062f, 0.47987163f, 0.0f, 0.47987163f, 0.59757638f, 0.6423595f, 0.0f, -0.80181062f, 0.0015183985f, 0.59757638f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f - }; + ); - QVERIFY(Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}) == Matrix4(matrix)); + QVERIFY(Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}) == matrix); } void Matrix4Test::debug() { - float m[] = { - 3, 5, 8, 4, - 4, 4, 7, 3, - 7, -1, 8, 0, - 9, 4, 5, 9 - }; + Matrix4 m( + 3.0f, 5.0f, 8.0f, 4.0f, + 4.0f, 4.0f, 7.0f, 3.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 9.0f, 4.0f, 5.0f, 9.0f + ); ostringstream o; - Debug(&o) << Matrix4(m); + Debug(&o) << m; QCOMPARE(QString::fromStdString(o.str()), QString("Matrix(3, 4, 7, 9,\n" " 5, 4, -1, 4,\n" " 8, 7, 8, 5,\n" diff --git a/src/Math/Test/MatrixTest.cpp b/src/Math/Test/MatrixTest.cpp index 3f61ddc1b..06ec1be4b 100644 --- a/src/Math/Test/MatrixTest.cpp +++ b/src/Math/Test/MatrixTest.cpp @@ -31,30 +31,48 @@ typedef Matrix Matrix4; typedef Matrix Matrix3; typedef Vector Vector4; +void MatrixTest::construct() { + float m[] = { + 3.0f, 5.0f, 8.0f, 4.0f, + 4.0f, 4.0f, 7.0f, 3.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 9.0f, 4.0f, 5.0f, 9.0f + }; + + Matrix4 expected( + 3.0f, 5.0f, 8.0f, 4.0f, + 4.0f, 4.0f, 7.0f, 3.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 9.0f, 4.0f, 5.0f, 9.0f + ); + + QVERIFY(Matrix4(m) == expected); +} + void MatrixTest::constructIdentity() { Matrix4 identity; - float identityExpected[] = { + Matrix4 identityExpected( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f - }; + ); - QVERIFY(identity == Matrix4(identityExpected)); + QVERIFY(identity == identityExpected); } void MatrixTest::constructZero() { Matrix4 zero(false); - float zeroExpected[] = { + Matrix4 zeroExpected( 0.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, 0.0f, 0.0f, 0.0f - }; + ); - QVERIFY(zero == Matrix4(zeroExpected)); + QVERIFY(zero == zeroExpected); } void MatrixTest::data() { @@ -71,14 +89,14 @@ void MatrixTest::data() { QVERIFY(m.at(1, 2) == 1.0f); QVERIFY(m.at(3) == vector); - float expected[] = { + Matrix4 expected( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 4.0f, 5.0f, 6.0f, 7.0f - }; + ); - QVERIFY(m == Matrix4(expected)); + QVERIFY(m == expected); } void MatrixTest::copy() { @@ -104,141 +122,137 @@ void MatrixTest::copy() { } void MatrixTest::multiplyIdentity() { - float values[] = { + Matrix4 values( 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f - }; + ); - QVERIFY(Matrix4()*Matrix4(values) == Matrix4(values)); - QVERIFY(Matrix4(values)*Matrix4() == Matrix4(values)); + QVERIFY(Matrix4()*values == values); + QVERIFY(values*Matrix4() == values); } void MatrixTest::multiply() { - int left[] = { + Matrix left( -3, -3, -1, 3, -5, -1, -3, -5, 2, 3, -1, -4, 3, -1, -2, -5, -5, -1, -4, -1, 1, 3, -3, -4, -1 - }; + ); - int right[] = { + Matrix right( 0, 5, 3, 4, 4, 5, 5, 0, 0, -2, 3, 2, -4, -3, 0, -3, 0, -1, 2, -1, 0, -1, -4, 4, 3 - }; + ); - int expected[] = { + Matrix expected( -24, -35, -32, -25, 1, -22, -36, -24, 33, -8, 8, 16, -22, 29, 2, -1, 0, 1, -12, 16, -12, 8, -20, -26, -2 - }; - - bool is = (Matrix(left)*Matrix(right) == Matrix(expected)); + ); - QVERIFY(is); + QVERIFY(left*right == expected); } void MatrixTest::multiplyVector() { - int matrix[] = { + Matrix matrix( -3, -3, -1, 3, -5, -1, -3, -5, 2, 3, -1, -4, 3, -1, -2, -5, -5, -1, -4, -1, 1, 3, -3, -4, -1 - }; + ); - bool is = (Matrix(matrix)*Vector(0, 5, 3, 4, 4) == Vector(-24, -35, -32, -25, 1)); + bool is = (matrix*Vector(0, 5, 3, 4, 4) == Vector(-24, -35, -32, -25, 1)); QVERIFY(is); } void MatrixTest::transposed() { - float original[] = { + Matrix4 original( 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f - }; + ); - float transposed[] = { + Matrix4 transposed( 0.0f, 4.0f, 8.0f, 12.0f, 1.0f, 5.0f, 9.0f, 13.0f, 2.0f, 6.0f, 10.0f, 14.0f, 3.0f, 7.0f, 11.0f, 15.0f - }; + ); - QVERIFY(Matrix4(original).transposed() == Matrix4(transposed)); + QVERIFY(original.transposed() == transposed); } void MatrixTest::ij() { - float original[] = { + Matrix4 original( 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f - }; + ); - float skipped[] = { + Matrix3 skipped( 0.0f, 1.0f, 3.0f, 8.0f, 9.0f, 11.0f, 12.0f, 13.0f, 15.0f - }; + ); - QVERIFY(Matrix4(original).ij(2, 1) == Matrix3(skipped)); + QVERIFY(original.ij(2, 1) == skipped); } void MatrixTest::determinant() { - int m[] = { + Matrix m( 1, 2, 2, 1, 0, 2, 3, 2, 1, -2, 1, 1, 1, 1, 0, 2, 0, 0, 1, 2, 3, 1, 0, 1, -2 - }; + ); - int d = Matrix(m).determinant(); - - QVERIFY(d == -2); + QVERIFY(m.determinant() == -2); } void MatrixTest::inverse() { - float m[] = { - 3, 5, 8, 4, - 4, 4, 7, 3, - 7, -1, 8, 0, - 9, 4, 5, 9 - }; - - float inverse[] = { + Matrix4 m( + 3.0f, 5.0f, 8.0f, 4.0f, + 4.0f, 4.0f, 7.0f, 3.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 9.0f, 4.0f, 5.0f, 9.0f + ); + + Matrix4 inverse( -60/103.0f, 71/103.0f, -4/103.0f, 3/103.0f, -66/103.0f, 109/103.0f, -25/103.0f, -7/103.0f, 177/412.0f, -97/206.0f, 53/412.0f, -7/206.0f, 259/412.0f, -185/206.0f, 31/412.0f, 27/206.0f - }; + ); - Matrix4 _inverse = Matrix4(m).inverse(); + Matrix4 _inverse = m.inverse(); - QVERIFY(_inverse == Matrix4(inverse)); - QVERIFY(_inverse*Matrix4(m) == Matrix4()); + QVERIFY(_inverse == inverse); + QVERIFY(_inverse*m == Matrix4()); } void MatrixTest::debug() { - float m[] = { - 3, 5, 8, 4, - 4, 4, 7, 3, - 7, -1, 8, 0, - 9, 4, 5, 9 - }; + Matrix4 m( + 3.0f, 5.0f, 8.0f, 4.0f, + 4.0f, 4.0f, 7.0f, 3.0f, + 7.0f, -1.0f, 8.0f, 0.0f, + 9.0f, 4.0f, 5.0f, 9.0f + ); ostringstream o; - Debug(&o) << Matrix4(m); + Debug(&o) << m; QCOMPARE(QString::fromStdString(o.str()), QString("Matrix(3, 4, 7, 9,\n" " 5, 4, -1, 4,\n" " 8, 7, 8, 5,\n" diff --git a/src/Math/Test/MatrixTest.h b/src/Math/Test/MatrixTest.h index fc034daca..899681d0d 100644 --- a/src/Math/Test/MatrixTest.h +++ b/src/Math/Test/MatrixTest.h @@ -23,6 +23,7 @@ class MatrixTest: public QObject { Q_OBJECT private slots: + void construct(); void constructIdentity(); void constructZero(); void data();