From 98fcf3cb611fe895e6998726ae39bdd30512c98b Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Mon, 10 May 2021 15:32:26 +0200 Subject: QtGui/math3d : Fix QQuaternion::getEulerAngles When rotating M_PI_2 based on x-axis, quaternion to euler conversion makes NaN for the x-rotation value. This patch fixes this corner case. Fixes: QTBUG-93600 Change-Id: Ice321a80ad90dba9cf3ee3a14ec7d3d047c21bd3 Reviewed-by: Laszlo Agocs Reviewed-by: Andy Nichols (cherry picked from commit 7ea2fbddcf674d49ad7d219cdb8a4b760258360c) Reviewed-by: Qt Cherry-pick Bot --- .../gui/math3d/qquaternion/tst_qquaternion.cpp | 36 +++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index b4b24548db..7d19601946 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -1085,35 +1085,38 @@ void tst_QQuaternion::fromEulerAngles_data() QTest::addColumn("yaw"); QTest::addColumn("roll"); + QTest::addColumn("quaternion"); + QTest::newRow("null") - << 0.0f << 0.0f << 0.0f; + << 0.0f << 0.0f << 0.0f << QQuaternion(1.0f, 0.0f, 0.0f, 0.0f); QTest::newRow("xonly") - << 90.0f << 0.0f << 0.0f; + << 90.0f << 0.0f << 0.0f << QQuaternion(0.707107f, 0.707107f, 0.0f, 0.0f); QTest::newRow("yonly") - << 0.0f << 180.0f << 0.0f; + << 0.0f << 180.0f << 0.0f << QQuaternion(0.0f, 0.0f, 1.0f, 0.0f); QTest::newRow("zonly") - << 0.0f << 0.0f << 270.0f; + << 0.0f << 0.0f << 270.0f << QQuaternion(-0.707107f, 0.0f, 0.0f, 0.707107f); QTest::newRow("x+z") - << 30.0f << 0.0f << 45.0f; + << 30.0f << 0.0f << 45.0f << QQuaternion(0.892399f, 0.239118f, -0.099046f, 0.369644f); QTest::newRow("x+y") - << 30.0f << 90.0f << 0.0f; + << 30.0f << 90.0f << 0.0f << QQuaternion(0.683013f, 0.183013f, 0.683013f, -0.183013f); QTest::newRow("y+z") - << 0.0f << 45.0f << 30.0f; + << 0.0f << 45.0f << 30.0f << QQuaternion(0.892399f, 0.099046f, 0.369644f, 0.239118f); QTest::newRow("complex") - << 30.0f << 240.0f << -45.0f; + << 30.0f << 240.0f << -45.0f << QQuaternion(-0.531976f, -0.43968f, 0.723317f, -0.02226f); } void tst_QQuaternion::fromEulerAngles() { QFETCH(float, pitch); QFETCH(float, yaw); QFETCH(float, roll); + QFETCH(QQuaternion, quaternion); // Use a straight-forward implementation of the algorithm at: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q60 @@ -1129,11 +1132,22 @@ void tst_QQuaternion::fromEulerAngles() QVERIFY(myFuzzyCompare(answer.z(), result.z())); QVERIFY(myFuzzyCompare(answer.scalar(), result.scalar())); + // quaternion should be the same as the result + QVERIFY(myFuzzyCompare(answer.x(), quaternion.x())); + QVERIFY(myFuzzyCompare(answer.y(), quaternion.y())); + QVERIFY(myFuzzyCompare(answer.z(), quaternion.z())); + QVERIFY(myFuzzyCompare(answer.scalar(), quaternion.scalar())); + { QVector3D answerEulerAngles = answer.toEulerAngles(); QVERIFY(myFuzzyCompareDegrees(answerEulerAngles.x(), pitch)); QVERIFY(myFuzzyCompareDegrees(answerEulerAngles.y(), yaw)); QVERIFY(myFuzzyCompareDegrees(answerEulerAngles.z(), roll)); + + QVector3D quaternionEulerAngles = quaternion.toEulerAngles(); + QVERIFY(myFuzzyCompareDegrees(quaternionEulerAngles.x(), pitch)); + QVERIFY(myFuzzyCompareDegrees(quaternionEulerAngles.y(), yaw)); + QVERIFY(myFuzzyCompareDegrees(quaternionEulerAngles.z(), roll)); } answer = QQuaternion::fromEulerAngles(pitch, yaw, roll); @@ -1148,6 +1162,12 @@ void tst_QQuaternion::fromEulerAngles() QVERIFY(myFuzzyCompareDegrees(answerPitch, pitch)); QVERIFY(myFuzzyCompareDegrees(answerYaw, yaw)); QVERIFY(myFuzzyCompareDegrees(answerRoll, roll)); + + float quaternionPitch, quaternionYaw, quaternionRoll; + quaternion.getEulerAngles(&quaternionPitch, &quaternionYaw, &quaternionRoll); + QVERIFY(myFuzzyCompareDegrees(quaternionPitch, pitch)); + QVERIFY(myFuzzyCompareDegrees(quaternionYaw, yaw)); + QVERIFY(myFuzzyCompareDegrees(quaternionRoll, roll)); } } -- cgit v1.2.3