diff --git a/src/Math/DualQuaternion.h b/src/Math/DualQuaternion.h index 9bf1d185c..56039ea5d 100644 --- a/src/Math/DualQuaternion.h +++ b/src/Math/DualQuaternion.h @@ -20,6 +20,7 @@ */ #include "Math/Dual.h" +#include "Math/Matrix4.h" #include "Math/Quaternion.h" namespace Magnum { namespace Math { @@ -137,6 +138,15 @@ template class DualQuaternion: public Dual> { return (this->dual()*this->real().conjugated()).vector()*T(2); } + /** + * @brief Convert dual quaternion to transformation matrix + * + * @see Quaternion::matrix() + */ + Matrix4 matrix() const { + return Matrix4::from(this->real().matrix(), translation()); + } + /** * @brief Quaternion-conjugated dual quaternion * diff --git a/src/Math/Quaternion.h b/src/Math/Quaternion.h index 8246ce995..74572bc55 100644 --- a/src/Math/Quaternion.h +++ b/src/Math/Quaternion.h @@ -200,7 +200,7 @@ template class Quaternion { /** * @brief Convert quaternion to rotation matrix * - * @see Matrix4::from(const Matrix<3, T>&, const Vector3&) + * @see DualQuaternion::matrix(), Matrix4::from(const Matrix<3, T>&, const Vector3&) */ Matrix<3, T> matrix() const { return { diff --git a/src/Math/Test/DualQuaternionTest.cpp b/src/Math/Test/DualQuaternionTest.cpp index 35c64dae0..ed3f20e55 100644 --- a/src/Math/Test/DualQuaternionTest.cpp +++ b/src/Math/Test/DualQuaternionTest.cpp @@ -18,7 +18,6 @@ #include "Math/Constants.h" #include "Math/DualQuaternion.h" -#include "Math/Matrix4.h" namespace Magnum { namespace Math { namespace Test { @@ -40,6 +39,7 @@ class DualQuaternionTest: public Corrade::TestSuite::Tester { void rotation(); void translation(); void combinedTransformParts(); + void matrix(); void transformPointNormalized(); void debug(); @@ -67,6 +67,7 @@ DualQuaternionTest::DualQuaternionTest() { &DualQuaternionTest::rotation, &DualQuaternionTest::translation, &DualQuaternionTest::combinedTransformParts, + &DualQuaternionTest::matrix, &DualQuaternionTest::transformPointNormalized, &DualQuaternionTest::debug); @@ -159,6 +160,15 @@ void DualQuaternionTest::combinedTransformParts() { CORRADE_COMPARE(b.translation(), Quaternion::rotation(deg(23.0f), Vector3::xAxis()).rotateVectorNormalized(translation)); } +void DualQuaternionTest::matrix() { + DualQuaternion q = DualQuaternion::rotation(deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({-1.0f, 2.0f, 3.0f}); + Matrix4 m = Matrix4::rotationX(deg(23.0f))*Matrix4::translation({-1.0f, 2.0f, 3.0f}); + + /* Verify that negated dual quaternion gives the same transformation */ + CORRADE_COMPARE(q.matrix(), m); + CORRADE_COMPARE((-q).matrix(), m); +} + void DualQuaternionTest::transformPointNormalized() { DualQuaternion a = DualQuaternion::translation({-1.0f, 2.0f, 3.0f})*DualQuaternion::rotation(deg(23.0f), Vector3::xAxis()); DualQuaternion b = DualQuaternion::rotation(deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({-1.0f, 2.0f, 3.0f}); diff --git a/src/Math/Test/QuaternionTest.cpp b/src/Math/Test/QuaternionTest.cpp index 1a39fc565..fcf1994a1 100644 --- a/src/Math/Test/QuaternionTest.cpp +++ b/src/Math/Test/QuaternionTest.cpp @@ -239,14 +239,12 @@ void QuaternionTest::angle() { } void QuaternionTest::matrix() { - float angle = deg(37.0f); - Vector3 axis(1.0f/Constants::sqrt3()); - Quaternion q = Quaternion::rotation(angle, axis); - Matrix3 expected = Matrix4::rotation(angle, axis).rotationScaling(); - CORRADE_COMPARE(q.matrix(), expected); + Quaternion q = Quaternion::rotation(deg(37.0f), Vector3(1.0f/Constants::sqrt3())); + Matrix3 m = Matrix4::rotation(deg(37.0f), Vector3(1.0f/Constants::sqrt3())).rotationScaling(); /* Verify that negated quaternion gives the same rotation */ - CORRADE_COMPARE((-q).matrix(), expected); + CORRADE_COMPARE(q.matrix(), m); + CORRADE_COMPARE((-q).matrix(), m); } void QuaternionTest::lerp() {