Browse Source

SceneGraph: support rotating directly via Complex/Quaternion.

A decade late, but finally.
pull/420/head
Vladimír Vondruš 6 years ago
parent
commit
c25b19d210
  1. 11
      doc/changelog.dox
  2. 45
      src/Magnum/SceneGraph/AbstractTranslationRotation2D.h
  3. 51
      src/Magnum/SceneGraph/AbstractTranslationRotation3D.h
  4. 8
      src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h
  5. 8
      src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h
  6. 4
      src/Magnum/SceneGraph/CMakeLists.txt
  7. 36
      src/Magnum/SceneGraph/DualComplexTransformation.h
  8. 40
      src/Magnum/SceneGraph/DualQuaternionTransformation.h
  9. 29
      src/Magnum/SceneGraph/MatrixTransformation2D.h
  10. 51
      src/Magnum/SceneGraph/MatrixTransformation2D.hpp
  11. 37
      src/Magnum/SceneGraph/MatrixTransformation3D.h
  12. 51
      src/Magnum/SceneGraph/MatrixTransformation3D.hpp
  13. 16
      src/Magnum/SceneGraph/Object.h
  14. 29
      src/Magnum/SceneGraph/RigidMatrixTransformation2D.h
  15. 51
      src/Magnum/SceneGraph/RigidMatrixTransformation2D.hpp
  16. 38
      src/Magnum/SceneGraph/RigidMatrixTransformation3D.h
  17. 51
      src/Magnum/SceneGraph/RigidMatrixTransformation3D.hpp
  18. 12
      src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp
  19. 24
      src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp
  20. 13
      src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp
  21. 25
      src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp
  22. 13
      src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp
  23. 25
      src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp
  24. 4
      src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp
  25. 7
      src/Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h
  26. 7
      src/Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h
  27. 15
      src/Magnum/SceneGraph/instantiation.cpp

11
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<T>&) "rotate()"
and @ref SceneGraph::AbstractBasicTranslationRotation2D::rotateLocal(const Math::Complex<T>&) "rotateLocal()"
overloads taking a @ref Math::Complex
- All 3D transformation implementations that support rotation now have a
@ref SceneGraph::AbstractBasicTranslationRotation3D::rotate(const Math::Quaternion<T>&) "rotate()"
and @ref SceneGraph::AbstractBasicTranslationRotation3D::rotateLocal(const Math::Quaternion<T>&) "rotateLocal()"
overloads taking a @ref Math::Quaternion
@subsubsection changelog-latest-new-vk Vk library
- Updated Vulkan headers for version 1.2

45
src/Magnum/SceneGraph/AbstractTranslationRotation2D.h

@ -46,12 +46,39 @@ template<class T> 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<T>),
* @ref rotateLocal(const Math::Complex<T>&)
*/
AbstractBasicTranslationRotation2D<T>& rotate(const Math::Complex<T>& 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<T>& rotateLocal(const Math::Complex<T>& 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<T>&), @ref rotateLocal()
*/
AbstractBasicTranslationRotation2D<T>& rotate(Math::Rad<T> angle) {
doRotate(angle);
@ -89,10 +116,22 @@ template<class T> class AbstractBasicTranslationRotation2D: public AbstractBasic
~AbstractBasicTranslationRotation2D() = default;
private:
/** @brief Polymorphic implementation for @ref rotate() */
/**
* @brief Polymorphic implementation for @ref rotate(const Math::Complex<T>&)
* @m_since_latest
*/
virtual void doRotate(const Math::Complex<T>&) = 0;
/**
* @brief Polymorphic implementation for @ref rotateLocal(const Math::Complex<T>&)
* @m_since_latest
*/
virtual void doRotateLocal(const Math::Complex<T>&) = 0;
/** @brief Polymorphic implementation for @ref rotate(Math::Rad<T>) */
virtual void doRotate(Math::Rad<T> angle) = 0;
/** @brief Polymorphic implementation for @ref rotateLocal() */
/** @brief Polymorphic implementation for @ref rotateLocal(Math::Rad<T>) */
virtual void doRotateLocal(Math::Rad<T> angle) = 0;
};

51
src/Magnum/SceneGraph/AbstractTranslationRotation3D.h

@ -47,15 +47,44 @@ template<class T> 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<T>, const Math::Vector3<T>&),
* @ref rotateLocal(const Math::Quaternion<T>&), @ref rotateX(),
* @ref rotateY(), @ref rotateZ()
*/
AbstractBasicTranslationRotation3D<T>& rotate(const Math::Quaternion<T>& 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<T>& rotateLocal(const Math::Quaternion<T>& 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<T>&), @ref rotateLocal(),
* @ref rotateX(), @ref rotateY(), @ref rotateZ(),
* @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(),
* @ref Math::Vector3::zAxis()
*/
AbstractBasicTranslationRotation3D<T>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) {
doRotate(angle, normalizedAxis);
@ -177,10 +206,22 @@ template<class T> class AbstractBasicTranslationRotation3D: public AbstractBasic
~AbstractBasicTranslationRotation3D() = default;
private:
/** @brief Polymorphic implementation for @ref rotate() */
/**
* @brief Polymorphic implementation for @ref rotate(const Math::Quaternion<T>&)
* @m_since_latest
*/
virtual void doRotate(const Math::Quaternion<T>&) = 0;
/**
* @brief Polymorphic implementation for @ref rotateLocal(const Math::Quaternion<T>&)
* @m_since_latest
*/
virtual void doRotateLocal(const Math::Quaternion<T>&) = 0;
/** @brief Polymorphic implementation for @ref rotate(Math::Rad<T>, const Math::Vector3<T>&) */
virtual void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) = 0;
/** @brief Polymorphic implementation for @ref rotateLocal() */
/** @brief Polymorphic implementation for @ref rotateLocal(Math::Rad<T>, const Math::Vector3<T>&) */
virtual void doRotateLocal(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) = 0;
/**

8
src/Magnum/SceneGraph/AbstractTranslationRotationScaling2D.h

@ -83,6 +83,14 @@ template<class T> class AbstractBasicTranslationRotationScaling2D: public Abstra
AbstractBasicTranslationRotation2D<T>::translateLocal(vector);
return *this;
}
AbstractBasicTranslationRotationScaling2D<T>& rotate(const Math::Complex<T>& complex) {
AbstractBasicTranslationRotation2D<T>::rotate(complex);
return *this;
}
AbstractBasicTranslationRotationScaling2D<T>& rotateLocal(const Math::Complex<T>& complex) {
AbstractBasicTranslationRotation2D<T>::rotateLocal(complex);
return *this;
}
AbstractBasicTranslationRotationScaling2D<T>& rotate(Math::Rad<T> angle) {
AbstractBasicTranslationRotation2D<T>::rotate(angle);
return *this;

8
src/Magnum/SceneGraph/AbstractTranslationRotationScaling3D.h

@ -83,6 +83,14 @@ template<class T> class AbstractBasicTranslationRotationScaling3D: public Abstra
AbstractBasicTranslationRotation3D<T>::translateLocal(vector);
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>& rotate(const Math::Quaternion<T>& quaternion) {
AbstractBasicTranslationRotation3D<T>::rotate(quaternion);
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>& rotateLocal(const Math::Quaternion<T>& quaternion) {
AbstractBasicTranslationRotation3D<T>::rotateLocal(quaternion);
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) {
AbstractBasicTranslationRotation3D<T>::rotate(angle, normalizedAxis);
return *this;

4
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

36
src/Magnum/SceneGraph/DualComplexTransformation.h

@ -132,13 +132,40 @@ template<class T> class BasicDualComplexTransformation: public AbstractBasicTran
return transformLocalInternal(Math::DualComplex<T>::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<T>),
* @ref rotateLocal(const Math::Complex<T>&)
*/
Object<BasicDualComplexTransformation<T>>& rotate(const Math::Complex<T>& 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<BasicDualComplexTransformation<T>>& rotateLocal(const Math::Complex<T>& 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<T>&), @ref rotateLocal(),
* @ref normalizeRotation()
*/
Object<BasicDualComplexTransformation<T>>& rotate(Math::Rad<T> angle) {
return transformInternal(Math::DualComplex<T>::rotation(angle));
@ -168,6 +195,13 @@ template<class T> class BasicDualComplexTransformation: public AbstractBasicTran
translateLocal(vector);
}
void doRotate(const Math::Complex<T>& complex) override final {
rotate(complex);
}
void doRotateLocal(const Math::Complex<T>& complex) override final {
rotateLocal(complex);
}
void doRotate(Math::Rad<T> angle) override final { rotate(angle); }
void doRotateLocal(Math::Rad<T> angle) override final { rotateLocal(angle); }

40
src/Magnum/SceneGraph/DualQuaternionTransformation.h

@ -131,6 +131,33 @@ template<class T> class BasicDualQuaternionTransformation: public AbstractBasicT
return transformLocalInternal(Math::DualQuaternion<T>::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<T>, const Math::Vector3<T>&),
* @ref rotateLocal(const Math::Quaternion<T>&), @ref rotateX(),
* @ref rotateY(), @ref rotateZ()
*/
Object<BasicDualQuaternionTransformation<T>>& rotate(const Math::Quaternion<T>& 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<BasicDualQuaternionTransformation<T>>& rotateLocal(const Math::Quaternion<T>& quaternion) {
return transformLocalInternal(quaternion);
}
/**
* @brief Rotate the object
* @param angle Angle (counterclockwise)
@ -138,9 +165,9 @@ template<class T> 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<T>&), @ref rotateLocal(),
* @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(),
* @ref Math::Vector3::zAxis(), @ref normalizeRotation()
*/
Object<BasicDualQuaternionTransformation<T>>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) {
return transformInternal(Math::DualQuaternion<T>::rotation(angle, normalizedAxis));
@ -192,6 +219,13 @@ template<class T> class BasicDualQuaternionTransformation: public AbstractBasicT
translateLocal(vector);
}
void doRotate(const Math::Quaternion<T>& quaternion) override final {
rotate(quaternion);
}
void doRotateLocal(const Math::Quaternion<T>& quaternion) override final {
rotateLocal(quaternion);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) override final {
rotate(angle, normalizedAxis);
}

29
src/Magnum/SceneGraph/MatrixTransformation2D.h

@ -114,6 +114,27 @@ template<class T> class BasicMatrixTransformation2D: public AbstractBasicTransla
return transformLocal(Math::Matrix3<T>::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<T>),
* @ref rotateLocal(const Math::Complex<T>&)
*/
Object<BasicMatrixTransformation2D<T>>& rotate(const Math::Complex<T>& 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<BasicMatrixTransformation2D<T>>& rotateLocal(const Math::Complex<T>& complex);
/**
* @brief Rotate the object
* @param angle Angle (counterclockwise)
@ -195,6 +216,13 @@ template<class T> class BasicMatrixTransformation2D: public AbstractBasicTransla
void doTranslate(const Math::Vector2<T>& vector) override final { translate(vector); }
void doTranslateLocal(const Math::Vector2<T>& vector) override final { translateLocal(vector); }
void doRotate(const Math::Complex<T>& complex) override final {
rotate(complex);
}
void doRotateLocal(const Math::Complex<T>& complex) override final {
rotateLocal(complex);
}
void doRotate(Math::Rad<T> angle) override final { rotate(angle); }
void doRotateLocal(Math::Rad<T> angle) override final { rotateLocal(angle); }
@ -234,6 +262,7 @@ template<class T> struct Transformation<BasicMatrixTransformation2D<T>> {
}
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT BasicMatrixTransformation2D<Float>;
extern template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicMatrixTransformation2D<Float>>;
#endif

51
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š <mosra@centrum.cz>
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<class T> Object<BasicMatrixTransformation2D<T>>& BasicMatrixTransformation2D<T>::rotate(const Math::Complex<T>& complex) {
return transform(Matrix3::from(complex.toMatrix(), {}));
}
template<class T> Object<BasicMatrixTransformation2D<T>>& BasicMatrixTransformation2D<T>::rotateLocal(const Math::Complex<T>& complex) {
return transformLocal(Matrix3::from(complex.toMatrix(), {}));
}
}}
#endif

37
src/Magnum/SceneGraph/MatrixTransformation3D.h

@ -114,6 +114,28 @@ template<class T> class BasicMatrixTransformation3D: public AbstractBasicTransla
return transformLocal(Math::Matrix4<T>::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<T>, const Math::Vector3<T>&),
* @ref rotateLocal(const Math::Quaternion<T>&), @ref rotateX(),
* @ref rotateY(), @ref rotateZ()
*/
Object<BasicMatrixTransformation3D<T>>& rotate(const Math::Quaternion<T>& 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<BasicMatrixTransformation3D<T>>& rotateLocal(const Math::Quaternion<T>& quaternion);
/**
* @brief Rotate the object
* @param angle Angle (counterclockwise)
@ -121,9 +143,10 @@ template<class T> 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<T>&), @ref rotateLocal(),
* @ref rotateX(), @ref rotateY(), @ref rotateZ(),
* @ref Math::Vector3::xAxis(), @ref Math::Vector3::yAxis(),
* @ref Math::Vector3::zAxis()
*/
Object<BasicMatrixTransformation3D<T>>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) {
return transform(Math::Matrix4<T>::rotation(angle, normalizedAxis));
@ -266,6 +289,13 @@ template<class T> class BasicMatrixTransformation3D: public AbstractBasicTransla
void doTranslate(const Math::Vector3<T>& vector) override final { translate(vector); }
void doTranslateLocal(const Math::Vector3<T>& vector) override final { translateLocal(vector); }
void doRotate(const Math::Quaternion<T>& quaternion) override final {
rotate(quaternion);
}
void doRotateLocal(const Math::Quaternion<T>& quaternion) override final {
rotateLocal(quaternion);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) override final {
rotate(angle, normalizedAxis);
}
@ -318,6 +348,7 @@ template<class T> struct Transformation<BasicMatrixTransformation3D<T>> {
}
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT BasicMatrixTransformation3D<Float>;
extern template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicMatrixTransformation3D<Float>>;
#endif

51
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š <mosra@centrum.cz>
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<class T> Object<BasicMatrixTransformation3D<T>>& BasicMatrixTransformation3D<T>::rotate(const Math::Quaternion<T>& quaternion) {
return transform(Matrix4::from(quaternion.toMatrix(), {}));
}
template<class T> Object<BasicMatrixTransformation3D<T>>& BasicMatrixTransformation3D<T>::rotateLocal(const Math::Quaternion<T>& quaternion) {
return transformLocal(Matrix4::from(quaternion.toMatrix(), {}));
}
}}
#endif

16
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<DualComplexTransformation>"
- @ref DualQuaternionTransformation "Object<DualQuaternionTransformation>"
- @ref MatrixTransformation2D "Object<MatrixTransformation2D>"
- @ref MatrixTransformation3D "Object<MatrixTransformation3D>"
- @ref MatrixTransformation2D "Object<MatrixTransformation2D>" (custom
specializations need also @ref MatrixTransformation2D.hpp)
- @ref MatrixTransformation3D "Object<MatrixTransformation3D>" (custom
specializations need also @ref MatrixTransformation3D.hpp)
- @ref RigidMatrixTransformation2D "Object<RigidMatrixTransformation2D>"
(custom specializations need also @ref RigidMatrixTransformation2D.hpp)
- @ref RigidMatrixTransformation3D "Object<RigidMatrixTransformation3D>"
(custom specializations need also @ref RigidMatrixTransformation3D.hpp)
- @ref TranslationTransformation2D "Object<TranslationTransformation2D>"
- @ref TranslationTransformation3D "Object<TranslationTransformation3D>"

29
src/Magnum/SceneGraph/RigidMatrixTransformation2D.h

@ -137,6 +137,27 @@ template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTr
return transformLocalInternal(Math::Matrix3<T>::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<T>),
* @ref rotateLocal(const Math::Complex<T>&)
*/
Object<BasicRigidMatrixTransformation2D<T>>& rotate(const Math::Complex<T>& 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<BasicRigidMatrixTransformation2D<T>>& rotateLocal(const Math::Complex<T>& complex);
/**
* @brief Rotate the object
* @param angle Angle (counterclockwise)
@ -195,6 +216,13 @@ template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTr
void doTranslate(const Math::Vector2<T>& vector) override final { translate(vector); }
void doTranslateLocal(const Math::Vector2<T>& vector) override final { translateLocal(vector); }
void doRotate(const Math::Complex<T>& complex) override final {
rotate(complex);
}
void doRotateLocal(const Math::Complex<T>& complex) override final {
rotateLocal(complex);
}
void doRotate(Math::Rad<T> angle) override final { rotate(angle); }
void doRotateLocal(Math::Rad<T> angle) override final { rotateLocal(angle); }
@ -254,6 +282,7 @@ template<class T> struct Transformation<BasicRigidMatrixTransformation2D<T>> {
}
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT BasicRigidMatrixTransformation2D<Float>;
extern template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicRigidMatrixTransformation2D<Float>>;
#endif

51
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š <mosra@centrum.cz>
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<class T> Object<BasicRigidMatrixTransformation2D<T>>& BasicRigidMatrixTransformation2D<T>::rotate(const Math::Complex<T>& complex) {
return transform(Matrix3::from(complex.toMatrix(), {}));
}
template<class T> Object<BasicRigidMatrixTransformation2D<T>>& BasicRigidMatrixTransformation2D<T>::rotateLocal(const Math::Complex<T>& complex) {
return transformLocal(Matrix3::from(complex.toMatrix(), {}));
}
}}
#endif

38
src/Magnum/SceneGraph/RigidMatrixTransformation3D.h

@ -136,6 +136,28 @@ template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTr
return transformLocalInternal(Math::Matrix4<T>::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<T>, const Math::Vector3<T>&),
* @ref rotateLocal(const Math::Quaternion<T>&), @ref rotateX(),
* @ref rotateY(), @ref rotateZ()
*/
Object<BasicRigidMatrixTransformation3D<T>>& rotate(const Math::Quaternion<T>& 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<BasicRigidMatrixTransformation3D<T>>& rotateLocal(const Math::Quaternion<T>& quaternion);
/**
* @brief Rotate the object
* @param angle Angle (counterclockwise)
@ -143,10 +165,10 @@ template<class T> 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<T>&), @ref rotateLocal(),
* @ref rotateX(), @ref rotateY(), @ref rotateZ(),
* @ref normalizeRotation(), @ref Math::Vector3::xAxis(),
* @ref Math::Vector3::yAxis(), @ref Math::Vector3::zAxis()
*/
Object<BasicRigidMatrixTransformation3D<T>>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) {
return transformInternal(Math::Matrix4<T>::rotation(angle, normalizedAxis));
@ -266,6 +288,13 @@ template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTr
void doTranslate(const Math::Vector3<T>& vector) override final { translate(vector); }
void doTranslateLocal(const Math::Vector3<T>& vector) override final { translateLocal(vector); }
void doRotate(const Math::Quaternion<T>& quaternion) override final {
rotate(quaternion);
}
void doRotateLocal(const Math::Quaternion<T>& quaternion) override final {
rotateLocal(quaternion);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) override final {
rotate(angle, normalizedAxis);
}
@ -338,6 +367,7 @@ template<class T> struct Transformation<BasicRigidMatrixTransformation3D<T>> {
}
#if defined(CORRADE_TARGET_WINDOWS) && !defined(__MINGW32__)
extern template class MAGNUM_SCENEGRAPH_EXPORT BasicRigidMatrixTransformation3D<Float>;
extern template class MAGNUM_SCENEGRAPH_EXPORT Object<BasicRigidMatrixTransformation3D<Float>>;
#endif

51
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š <mosra@centrum.cz>
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<class T> Object<BasicRigidMatrixTransformation3D<T>>& BasicRigidMatrixTransformation3D<T>::rotate(const Math::Quaternion<T>& quaternion) {
return transform(Matrix4::from(quaternion.toMatrix(), {}));
}
template<class T> Object<BasicRigidMatrixTransformation3D<T>>& BasicRigidMatrixTransformation3D<T>::rotateLocal(const Math::Quaternion<T>& quaternion) {
return transformLocal(Matrix4::from(quaternion.toMatrix(), {}));
}
}}
#endif

12
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)));
}
}

24
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))*

13
src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp

@ -25,6 +25,7 @@
#include <Corrade/TestSuite/Tester.h>
#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<MatrixTransformation2D>::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)));
}
}

25
src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp

@ -25,6 +25,7 @@
#include <Corrade/TestSuite/Tester.h>
#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<MatrixTransformation3D>::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))*

13
src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h>
#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)));
}
}

25
src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h>
#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))*

4
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));

7
src/Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h

@ -212,6 +212,13 @@ template<class T> class BasicTranslationRotationScalingTransformation2D: public
void doTranslate(const Math::Vector2<T>& vector) override final { translate(vector); }
void doTranslateLocal(const Math::Vector2<T>& vector) override final { translateLocal(vector); }
void doRotate(const Math::Complex<T>& complex) override final {
rotate(complex);
}
void doRotateLocal(const Math::Complex<T>& complex) override final {
rotateLocal(complex);
}
void doRotate(Math::Rad<T> angle) override final {
rotate(angle);
}

7
src/Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h

@ -292,6 +292,13 @@ template<class T> class BasicTranslationRotationScalingTransformation3D: public
void doTranslate(const Math::Vector3<T>& vector) override final { translate(vector); }
void doTranslateLocal(const Math::Vector3<T>& vector) override final { translateLocal(vector); }
void doRotate(const Math::Quaternion<T>& quaternion) override final {
rotate(quaternion);
}
void doRotateLocal(const Math::Quaternion<T>& quaternion) override final {
rotateLocal(quaternion);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis) override final {
rotate(angle, normalizedAxis);
}

15
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<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicMatrixTransformation3D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicRigidMatrixTransformation2D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP BasicRigidMatrixTransformation3D<Float>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Object<BasicDualComplexTransformation<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Object<BasicDualQuaternionTransformation<Float>>;
template class MAGNUM_SCENEGRAPH_EXPORT_HPP Object<BasicMatrixTransformation2D<Float>>;

Loading…
Cancel
Save