diff --git a/doc/changelog.dox b/doc/changelog.dox index 4ef5b3e33..398d6ceaf 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -110,6 +110,17 @@ See also: bootstrap project for using Magnum together with gtkmm (see [mosra/magnum-bootstrap#24](https://github.com/mosra/magnum-bootstrap/pull/24)) +@subsubsection changelog-latest-new-scenegraph SceneGraph library + +- All 2D transformation implementations that support rotation now have a + @ref SceneGraph::AbstractBasicTranslationRotation2D::rotate(const Math::Complex&) "rotate()" + and @ref SceneGraph::AbstractBasicTranslationRotation2D::rotateLocal(const Math::Complex&) "rotateLocal()" + overloads taking a @ref Math::Complex +- All 3D transformation implementations that support rotation now have a + @ref SceneGraph::AbstractBasicTranslationRotation3D::rotate(const Math::Quaternion&) "rotate()" + and @ref SceneGraph::AbstractBasicTranslationRotation3D::rotateLocal(const Math::Quaternion&) "rotateLocal()" + overloads taking a @ref Math::Quaternion + @subsubsection changelog-latest-new-vk Vk library - Updated Vulkan headers for version 1.2 diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h b/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h index 2fdfe2ffd..b319b0ac8 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotation2D.h @@ -46,12 +46,39 @@ template class AbstractBasicTranslationRotation2D: public AbstractBasic public: explicit AbstractBasicTranslationRotation2D() = default; + /** + * @brief Rotate the object using a complex number + * @param complex Normalized complex number + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Expects that the complex number is normalized. + * @see @ref rotate(Math::Rad), + * @ref rotateLocal(const Math::Complex&) + */ + AbstractBasicTranslationRotation2D& rotate(const Math::Complex& complex) { + doRotate(complex); + return *this; + } + + /** + * @brief Rotate the object using a complex number as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + AbstractBasicTranslationRotation2D& rotateLocal(const Math::Complex& complex) { + doRotateLocal(complex); + return *this; + } + /** * @brief Rotate the object * @param angle Angle (counterclockwise) * @return Reference to self (for method chaining) * - * @see @ref rotateLocal() + * @see @ref rotate(const Math::Complex&), @ref rotateLocal() */ AbstractBasicTranslationRotation2D& rotate(Math::Rad angle) { doRotate(angle); @@ -89,10 +116,22 @@ template class AbstractBasicTranslationRotation2D: public AbstractBasic ~AbstractBasicTranslationRotation2D() = default; private: - /** @brief Polymorphic implementation for @ref rotate() */ + /** + * @brief Polymorphic implementation for @ref rotate(const Math::Complex&) + * @m_since_latest + */ + virtual void doRotate(const Math::Complex&) = 0; + + /** + * @brief Polymorphic implementation for @ref rotateLocal(const Math::Complex&) + * @m_since_latest + */ + virtual void doRotateLocal(const Math::Complex&) = 0; + + /** @brief Polymorphic implementation for @ref rotate(Math::Rad) */ virtual void doRotate(Math::Rad angle) = 0; - /** @brief Polymorphic implementation for @ref rotateLocal() */ + /** @brief Polymorphic implementation for @ref rotateLocal(Math::Rad) */ virtual void doRotateLocal(Math::Rad angle) = 0; }; diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h b/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h index 16c7ffad4..04ff8d344 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotation3D.h @@ -47,15 +47,44 @@ template class AbstractBasicTranslationRotation3D: public AbstractBasic public: explicit AbstractBasicTranslationRotation3D() = default; + /** + * @brief Rotate the object using a quaternion + * @param quaternion Normalized quaternion + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Expects that the quaternion is normalized. + * @see @ref rotate(Math::Rad, const Math::Vector3&), + * @ref rotateLocal(const Math::Quaternion&), @ref rotateX(), + * @ref rotateY(), @ref rotateZ() + */ + AbstractBasicTranslationRotation3D& rotate(const Math::Quaternion& quaternion) { + doRotate(quaternion); + return *this; + } + + /** + * @brief Rotate the object using a quaternion as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + AbstractBasicTranslationRotation3D& rotateLocal(const Math::Quaternion& quaternion) { + doRotateLocal(quaternion); + return *this; + } + /** * @brief Rotate the object * @param angle Angle (counterclockwise) * @param normalizedAxis Normalized rotation axis * @return Reference to self (for method chaining) * - * @see @ref rotateLocal(), @ref rotateX(), @ref rotateY(), - * @ref rotateZ(), @ref Math::Vector3::xAxis(), - * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + * @see @ref rotate(const Math::Quaternion&), @ref rotateLocal(), + * @ref rotateX(), @ref rotateY(), @ref rotateZ(), + * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), + * @ref Math::Vector3::zAxis() */ AbstractBasicTranslationRotation3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { doRotate(angle, normalizedAxis); @@ -177,10 +206,22 @@ template class AbstractBasicTranslationRotation3D: public AbstractBasic ~AbstractBasicTranslationRotation3D() = default; private: - /** @brief Polymorphic implementation for @ref rotate() */ + /** + * @brief Polymorphic implementation for @ref rotate(const Math::Quaternion&) + * @m_since_latest + */ + virtual void doRotate(const Math::Quaternion&) = 0; + + /** + * @brief Polymorphic implementation for @ref rotateLocal(const Math::Quaternion&) + * @m_since_latest + */ + virtual void doRotateLocal(const Math::Quaternion&) = 0; + + /** @brief Polymorphic implementation for @ref rotate(Math::Rad, const Math::Vector3&) */ virtual void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) = 0; - /** @brief Polymorphic implementation for @ref rotateLocal() */ + /** @brief Polymorphic implementation for @ref rotateLocal(Math::Rad, const Math::Vector3&) */ virtual void doRotateLocal(Math::Rad angle, const Math::Vector3& normalizedAxis) = 0; /** diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h index 54143df54..c9995cdfa 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h @@ -83,6 +83,14 @@ template class AbstractBasicTranslationRotationScaling2D: public Abstra AbstractBasicTranslationRotation2D::translateLocal(vector); return *this; } + AbstractBasicTranslationRotationScaling2D& rotate(const Math::Complex& complex) { + AbstractBasicTranslationRotation2D::rotate(complex); + return *this; + } + AbstractBasicTranslationRotationScaling2D& rotateLocal(const Math::Complex& complex) { + AbstractBasicTranslationRotation2D::rotateLocal(complex); + return *this; + } AbstractBasicTranslationRotationScaling2D& rotate(Math::Rad angle) { AbstractBasicTranslationRotation2D::rotate(angle); return *this; diff --git a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h index 4a95fc93b..9a88c4d7c 100644 --- a/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h +++ b/src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h @@ -83,6 +83,14 @@ template class AbstractBasicTranslationRotationScaling3D: public Abstra AbstractBasicTranslationRotation3D::translateLocal(vector); return *this; } + AbstractBasicTranslationRotationScaling3D& rotate(const Math::Quaternion& quaternion) { + AbstractBasicTranslationRotation3D::rotate(quaternion); + return *this; + } + AbstractBasicTranslationRotationScaling3D& rotateLocal(const Math::Quaternion& quaternion) { + AbstractBasicTranslationRotation3D::rotateLocal(quaternion); + return *this; + } AbstractBasicTranslationRotationScaling3D& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { AbstractBasicTranslationRotation3D::rotate(angle, normalizedAxis); return *this; diff --git a/src/Magnum/SceneGraph/CMakeLists.txt b/src/Magnum/SceneGraph/CMakeLists.txt index 5647415b6..06d10c0e9 100644 --- a/src/Magnum/SceneGraph/CMakeLists.txt +++ b/src/Magnum/SceneGraph/CMakeLists.txt @@ -52,11 +52,15 @@ set(MagnumSceneGraph_HEADERS DualComplexTransformation.h DualQuaternionTransformation.h RigidMatrixTransformation2D.h + RigidMatrixTransformation2D.hpp RigidMatrixTransformation3D.h + RigidMatrixTransformation3D.hpp FeatureGroup.h FeatureGroup.hpp MatrixTransformation2D.h + MatrixTransformation2D.hpp MatrixTransformation3D.h + MatrixTransformation3D.hpp Object.h Object.hpp Scene.h diff --git a/src/Magnum/SceneGraph/DualComplexTransformation.h b/src/Magnum/SceneGraph/DualComplexTransformation.h index f229cf8ec..5344c9dd4 100644 --- a/src/Magnum/SceneGraph/DualComplexTransformation.h +++ b/src/Magnum/SceneGraph/DualComplexTransformation.h @@ -132,13 +132,40 @@ template class BasicDualComplexTransformation: public AbstractBasicTran return transformLocalInternal(Math::DualComplex::translation(vector)); } + /** + * @brief Rotate the object using a complex number + * @param complex Normalized complex number + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Same as calling @ref transform() with @p complex. Expects that the + * complex number is normalized. + * @see @ref rotate(Math::Rad), + * @ref rotateLocal(const Math::Complex&) + */ + Object>& rotate(const Math::Complex& complex) { + return transformInternal(complex); + } + + /** + * @brief Rotate the object using a complex number as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(const Math::Complex& complex) { + return transformLocalInternal(complex); + } + /** * @brief Rotate the object * @param angle Angle (counterclockwise) * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::DualComplex::rotation(). - * @see @ref rotateLocal(), @ref normalizeRotation() + * @see @ref rotate(const Math::Complex&), @ref rotateLocal(), + * @ref normalizeRotation() */ Object>& rotate(Math::Rad angle) { return transformInternal(Math::DualComplex::rotation(angle)); @@ -168,6 +195,13 @@ template class BasicDualComplexTransformation: public AbstractBasicTran translateLocal(vector); } + void doRotate(const Math::Complex& complex) override final { + rotate(complex); + } + void doRotateLocal(const Math::Complex& complex) override final { + rotateLocal(complex); + } + void doRotate(Math::Rad angle) override final { rotate(angle); } void doRotateLocal(Math::Rad angle) override final { rotateLocal(angle); } diff --git a/src/Magnum/SceneGraph/DualQuaternionTransformation.h b/src/Magnum/SceneGraph/DualQuaternionTransformation.h index fc481dbf4..e06cf0319 100644 --- a/src/Magnum/SceneGraph/DualQuaternionTransformation.h +++ b/src/Magnum/SceneGraph/DualQuaternionTransformation.h @@ -131,6 +131,33 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT return transformLocalInternal(Math::DualQuaternion::translation(vector)); } + /** + * @brief Rotate the object using a quaternion + * @param quaternion Normalized quaternion + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Same as calling @ref transform() with @p quaternion. Expects that + * the quaternion is normalized. + * @see @ref rotate(Math::Rad, const Math::Vector3&), + * @ref rotateLocal(const Math::Quaternion&), @ref rotateX(), + * @ref rotateY(), @ref rotateZ() + */ + Object>& rotate(const Math::Quaternion& quaternion) { + return transformInternal(quaternion); + } + + /** + * @brief Rotate the object using a quaternion as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(const Math::Quaternion& quaternion) { + return transformLocalInternal(quaternion); + } + /** * @brief Rotate the object * @param angle Angle (counterclockwise) @@ -138,9 +165,9 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::DualQuaternion::rotation(). - * @see @ref rotateLocal(), @ref Math::Vector3::xAxis(), - * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis(), - * @ref normalizeRotation() + * @see @ref rotate(const Math::Quaternion&), @ref rotateLocal(), + * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), + * @ref Math::Vector3::zAxis(), @ref normalizeRotation() */ Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { return transformInternal(Math::DualQuaternion::rotation(angle, normalizedAxis)); @@ -192,6 +219,13 @@ template class BasicDualQuaternionTransformation: public AbstractBasicT translateLocal(vector); } + void doRotate(const Math::Quaternion& quaternion) override final { + rotate(quaternion); + } + void doRotateLocal(const Math::Quaternion& quaternion) override final { + rotateLocal(quaternion); + } + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { rotate(angle, normalizedAxis); } diff --git a/src/Magnum/SceneGraph/MatrixTransformation2D.h b/src/Magnum/SceneGraph/MatrixTransformation2D.h index dfd6276ba..7f36e745f 100644 --- a/src/Magnum/SceneGraph/MatrixTransformation2D.h +++ b/src/Magnum/SceneGraph/MatrixTransformation2D.h @@ -114,6 +114,27 @@ template class BasicMatrixTransformation2D: public AbstractBasicTransla return transformLocal(Math::Matrix3::translation(vector)); } + /** + * @brief Rotate the object using a complex number + * @param complex Normalized complex number + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Expects that the complex number is normalized. + * @see @ref rotate(Math::Rad), + * @ref rotateLocal(const Math::Complex&) + */ + Object>& rotate(const Math::Complex& complex); + + /** + * @brief Rotate the object using a complex number as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(const Math::Complex& complex); + /** * @brief Rotate the object * @param angle Angle (counterclockwise) @@ -195,6 +216,13 @@ template class BasicMatrixTransformation2D: public AbstractBasicTransla void doTranslate(const Math::Vector2& vector) override final { translate(vector); } void doTranslateLocal(const Math::Vector2& vector) override final { translateLocal(vector); } + void doRotate(const Math::Complex& complex) override final { + rotate(complex); + } + void doRotateLocal(const Math::Complex& complex) override final { + rotateLocal(complex); + } + void doRotate(Math::Rad angle) override final { rotate(angle); } void doRotateLocal(Math::Rad angle) override final { rotateLocal(angle); } @@ -234,6 +262,7 @@ template struct Transformation> { } #if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__) +extern template class MAGNUM_SCENEGRAPH_EXPORT BasicMatrixTransformation2D; extern template class MAGNUM_SCENEGRAPH_EXPORT Object>; #endif diff --git a/src/Magnum/SceneGraph/MatrixTransformation2D.hpp b/src/Magnum/SceneGraph/MatrixTransformation2D.hpp new file mode 100644 index 000000000..aa45000fa --- /dev/null +++ b/src/Magnum/SceneGraph/MatrixTransformation2D.hpp @@ -0,0 +1,51 @@ +#ifndef Magnum_SceneGraph_MatrixTransformation2D_hpp +#define Magnum_SceneGraph_MatrixTransformation2D_hpp +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief @ref compilation-speedup-hpp "Template implementation" for @ref MatrixTransformation2D.h + * @m_since_latest + */ + +#include "MatrixTransformation2D.h" + +#include "Magnum/Math/Complex.h" + +namespace Magnum { namespace SceneGraph { + +/* These are here to avoid including Complex in MatrixTransformation2D.h */ + +template Object>& BasicMatrixTransformation2D::rotate(const Math::Complex& complex) { + return transform(Matrix3::from(complex.toMatrix(), {})); +} + +template Object>& BasicMatrixTransformation2D::rotateLocal(const Math::Complex& complex) { + return transformLocal(Matrix3::from(complex.toMatrix(), {})); +} + +}} + +#endif diff --git a/src/Magnum/SceneGraph/MatrixTransformation3D.h b/src/Magnum/SceneGraph/MatrixTransformation3D.h index f2ba5b4a3..4229b15f9 100644 --- a/src/Magnum/SceneGraph/MatrixTransformation3D.h +++ b/src/Magnum/SceneGraph/MatrixTransformation3D.h @@ -114,6 +114,28 @@ template class BasicMatrixTransformation3D: public AbstractBasicTransla return transformLocal(Math::Matrix4::translation(vector)); } + /** + * @brief Rotate the object using a quaternion + * @param quaternion Normalized quaternion + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Expects that the quaternion is normalized. + * @see @ref rotate(Math::Rad, const Math::Vector3&), + * @ref rotateLocal(const Math::Quaternion&), @ref rotateX(), + * @ref rotateY(), @ref rotateZ() + */ + Object>& rotate(const Math::Quaternion& quaternion); + + /** + * @brief Rotate the object using a quaternion as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(const Math::Quaternion& quaternion); + /** * @brief Rotate the object * @param angle Angle (counterclockwise) @@ -121,9 +143,10 @@ template class BasicMatrixTransformation3D: public AbstractBasicTransla * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::rotation(). - * @see @ref rotateLocal(), @ref rotateX(), @ref rotateY(), - * @ref rotateZ(), @ref Math::Vector3::xAxis(), - * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() + * @see @ref rotate(const Math::Quaternion&), @ref rotateLocal(), + * @ref rotateX(), @ref rotateY(), @ref rotateZ(), + * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), + * @ref Math::Vector3::zAxis() */ Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { return transform(Math::Matrix4::rotation(angle, normalizedAxis)); @@ -266,6 +289,13 @@ template class BasicMatrixTransformation3D: public AbstractBasicTransla void doTranslate(const Math::Vector3& vector) override final { translate(vector); } void doTranslateLocal(const Math::Vector3& vector) override final { translateLocal(vector); } + void doRotate(const Math::Quaternion& quaternion) override final { + rotate(quaternion); + } + void doRotateLocal(const Math::Quaternion& quaternion) override final { + rotateLocal(quaternion); + } + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { rotate(angle, normalizedAxis); } @@ -318,6 +348,7 @@ template struct Transformation> { } #if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__) +extern template class MAGNUM_SCENEGRAPH_EXPORT BasicMatrixTransformation3D; extern template class MAGNUM_SCENEGRAPH_EXPORT Object>; #endif diff --git a/src/Magnum/SceneGraph/MatrixTransformation3D.hpp b/src/Magnum/SceneGraph/MatrixTransformation3D.hpp new file mode 100644 index 000000000..f983da697 --- /dev/null +++ b/src/Magnum/SceneGraph/MatrixTransformation3D.hpp @@ -0,0 +1,51 @@ +#ifndef Magnum_SceneGraph_MatrixTransformation3D_hpp +#define Magnum_SceneGraph_MatrixTransformation3D_hpp +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief @ref compilation-speedup-hpp "Template implementation" for @ref MatrixTransformation3D.h + * @m_since_latest + */ + +#include "MatrixTransformation3D.h" + +#include "Magnum/Math/Quaternion.h" + +namespace Magnum { namespace SceneGraph { + +/* These are here to avoid including Quaternion in MatrixTransformation3D.h */ + +template Object>& BasicMatrixTransformation3D::rotate(const Math::Quaternion& quaternion) { + return transform(Matrix4::from(quaternion.toMatrix(), {})); +} + +template Object>& BasicMatrixTransformation3D::rotateLocal(const Math::Quaternion& quaternion) { + return transformLocal(Matrix4::from(quaternion.toMatrix(), {})); +} + +}} + +#endif diff --git a/src/Magnum/SceneGraph/Object.h b/src/Magnum/SceneGraph/Object.h index 3fcf0adb1..daddf6bbd 100644 --- a/src/Magnum/SceneGraph/Object.h +++ b/src/Magnum/SceneGraph/Object.h @@ -76,20 +76,24 @@ and @ref previousSibling(). @section SceneGraph-Object-explicit-specializations Explicit template specializations -The following specializations are explicitly compiled into @ref SceneGraph +The following specializations are explicitly compiled into the @ref SceneGraph library. For other specializations (e.g. using @ref Magnum::Double "Double" -type or special transformation class) you have to use @ref Object.hpp -implementation file to avoid linker errors. See also relevant sections in -@ref SceneGraph-AbstractObject-explicit-specializations "AbstractObject" and +type or special transformation class) you have to use the @ref Object.hpp +implementation file (and possibly others) to avoid linker errors. See also +relevant sections in the @ref SceneGraph-AbstractObject-explicit-specializations "AbstractObject" and @ref SceneGraph-AbstractTransformation-explicit-specializations "AbstractTransformation" class documentation or @ref compilation-speedup-hpp for more information. - @ref DualComplexTransformation "Object" - @ref DualQuaternionTransformation "Object" -- @ref MatrixTransformation2D "Object" -- @ref MatrixTransformation3D "Object" +- @ref MatrixTransformation2D "Object" (custom + specializations need also @ref MatrixTransformation2D.hpp) +- @ref MatrixTransformation3D "Object" (custom + specializations need also @ref MatrixTransformation3D.hpp) - @ref RigidMatrixTransformation2D "Object" + (custom specializations need also @ref RigidMatrixTransformation2D.hpp) - @ref RigidMatrixTransformation3D "Object" + (custom specializations need also @ref RigidMatrixTransformation3D.hpp) - @ref TranslationTransformation2D "Object" - @ref TranslationTransformation3D "Object" diff --git a/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h b/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h index 431786ce3..6cfa90870 100644 --- a/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h +++ b/src/Magnum/SceneGraph/RigidMatrixTransformation2D.h @@ -137,6 +137,27 @@ template class BasicRigidMatrixTransformation2D: public AbstractBasicTr return transformLocalInternal(Math::Matrix3::translation(vector)); } + /** + * @brief Rotate the object using a complex number + * @param complex Normalized complex number + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Expects that the complex number is normalized. + * @see @ref rotate(Math::Rad), + * @ref rotateLocal(const Math::Complex&) + */ + Object>& rotate(const Math::Complex& complex); + + /** + * @brief Rotate the object using a complex number as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(const Math::Complex& complex); + /** * @brief Rotate the object * @param angle Angle (counterclockwise) @@ -195,6 +216,13 @@ template class BasicRigidMatrixTransformation2D: public AbstractBasicTr void doTranslate(const Math::Vector2& vector) override final { translate(vector); } void doTranslateLocal(const Math::Vector2& vector) override final { translateLocal(vector); } + void doRotate(const Math::Complex& complex) override final { + rotate(complex); + } + void doRotateLocal(const Math::Complex& complex) override final { + rotateLocal(complex); + } + void doRotate(Math::Rad angle) override final { rotate(angle); } void doRotateLocal(Math::Rad angle) override final { rotateLocal(angle); } @@ -254,6 +282,7 @@ template struct Transformation> { } #if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__) +extern template class MAGNUM_SCENEGRAPH_EXPORT BasicRigidMatrixTransformation2D; extern template class MAGNUM_SCENEGRAPH_EXPORT Object>; #endif diff --git a/src/Magnum/SceneGraph/RigidMatrixTransformation2D.hpp b/src/Magnum/SceneGraph/RigidMatrixTransformation2D.hpp new file mode 100644 index 000000000..c84fb9c30 --- /dev/null +++ b/src/Magnum/SceneGraph/RigidMatrixTransformation2D.hpp @@ -0,0 +1,51 @@ +#ifndef Magnum_SceneGraph_RigidMatrixTransformation2D_hpp +#define Magnum_SceneGraph_RigidMatrixTransformation2D_hpp +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief @ref compilation-speedup-hpp "Template implementation" for @ref RigidMatrixTransformation2D.h + * @m_since_latest + */ + +#include "RigidMatrixTransformation2D.h" + +#include "Magnum/Math/Complex.h" + +namespace Magnum { namespace SceneGraph { + +/* These are here to avoid including Complex in RigidMatrixTransformation2D.h */ + +template Object>& BasicRigidMatrixTransformation2D::rotate(const Math::Complex& complex) { + return transform(Matrix3::from(complex.toMatrix(), {})); +} + +template Object>& BasicRigidMatrixTransformation2D::rotateLocal(const Math::Complex& complex) { + return transformLocal(Matrix3::from(complex.toMatrix(), {})); +} + +}} + +#endif diff --git a/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h b/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h index 9b34b84ca..17edaed49 100644 --- a/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h +++ b/src/Magnum/SceneGraph/RigidMatrixTransformation3D.h @@ -136,6 +136,28 @@ template class BasicRigidMatrixTransformation3D: public AbstractBasicTr return transformLocalInternal(Math::Matrix4::translation(vector)); } + /** + * @brief Rotate the object using a quaternion + * @param quaternion Normalized quaternion + * @return Reference to self (for method chaining) + * @m_since_latest + * + * Expects that the quaternion is normalized. + * @see @ref rotate(Math::Rad, const Math::Vector3&), + * @ref rotateLocal(const Math::Quaternion&), @ref rotateX(), + * @ref rotateY(), @ref rotateZ() + */ + Object>& rotate(const Math::Quaternion& quaternion); + + /** + * @brief Rotate the object using a quaternion as a local transformation + * @m_since_latest + * + * Similar to the above, except that the transformation is applied + * before all others. + */ + Object>& rotateLocal(const Math::Quaternion& quaternion); + /** * @brief Rotate the object * @param angle Angle (counterclockwise) @@ -143,10 +165,10 @@ template class BasicRigidMatrixTransformation3D: public AbstractBasicTr * @return Reference to self (for method chaining) * * Same as calling @ref transform() with @ref Math::Matrix4::rotation(). - * @see @ref rotateLocal(), @ref rotateX(), @ref rotateY(), - * @ref rotateZ(), @ref normalizeRotation(), - * @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(), - * @ref Math::Vector3::zAxis() + * @see @ref rotate(const Math::Quaternion&), @ref rotateLocal(), + * @ref rotateX(), @ref rotateY(), @ref rotateZ(), + * @ref normalizeRotation(), @ref Math::Vector3::xAxis(), + * @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis() */ Object>& rotate(Math::Rad angle, const Math::Vector3& normalizedAxis) { return transformInternal(Math::Matrix4::rotation(angle, normalizedAxis)); @@ -266,6 +288,13 @@ template class BasicRigidMatrixTransformation3D: public AbstractBasicTr void doTranslate(const Math::Vector3& vector) override final { translate(vector); } void doTranslateLocal(const Math::Vector3& vector) override final { translateLocal(vector); } + void doRotate(const Math::Quaternion& quaternion) override final { + rotate(quaternion); + } + void doRotateLocal(const Math::Quaternion& quaternion) override final { + rotateLocal(quaternion); + } + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { rotate(angle, normalizedAxis); } @@ -338,6 +367,7 @@ template struct Transformation> { } #if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__) +extern template class MAGNUM_SCENEGRAPH_EXPORT BasicRigidMatrixTransformation3D; extern template class MAGNUM_SCENEGRAPH_EXPORT Object>; #endif diff --git a/src/Magnum/SceneGraph/RigidMatrixTransformation3D.hpp b/src/Magnum/SceneGraph/RigidMatrixTransformation3D.hpp new file mode 100644 index 000000000..cc3f2ccb0 --- /dev/null +++ b/src/Magnum/SceneGraph/RigidMatrixTransformation3D.hpp @@ -0,0 +1,51 @@ +#ifndef Magnum_SceneGraph_RigidMatrixTransformation3D_hpp +#define Magnum_SceneGraph_RigidMatrixTransformation3D_hpp +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief @ref compilation-speedup-hpp "Template implementation" for @ref RigidMatrixTransformation3D.hpp + * @m_since_latest + */ + +#include "RigidMatrixTransformation3D.h" + +#include "Magnum/Math/Quaternion.h" + +namespace Magnum { namespace SceneGraph { + +/* These are here to avoid including Quaternion in the header */ + +template Object>& BasicRigidMatrixTransformation3D::rotate(const Math::Quaternion& quaternion) { + return transform(Matrix4::from(quaternion.toMatrix(), {})); +} + +template Object>& BasicRigidMatrixTransformation3D::rotateLocal(const Math::Quaternion& quaternion) { + return transformLocal(Matrix4::from(quaternion.toMatrix(), {})); +} + +}} + +#endif diff --git a/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp b/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp index 325aa375f..5fe7ca870 100644 --- a/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp +++ b/src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp @@ -65,6 +65,8 @@ DualComplexTransformationTest::DualComplexTransformationTest() { &DualComplexTransformationTest::normalizeRotation}); } +using namespace Math::Literals; + void DualComplexTransformationTest::fromMatrix() { Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f}); @@ -158,13 +160,15 @@ void DualComplexTransformationTest::translate() { void DualComplexTransformationTest::rotate() { { Object2D o; - o.setTransformation(DualComplex::translation({1.0f, -0.3f})); - o.rotate(Deg(17.0f)); + o.setTransformation(DualComplex::translation({1.0f, -0.3f})) + .rotate(Complex::rotation(7.0_degf)) + .rotate(10.0_degf); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } { Object2D o; - o.setTransformation(DualComplex::translation({1.0f, -0.3f})); - o.rotateLocal(Deg(17.0f)); + o.setTransformation(DualComplex::translation({1.0f, -0.3f})) + .rotateLocal(Complex::rotation(7.0_degf)) + .rotateLocal(10.0_degf); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f))); } } diff --git a/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp b/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp index 61dffd1ea..2e8dc9005 100644 --- a/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp +++ b/src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp @@ -65,6 +65,8 @@ DualQuaternionTransformationTest::DualQuaternionTransformationTest() { &DualQuaternionTransformationTest::normalizeRotation}); } +using namespace Math::Literals; + void DualQuaternionTransformationTest::fromMatrix() { std::ostringstream o; Error redirectError{&o}; @@ -164,11 +166,12 @@ void DualQuaternionTransformationTest::translate() { void DualQuaternionTransformationTest::rotate() { { Object3D o; - o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f})); - o.rotateX(Deg(17.0f)) - .rotateY(Deg(25.0f)) - .rotateZ(Deg(-23.0f)) - .rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); + o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f})) + .rotateX(17.0_degf) + .rotateY(25.0_degf) + .rotateZ(-23.0_degf) + .rotate(Quaternion::rotation(36.0_degf, Vector3{1.0f/Constants::sqrt3()})) + .rotate(60.0_degf, Vector3{1.0f/Constants::sqrt3()}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))* Matrix4::rotationZ(Deg(-23.0f))* @@ -177,11 +180,12 @@ void DualQuaternionTransformationTest::rotate() { Matrix4::translation({1.0f, -0.3f, 2.3f})); } { Object3D o; - o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f})); - o.rotateXLocal(Deg(17.0f)) - .rotateYLocal(Deg(25.0f)) - .rotateZLocal(Deg(-23.0f)) - .rotateLocal(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); + o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f})) + .rotateXLocal(17.0_degf) + .rotateYLocal(25.0_degf) + .rotateZLocal(-23.0_degf) + .rotateLocal(Quaternion::rotation(36.0_degf, Vector3{1.0f/Constants::sqrt3()})) + .rotateLocal(60.0_degf, Vector3{1.0f/Constants::sqrt3()}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})* Matrix4::rotationX(Deg(17.0f))* diff --git a/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp b/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp index 76f4ecd9b..8a6b786d5 100644 --- a/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp +++ b/src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp @@ -25,6 +25,7 @@ #include +#include "Magnum/Math/Complex.h" #include "Magnum/SceneGraph/MatrixTransformation2D.h" #include "Magnum/SceneGraph/Scene.h" @@ -65,6 +66,8 @@ MatrixTransformation2DTest::MatrixTransformation2DTest() { &MatrixTransformation2DTest::reflect}); } +using namespace Math::Literals; + void MatrixTransformation2DTest::fromMatrix() { Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}); CORRADE_COMPARE(Implementation::Transformation::fromMatrix(m), m); @@ -143,13 +146,15 @@ void MatrixTransformation2DTest::translate() { void MatrixTransformation2DTest::rotate() { { Object2D o; - o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotate(Deg(17.0f)); + o.setTransformation(Matrix3::translation({1.0f, -0.3f})) + .rotate(Complex::rotation(7.0_degf)) + .rotate(10.0_degf); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } { Object2D o; - o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotateLocal(Deg(17.0f)); + o.setTransformation(Matrix3::translation({1.0f, -0.3f})) + .rotateLocal(Complex::rotation(7.0_degf)) + .rotateLocal(10.0_degf); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f))); } } diff --git a/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp b/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp index cc6afeb7c..48c255ce0 100644 --- a/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp +++ b/src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp @@ -25,6 +25,7 @@ #include +#include "Magnum/Math/Quaternion.h" #include "Magnum/SceneGraph/MatrixTransformation3D.h" #include "Magnum/SceneGraph/Scene.h" @@ -65,6 +66,8 @@ MatrixTransformation3DTest::MatrixTransformation3DTest() { &MatrixTransformation3DTest::reflect}); } +using namespace Math::Literals; + void MatrixTransformation3DTest::fromMatrix() { Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f}); CORRADE_COMPARE(Implementation::Transformation::fromMatrix(m), m); @@ -143,11 +146,12 @@ void MatrixTransformation3DTest::translate() { void MatrixTransformation3DTest::rotate() { { Object3D o; - o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})); - o.rotateX(Deg(17.0f)) - .rotateY(Deg(25.0f)) - .rotateZ(Deg(-23.0f)) - .rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); + o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})) + .rotateX(17.0_degf) + .rotateY(25.0_degf) + .rotateZ(-23.0_degf) + .rotate(Quaternion::rotation(36.0_degf, Vector3{1.0f/Constants::sqrt3()})) + .rotate(60.0_degf, Vector3{1.0f/Constants::sqrt3()}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))* Matrix4::rotationZ(Deg(-23.0f))* @@ -156,11 +160,12 @@ void MatrixTransformation3DTest::rotate() { Matrix4::translation({1.0f, -0.3f, 2.3f})); } { Object3D o; - o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})); - o.rotateXLocal(Deg(17.0f)) - .rotateYLocal(Deg(25.0f)) - .rotateZLocal(Deg(-23.0f)) - .rotateLocal(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); + o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})) + .rotateXLocal(17.0_degf) + .rotateYLocal(25.0_degf) + .rotateZLocal(-23.0_degf) + .rotateLocal(Quaternion::rotation(36.0_degf, Vector3{1.0f/Constants::sqrt3()})) + .rotateLocal(60.0_degf, Vector3{1.0f/Constants::sqrt3()}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})* Matrix4::rotationX(Deg(17.0f))* diff --git a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp index b33704691..8798580f6 100644 --- a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp +++ b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp @@ -27,6 +27,7 @@ #include #include +#include "Magnum/Math/Complex.h" #include "Magnum/SceneGraph/RigidMatrixTransformation2D.h" #include "Magnum/SceneGraph/Scene.h" @@ -67,6 +68,8 @@ RigidMatrixTransformation2DTest::RigidMatrixTransformation2DTest() { &RigidMatrixTransformation2DTest::normalizeRotation}); } +using namespace Math::Literals; + void RigidMatrixTransformation2DTest::fromMatrix() { std::ostringstream o; Error redirectError{&o}; @@ -163,13 +166,15 @@ void RigidMatrixTransformation2DTest::translate() { void RigidMatrixTransformation2DTest::rotate() { { Object2D o; - o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotate(Deg(17.0f)); + o.setTransformation(Matrix3::translation({1.0f, -0.3f})) + .rotate(Complex::rotation(7.0_degf)) + .rotate(10.0_degf); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f})); } { Object2D o; - o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotateLocal(Deg(17.0f)); + o.setTransformation(Matrix3::translation({1.0f, -0.3f})) + .rotateLocal(Complex::rotation(7.0_degf)) + .rotateLocal(10.0_degf); CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f))); } } diff --git a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp index 22275d617..e97a16ecb 100644 --- a/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp +++ b/src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp @@ -27,6 +27,7 @@ #include #include +#include "Magnum/Math/Quaternion.h" #include "Magnum/SceneGraph/RigidMatrixTransformation3D.h" #include "Magnum/SceneGraph/Scene.h" @@ -67,6 +68,8 @@ RigidMatrixTransformation3DTest::RigidMatrixTransformation3DTest() { &RigidMatrixTransformation3DTest::normalizeRotation}); } +using namespace Math::Literals; + void RigidMatrixTransformation3DTest::fromMatrix() { std::ostringstream o; Error redirectError{&o}; @@ -164,11 +167,12 @@ void RigidMatrixTransformation3DTest::translate() { void RigidMatrixTransformation3DTest::rotate() { { Object3D o; - o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})); - o.rotateX(Deg(17.0f)) - .rotateY(Deg(25.0f)) - .rotateZ(Deg(-23.0f)) - .rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); + o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})) + .rotateX(17.0_degf) + .rotateY(25.0_degf) + .rotateZ(-23.0_degf) + .rotate(Quaternion::rotation(36.0_degf, Vector3{1.0f/Constants::sqrt3()})) + .rotate(60.0_degf, Vector3{1.0f/Constants::sqrt3()}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))* Matrix4::rotationZ(Deg(-23.0f))* @@ -177,11 +181,12 @@ void RigidMatrixTransformation3DTest::rotate() { Matrix4::translation({1.0f, -0.3f, 2.3f})); } { Object3D o; - o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})); - o.rotateXLocal(Deg(17.0f)) - .rotateYLocal(Deg(25.0f)) - .rotateZLocal(Deg(-23.0f)) - .rotateLocal(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())); + o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f})) + .rotateXLocal(17.0_degf) + .rotateYLocal(25.0_degf) + .rotateZLocal(-23.0_degf) + .rotateLocal(Quaternion::rotation(36.0_degf, Vector3{1.0f/Constants::sqrt3()})) + .rotateLocal(60.0_degf, Vector3{1.0f/Constants::sqrt3()}); CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})* Matrix4::rotationX(Deg(17.0f))* diff --git a/src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp b/src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp index 624a07701..625387f68 100644 --- a/src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp +++ b/src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp @@ -166,7 +166,7 @@ void TranslationRotationScalingTransformation2DTest::rotate() { { Object2D o; o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotate(17.0_degf) + o.rotate(Complex::rotation(17.0_degf)) .rotate(-96.0_degf); CORRADE_COMPARE(o.translation(), (Vector2{1.0f, -0.3f})); CORRADE_COMPARE(o.rotation(), Complex::rotation(-79.0_degf)); @@ -178,7 +178,7 @@ void TranslationRotationScalingTransformation2DTest::rotate() { } { Object2D o; o.setTransformation(Matrix3::translation({1.0f, -0.3f})); - o.rotateLocal(17.0_degf) + o.rotateLocal(Complex::rotation(17.0_degf)) .rotateLocal(-96.0_degf); CORRADE_COMPARE(o.translation(), (Vector2{1.0f, -0.3f})); CORRADE_COMPARE(o.rotation(), Complex::rotation(-79.0_degf)); diff --git a/src/Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h b/src/Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h index 8d48fa474..2eb2c21a0 100644 --- a/src/Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h +++ b/src/Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h @@ -212,6 +212,13 @@ template class BasicTranslationRotationScalingTransformation2D: public void doTranslate(const Math::Vector2& vector) override final { translate(vector); } void doTranslateLocal(const Math::Vector2& vector) override final { translateLocal(vector); } + void doRotate(const Math::Complex& complex) override final { + rotate(complex); + } + void doRotateLocal(const Math::Complex& complex) override final { + rotateLocal(complex); + } + void doRotate(Math::Rad angle) override final { rotate(angle); } diff --git a/src/Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h b/src/Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h index 02450cbee..3d08e4e3e 100644 --- a/src/Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h +++ b/src/Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h @@ -292,6 +292,13 @@ template class BasicTranslationRotationScalingTransformation3D: public void doTranslate(const Math::Vector3& vector) override final { translate(vector); } void doTranslateLocal(const Math::Vector3& vector) override final { translateLocal(vector); } + void doRotate(const Math::Quaternion& quaternion) override final { + rotate(quaternion); + } + void doRotateLocal(const Math::Quaternion& quaternion) override final { + rotateLocal(quaternion); + } + void doRotate(Math::Rad angle, const Math::Vector3& normalizedAxis) override final { rotate(angle, normalizedAxis); } diff --git a/src/Magnum/SceneGraph/instantiation.cpp b/src/Magnum/SceneGraph/instantiation.cpp index 4920bf4dc..fd8bdcffc 100644 --- a/src/Magnum/SceneGraph/instantiation.cpp +++ b/src/Magnum/SceneGraph/instantiation.cpp @@ -30,11 +30,11 @@ #include "Magnum/SceneGraph/DualComplexTransformation.h" #include "Magnum/SceneGraph/DualQuaternionTransformation.h" #include "Magnum/SceneGraph/FeatureGroup.hpp" -#include "Magnum/SceneGraph/MatrixTransformation2D.h" -#include "Magnum/SceneGraph/MatrixTransformation3D.h" +#include "Magnum/SceneGraph/MatrixTransformation2D.hpp" +#include "Magnum/SceneGraph/MatrixTransformation3D.hpp" #include "Magnum/SceneGraph/Object.hpp" -#include "Magnum/SceneGraph/RigidMatrixTransformation2D.h" -#include "Magnum/SceneGraph/RigidMatrixTransformation3D.h" +#include "Magnum/SceneGraph/RigidMatrixTransformation2D.hpp" +#include "Magnum/SceneGraph/RigidMatrixTransformation3D.hpp" #include "Magnum/SceneGraph/TranslationTransformation.h" #include "Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h" #include "Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h" @@ -72,6 +72,13 @@ template class MAGNUM_SCENEGRAPH_EXPORT_HPP Camera<3, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<2, Float>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Drawable<3, Float>; +/* These have rotation(const Complex&) and rotation(const Quaternion&) defined + in a hpp to avoid dragging in Complex / Quaternion for every user */ +template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicMatrixTransformation2D; +template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicMatrixTransformation3D; +template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicRigidMatrixTransformation2D; +template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicRigidMatrixTransformation3D; + template class MAGNUM_SCENEGRAPH_EXPORT_HPP Object>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Object>; template class MAGNUM_SCENEGRAPH_EXPORT_HPP Object>;