summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp12
-rw-r--r--src/gui/math3d/qmatrix4x4.h22
-rw-r--r--tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp61
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