diff --git a/src/Math/Quaternion.h b/src/Math/Quaternion.h index 4effe4f28..adaf3c5fa 100644 --- a/src/Math/Quaternion.h +++ b/src/Math/Quaternion.h @@ -20,6 +20,7 @@ */ #include +#include #include #include "Vector3.h" @@ -134,13 +135,26 @@ template class Quaternion { /** * @brief Inverted quaternion * - * If the quaternion is already normalized, this function is - * equivalent to conjugated(). + * See invertedNormalized() which is faster for normalized + * quaternions. */ inline Quaternion inverted() const { return conjugated()/lengthSquared(); } + /** + * @brief Inverted normalized quaternion + * + * Equivalent to conjugated(). Assumes that the quaternion is + * normalized. + */ + inline Quaternion invertedNormalized() const { + CORRADE_ASSERT(MathTypeTraits::equals(lengthSquared(), T(1)), + "Math::Quaternion::invertedNormalized(): quaternion must be normalized", + Quaternion({}, std::numeric_limits::quiet_NaN())); + return conjugated(); + } + private: Vector3 _vector; T _scalar; diff --git a/src/Math/Test/CMakeLists.txt b/src/Math/Test/CMakeLists.txt index c193b8335..13b60f6ab 100644 --- a/src/Math/Test/CMakeLists.txt +++ b/src/Math/Test/CMakeLists.txt @@ -20,4 +20,4 @@ corrade_add_test(MathSwizzleTest SwizzleTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathQuaternionTest MathQuaternionTest.cpp LIBRARIES MagnumMathTestLib) -set_target_properties(MathVectorTest MathMatrix3Test MathMatrix4Test PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) +set_target_properties(MathVectorTest MathMatrix3Test MathMatrix4Test MathQuaternionTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) diff --git a/src/Math/Test/MathQuaternionTest.cpp b/src/Math/Test/MathQuaternionTest.cpp index 24fccec56..0e3de5aa0 100644 --- a/src/Math/Test/MathQuaternionTest.cpp +++ b/src/Math/Test/MathQuaternionTest.cpp @@ -31,6 +31,7 @@ class QuaternionTest: public Corrade::TestSuite::Tester { void normalized(); void conjugated(); void inverted(); + void invertedNormalized(); void debug(); }; @@ -46,6 +47,7 @@ QuaternionTest::QuaternionTest() { &QuaternionTest::normalized, &QuaternionTest::conjugated, &QuaternionTest::inverted, + &QuaternionTest::invertedNormalized, &QuaternionTest::debug); } @@ -94,6 +96,23 @@ void QuaternionTest::inverted() { CORRADE_COMPARE(inverted, Quaternion({-1.0f, -3.0f, 2.0f}, -4.0f)/30.0f); } +void QuaternionTest::invertedNormalized() { + Quaternion a = Quaternion({1.0f, 3.0f, -2.0f}, -4.0f); + + std::ostringstream o; + Corrade::Utility::Error::setOutput(&o); + Quaternion notInverted = a.invertedNormalized(); + CORRADE_COMPARE(notInverted.vector(), Vector3()); + CORRADE_COMPARE(notInverted.scalar(), std::numeric_limits::quiet_NaN()); + CORRADE_COMPARE(o.str(), "Math::Quaternion::invertedNormalized(): quaternion must be normalized\n"); + + Quaternion aNormalized = a.normalized(); + Quaternion inverted = aNormalized.invertedNormalized(); + CORRADE_COMPARE(aNormalized*inverted, Quaternion()); + CORRADE_COMPARE(inverted*aNormalized.normalized(), Quaternion()); + CORRADE_COMPARE(inverted, Quaternion({-1.0f, -3.0f, 2.0f}, -4.0f)/std::sqrt(30.0f)); +} + void QuaternionTest::debug() { std::ostringstream o;