From b9c96d76e85fdf43cef62ca9f868dc79da6c3939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 24 Aug 2018 21:11:34 +0200 Subject: [PATCH] Math: ability to use [Dual]Complex and [Dual]Quaternion in configuration. --- doc/changelog.dox | 3 +++ src/Magnum/Math/Complex.h | 22 +++++++++++++++++ src/Magnum/Math/DualComplex.h | 22 +++++++++++++++++ src/Magnum/Math/DualQuaternion.h | 26 +++++++++++++++++++++ src/Magnum/Math/Quaternion.h | 22 +++++++++++++++++ src/Magnum/Math/Test/ComplexTest.cpp | 24 ++++++++++++++++++- src/Magnum/Math/Test/DualComplexTest.cpp | 24 ++++++++++++++++++- src/Magnum/Math/Test/DualQuaternionTest.cpp | 24 ++++++++++++++++++- src/Magnum/Math/Test/QuaternionTest.cpp | 24 ++++++++++++++++++- src/Magnum/Math/instantiation.cpp | 5 ++++ 10 files changed, 192 insertions(+), 4 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index d389e8f89..5c893bf37 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -83,6 +83,9 @@ See also: @ref Math::Distance::pointPlane() and others - Ability to convert @ref Math::BoolVector from and to external representation +- Ability to use @ref Math::Complex, @ref Math::DualComplex, + @ref Math::Quaternion, @ref Math::DualQuaternion with + @ref Corrade::Utility::Configuration and @ref Corrade::Utility::Arguments @subsubsection changelog-latest-new-platform Platform libraries diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index ff40522a4..f966aa2ef 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -471,4 +471,26 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili }} +namespace Corrade { namespace Utility { + +/** @configurationvalue{Magnum::Math::Complex} */ +template struct ConfigurationValue> { + ConfigurationValue() = delete; + + /** @brief Writes elements separated with spaces */ + static std::string toString(const Magnum::Math::Complex& value, ConfigurationValueFlags flags) { + return ConfigurationValue>::toString(reinterpret_cast&>(value), flags); + } + + /** @brief Reads elements separated with whitespace */ + static Magnum::Math::Complex fromString(const std::string& stringValue, ConfigurationValueFlags flags) { + const Magnum::Math::Vector<2, T> value = ConfigurationValue>::fromString(stringValue, flags); + return reinterpret_cast&>(value); + } +}; + +/* No explicit instantiation needed, as Vector<2, T> is instantiated already */ + +}} + #endif diff --git a/src/Magnum/Math/DualComplex.h b/src/Magnum/Math/DualComplex.h index 2dc3b03ae..59a7da4b7 100644 --- a/src/Magnum/Math/DualComplex.h +++ b/src/Magnum/Math/DualComplex.h @@ -372,4 +372,26 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili }} +namespace Corrade { namespace Utility { + +/** @configurationvalue{Magnum::Math::DualComplex} */ +template struct ConfigurationValue> { + ConfigurationValue() = delete; + + /** @brief Writes elements separated with spaces */ + static std::string toString(const Magnum::Math::DualComplex& value, ConfigurationValueFlags flags) { + return ConfigurationValue>::toString(reinterpret_cast&>(value), flags); + } + + /** @brief Reads elements separated with whitespace */ + static Magnum::Math::DualComplex fromString(const std::string& stringValue, ConfigurationValueFlags flags) { + const Magnum::Math::Vector<4, T> value = ConfigurationValue>::fromString(stringValue, flags); + return reinterpret_cast&>(value); + } +}; + +/* No explicit instantiation needed, as Vector<4, T> is instantiated already */ + +}} + #endif diff --git a/src/Magnum/Math/DualQuaternion.h b/src/Magnum/Math/DualQuaternion.h index 398d6f168..81c4a95ae 100644 --- a/src/Magnum/Math/DualQuaternion.h +++ b/src/Magnum/Math/DualQuaternion.h @@ -451,4 +451,30 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili }} +namespace Corrade { namespace Utility { + +/** @configurationvalue{Magnum::Math::DualQuaternion} */ +template struct ConfigurationValue> { + ConfigurationValue() = delete; + + /** @brief Writes elements separated with spaces */ + static std::string toString(const Magnum::Math::DualQuaternion& value, ConfigurationValueFlags flags) { + return ConfigurationValue>::toString(reinterpret_cast&>(value), flags); + } + + /** @brief Reads elements separated with whitespace */ + static Magnum::Math::DualQuaternion fromString(const std::string& stringValue, ConfigurationValueFlags flags) { + const Magnum::Math::Vector<8, T> value = ConfigurationValue>::fromString(stringValue, flags); + return reinterpret_cast&>(value); + } +}; + +/* Explicit instantiation for commonly used types */ +#if !defined(DOXYGEN_GENERATING_OUTPUT) && !defined(__MINGW32__) +extern template struct MAGNUM_EXPORT ConfigurationValue>; +extern template struct MAGNUM_EXPORT ConfigurationValue>; +#endif + +}} + #endif diff --git a/src/Magnum/Math/Quaternion.h b/src/Magnum/Math/Quaternion.h index 366c89bb3..9075b2798 100644 --- a/src/Magnum/Math/Quaternion.h +++ b/src/Magnum/Math/Quaternion.h @@ -614,4 +614,26 @@ template inline Vector3 Quaternion::transformVectorNormalized(con }} +namespace Corrade { namespace Utility { + +/** @configurationvalue{Magnum::Math::Quaternion} */ +template struct ConfigurationValue> { + ConfigurationValue() = delete; + + /** @brief Writes elements separated with spaces */ + static std::string toString(const Magnum::Math::Quaternion& value, ConfigurationValueFlags flags) { + return ConfigurationValue>::toString(reinterpret_cast&>(value), flags); + } + + /** @brief Reads elements separated with whitespace */ + static Magnum::Math::Quaternion fromString(const std::string& stringValue, ConfigurationValueFlags flags) { + const Magnum::Math::Vector<4, T> value = ConfigurationValue>::fromString(stringValue, flags); + return reinterpret_cast&>(value); + } +}; + +/* No explicit instantiation needed, as Vector<4, T> is instantiated already */ + +}} + #endif diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index c10234e11..c5540a1bc 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "Magnum/Math/Complex.h" #include "Magnum/Math/Matrix3.h" @@ -88,6 +89,7 @@ struct ComplexTest: Corrade::TestSuite::Tester { void transformVector(); void debug(); + void configuration(); }; ComplexTest::ComplexTest() { @@ -128,7 +130,8 @@ ComplexTest::ComplexTest() { &ComplexTest::matrix, &ComplexTest::transformVector, - &ComplexTest::debug}); + &ComplexTest::debug, + &ComplexTest::configuration}); } typedef Math::Deg Deg; @@ -425,6 +428,25 @@ void ComplexTest::debug() { CORRADE_COMPARE(o.str(), "Complex(2.5, -7.5)\n"); } +void ComplexTest::configuration() { + Corrade::Utility::Configuration c; + + Complex x{3.0f, 3.125f}; + std::string value{"3 3.125"}; + + c.setValue("complex", x); + CORRADE_COMPARE(c.value("complex"), value); + CORRADE_COMPARE(c.value("complex"), x); + + /* Underflow */ + c.setValue("underflow", "2.1"); + CORRADE_COMPARE(c.value("underflow"), (Complex{2.1f, 0.0f})); + + /* Overflow */ + c.setValue("overflow", "2 9 16 33"); + CORRADE_COMPARE(c.value("overflow"), (Complex{2.0f, 9.0f})); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::ComplexTest) diff --git a/src/Magnum/Math/Test/DualComplexTest.cpp b/src/Magnum/Math/Test/DualComplexTest.cpp index b48ba31bf..7637520aa 100644 --- a/src/Magnum/Math/Test/DualComplexTest.cpp +++ b/src/Magnum/Math/Test/DualComplexTest.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "Magnum/Math/DualComplex.h" #include "Magnum/Math/DualQuaternion.h" @@ -87,6 +88,7 @@ struct DualComplexTest: Corrade::TestSuite::Tester { void transformPoint(); void debug(); + void configuration(); }; typedef Math::Deg Deg; @@ -135,7 +137,8 @@ DualComplexTest::DualComplexTest() { &DualComplexTest::matrix, &DualComplexTest::transformPoint, - &DualComplexTest::debug}); + &DualComplexTest::debug, + &DualComplexTest::configuration}); } void DualComplexTest::construct() { @@ -418,6 +421,25 @@ void DualComplexTest::debug() { CORRADE_COMPARE(o.str(), "DualComplex({-1, -2.5}, {-3, -7.5})\n"); } +void DualComplexTest::configuration() { + Corrade::Utility::Configuration c; + + DualComplex a{{3.0f, 3.125f}, {9.0f, 9.55f}}; + std::string value("3 3.125 9 9.55"); + + c.setValue("dualcomplex", a); + CORRADE_COMPARE(c.value("dualcomplex"), value); + CORRADE_COMPARE(c.value("dualcomplex"), a); + + /* Underflow */ + c.setValue("underflow", "2.1 8.9"); + CORRADE_COMPARE(c.value("underflow"), (DualComplex{{2.1f, 8.9f}, {0.0f, 0.0f}})); + + /* Overflow */ + c.setValue("overflow", "2 1 8 9 16 33"); + CORRADE_COMPARE(c.value("overflow"), (DualComplex{{2.0f, 1.0f}, {8.0f, 9.0f}})); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::DualComplexTest) diff --git a/src/Magnum/Math/Test/DualQuaternionTest.cpp b/src/Magnum/Math/Test/DualQuaternionTest.cpp index b2aa2cbbc..578342963 100644 --- a/src/Magnum/Math/Test/DualQuaternionTest.cpp +++ b/src/Magnum/Math/Test/DualQuaternionTest.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "Magnum/Math/DualQuaternion.h" @@ -91,6 +92,7 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester { void sclerp(); void debug(); + void configuration(); }; typedef Math::Deg Deg; @@ -143,7 +145,8 @@ DualQuaternionTest::DualQuaternionTest() { &DualQuaternionTest::sclerp, - &DualQuaternionTest::debug}); + &DualQuaternionTest::debug, + &DualQuaternionTest::configuration}); } void DualQuaternionTest::construct() { @@ -513,6 +516,25 @@ void DualQuaternionTest::debug() { CORRADE_COMPARE(o.str(), "DualQuaternion({{1, 2, 3}, -4}, {{0.5, -3.1, 3.3}, 2})\n"); } +void DualQuaternionTest::configuration() { + Corrade::Utility::Configuration c; + + DualQuaternion a{{{3.0f, 3.125f, 9.0f}, 9.55f}, {{-1.2f, 0.3f, 1.1f}, 92.05f}}; + std::string value{"3 3.125 9 9.55 -1.2 0.3 1.1 92.05"}; + + c.setValue("dualquat", a); + CORRADE_COMPARE(c.value("dualquat"), value); + CORRADE_COMPARE(c.value("dualquat"), a); + + /* Underflow */ + c.setValue("underflow", "2.1 8.9"); + CORRADE_COMPARE(c.value("underflow"), (DualQuaternion{{{2.1f, 8.9f, 0.0f}, 0.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f}})); + + /* Overflow */ + c.setValue("overflow", "2 1 8 9 16 33 -1 5 2 10"); + CORRADE_COMPARE(c.value("overflow"), (DualQuaternion{{{2.0f, 1.0f, 8.0f}, 9.0f}, {{16.0f, 33.0f, -1.0f}, 5.0f}})); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::DualQuaternionTest) diff --git a/src/Magnum/Math/Test/QuaternionTest.cpp b/src/Magnum/Math/Test/QuaternionTest.cpp index 07709a2e4..98e3149b2 100644 --- a/src/Magnum/Math/Test/QuaternionTest.cpp +++ b/src/Magnum/Math/Test/QuaternionTest.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "Magnum/Math/Matrix4.h" #include "Magnum/Math/Quaternion.h" @@ -92,6 +93,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester { void transformVectorNormalized(); void debug(); + void configuration(); }; typedef Math::Deg Deg; @@ -143,7 +145,8 @@ QuaternionTest::QuaternionTest() { &QuaternionTest::transformVector, &QuaternionTest::transformVectorNormalized, - &QuaternionTest::debug}); + &QuaternionTest::debug, + &QuaternionTest::configuration}); } void QuaternionTest::construct() { @@ -523,6 +526,25 @@ void QuaternionTest::debug() { CORRADE_COMPARE(o.str(), "Quaternion({1, 2, 3}, -4)\n"); } +void QuaternionTest::configuration() { + Corrade::Utility::Configuration c; + + Quaternion q{{3.0f, 3.125f, 9.0f}, 9.55f}; + std::string value{"3 3.125 9 9.55"}; + + c.setValue("quat", q); + CORRADE_COMPARE(c.value("quat"), value); + CORRADE_COMPARE(c.value("quat"), q); + + /* Underflow */ + c.setValue("underflow", "2.1 8.9"); + CORRADE_COMPARE(c.value("underflow"), (Quaternion{{2.1f, 8.9f, 0.0f}, 0.0f})); + + /* Overflow */ + c.setValue("overflow", "2 1 8 9 16 33"); + CORRADE_COMPARE(c.value("overflow"), (Quaternion{{2.0f, 1.0f, 8.0f}, 9.0f})); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::QuaternionTest) diff --git a/src/Magnum/Math/instantiation.cpp b/src/Magnum/Math/instantiation.cpp index ab986612f..f6cf11909 100644 --- a/src/Magnum/Math/instantiation.cpp +++ b/src/Magnum/Math/instantiation.cpp @@ -80,6 +80,11 @@ template struct ConfigurationValue>; template struct ConfigurationValue>; template struct ConfigurationValue>; template struct ConfigurationValue>; + +/* Other (complex, dual complex, quaternion) just reinterpret to 2/4-component + vectors instantiated above */ +template struct ConfigurationValue>; +template struct ConfigurationValue>; #endif }}