summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2015-02-26 18:04:43 +0400
committerKonstantin Ritt <ritt.ks@gmail.com>2015-04-07 13:07:48 +0000
commit95d034a14f78aaefd6990de180f715c8b4d510b1 (patch)
treef1f2879ffd11dd697ee268a335e92aacfb07a5f9 /tests
parent3fb6014ce71febe1cb18ceaff16840bb4aea7deb (diff)
Introduce QQuaternion::fromDirection()
...which constructs a quaternion using specified forward and upward directions, so that the resulting Z axis "faces" a given forward direction. Change-Id: Ib77b8ab5c359a4880b0d946face87026acdc6f0b Reviewed-by: Paul Lemire <paul.lemire@kdab.com> Reviewed-by: Michael Krasnyk <michael.krasnyk@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp
index 2c38e4c111..ec7af97f07 100644
--- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp
+++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp
@@ -141,6 +141,9 @@ private slots:
void rotationTo_data();
void rotationTo();
+ void fromDirection_data();
+ void fromDirection();
+
void fromEulerAngles_data();
void fromEulerAngles();
@@ -989,6 +992,97 @@ void tst_QQuaternion::rotationTo()
QVERIFY(myFuzzyCompare(vec2, from));
}
+static QByteArray testnameForAxis(const QVector3D &axis)
+{
+ QByteArray testname;
+ if (axis == QVector3D()) {
+ testname = "null";
+ } else {
+ if (axis.x()) {
+ testname += axis.x() < 0 ? "-" : "+";
+ testname += "X";
+ }
+ if (axis.y()) {
+ testname += axis.y() < 0 ? "-" : "+";
+ testname += "Y";
+ }
+ if (axis.z()) {
+ testname += axis.z() < 0 ? "-" : "+";
+ testname += "Z";
+ }
+ }
+ return testname;
+}
+
+// Test quaternion convertion to and from orthonormal axes.
+void tst_QQuaternion::fromDirection_data()
+{
+ QTest::addColumn<QVector3D>("direction");
+ QTest::addColumn<QVector3D>("up");
+
+ QList<QQuaternion> orientations;
+ orientations << QQuaternion();
+ for (int angle = 45; angle <= 360; angle += 45) {
+ orientations << QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), angle)
+ << QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), angle)
+ << QQuaternion::fromAxisAndAngle(QVector3D(0, 0, 1), angle)
+ << QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), angle)
+ * QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), angle)
+ * QQuaternion::fromAxisAndAngle(QVector3D(0, 0, 1), angle);
+ }
+
+ // othonormal up and dir
+ foreach (const QQuaternion &q, orientations) {
+ QVector3D xAxis, yAxis, zAxis;
+ q.getAxes(&xAxis, &yAxis, &zAxis);
+
+ QTest::newRow("dir: " + testnameForAxis(zAxis) + ", up: " + testnameForAxis(yAxis))
+ << zAxis * 10.0f << yAxis * 10.0f;
+ }
+
+ // collinear up and dir
+ QTest::newRow("dir: +X, up: +X") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(10.0f, 0.0f, 0.0f);
+ QTest::newRow("dir: +X, up: -X") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(-10.0f, 0.0f, 0.0f);
+ QTest::newRow("dir: +Y, up: +Y") << QVector3D(0.0f, 10.0f, 0.0f) << QVector3D(0.0f, 10.0f, 0.0f);
+ QTest::newRow("dir: +Y, up: -Y") << QVector3D(0.0f, 10.0f, 0.0f) << QVector3D(0.0f, -10.0f, 0.0f);
+ QTest::newRow("dir: +Z, up: +Z") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 0.0f, 10.0f);
+ QTest::newRow("dir: +Z, up: -Z") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 0.0f, -10.0f);
+ QTest::newRow("dir: +X+Y+Z, up: +X+Y+Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(10.0f, 10.0f, 10.0f);
+ QTest::newRow("dir: +X+Y+Z, up: -X-Y-Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(-10.0f, -10.0f, -10.0f);
+
+ // invalid up
+ foreach (const QQuaternion &q, orientations) {
+ QVector3D xAxis, yAxis, zAxis;
+ q.getAxes(&xAxis, &yAxis, &zAxis);
+
+ QTest::newRow("dir: " + testnameForAxis(zAxis) + ", up: null")
+ << zAxis * 10.0f << QVector3D();
+ }
+}
+void tst_QQuaternion::fromDirection()
+{
+ QFETCH(QVector3D, direction);
+ QFETCH(QVector3D, up);
+
+ QVector3D expextedZ(direction != QVector3D() ? direction.normalized() : QVector3D(0, 0, 1));
+ QVector3D expextedY(up.normalized());
+
+ QQuaternion result = QQuaternion::fromDirection(direction, up);
+ QVERIFY(myFuzzyCompare(result, result.normalized()));
+
+ QVector3D xAxis, yAxis, zAxis;
+ result.getAxes(&xAxis, &yAxis, &zAxis);
+
+ QVERIFY(myFuzzyCompare(zAxis, expextedZ));
+
+ if (!qFuzzyIsNull(QVector3D::crossProduct(expextedZ, expextedY).lengthSquared())) {
+ QVector3D expextedX(QVector3D::crossProduct(expextedY, expextedZ));
+
+ QVERIFY(myFuzzyCompare(yAxis, expextedY));
+ QVERIFY(myFuzzyCompare(xAxis, expextedX));
+ }
+}
+
// Test quaternion creation from an axis and an angle.
void tst_QQuaternion::fromEulerAngles_data()
{