diff options
-rw-r--r-- | src/gui/math3d/qmatrix4x4.cpp | 12 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.h | 22 | ||||
-rw-r--r-- | tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp | 61 |
3 files changed, 94 insertions, 1 deletions
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 123c0f0..ed1b13d 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1502,7 +1502,17 @@ QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const Maps \a point by multiplying this matrix by \a point. - \sa mapRect() + \sa mapRect(), mapVector() +*/ + +/*! + \fn QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const + + Maps \a vector by multiplying the top 3x3 portion of this matrix + by \a vector. The translation and projection components of + this matrix are ignored. + + \sa map() */ #endif diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 7631ae7..cfa3f2a 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -165,6 +165,7 @@ public: QPointF map(const QPointF& point) const; #ifndef QT_NO_VECTOR3D QVector3D map(const QVector3D& point) const; + QVector3D mapVector(const QVector3D& vector) const; #endif #ifndef QT_NO_VECTOR4D QVector4D map(const QVector4D& point) const; @@ -940,6 +941,27 @@ inline QVector3D QMatrix4x4::map(const QVector3D& point) const return *this * point; } +inline QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const +{ + if (flagBits == Identity || flagBits == Translation) { + return vector; + } else if (flagBits == Scale || flagBits == (Translation | Scale)) { + return QVector3D(vector.x() * m[0][0], + vector.y() * m[1][1], + vector.z() * m[2][2]); + } else { + return QVector3D(vector.x() * m[0][0] + + vector.y() * m[1][0] + + vector.z() * m[2][0], + vector.x() * m[0][1] + + vector.y() * m[1][1] + + vector.z() * m[2][1], + vector.x() * m[0][2] + + vector.y() * m[1][2] + + vector.z() * m[2][2]); + } +} + #endif #ifndef QT_NO_VECTOR4D diff --git a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp index 90db496..ff5e00f 100644 --- a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp @@ -170,6 +170,9 @@ private slots: void mapRect_data(); void mapRect(); + void mapVector_data(); + void mapVector(); + void properties(); void metaTypes(); @@ -3317,6 +3320,64 @@ void tst_QMatrixNxN::mapRect() QVERIFY(mri == tri); } +void tst_QMatrixNxN::mapVector_data() +{ + QTest::addColumn<void *>("mValues"); + + QTest::newRow("null") + << (void *)nullValues4; + + QTest::newRow("identity") + << (void *)identityValues4; + + QTest::newRow("unique") + << (void *)uniqueValues4; + + static const qreal scale[] = + {2.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 11.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -6.5f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; + QTest::newRow("scale") + << (void *)scale; + + static const qreal scaleTranslate[] = + {2.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 11.0f, 0.0f, 2.0f, + 0.0f, 0.0f, -6.5f, 3.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; + QTest::newRow("scaleTranslate") + << (void *)scaleTranslate; + + static const qreal translate[] = + {1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 2.0f, + 0.0f, 0.0f, 1.0f, 3.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; + QTest::newRow("translate") + << (void *)translate; +} +void tst_QMatrixNxN::mapVector() +{ + QFETCH(void *, mValues); + + QMatrix4x4 m1((const qreal *)mValues); + m1.inferSpecialType(); + + QVector3D v(3.5f, -1.0f, 2.5f); + + QVector3D expected + (v.x() * m1(0, 0) + v.y() * m1(0, 1) + v.z() * m1(0, 2), + v.x() * m1(1, 0) + v.y() * m1(1, 1) + v.z() * m1(1, 2), + v.x() * m1(2, 0) + v.y() * m1(2, 1) + v.z() * m1(2, 2)); + + QVector3D actual = m1.mapVector(v); + + QVERIFY(fuzzyCompare(actual.x(), expected.x())); + QVERIFY(fuzzyCompare(actual.y(), expected.y())); + QVERIFY(fuzzyCompare(actual.z(), expected.z())); +} + class tst_QMatrixNxN4x4Properties : public QObject { Q_OBJECT |