Browse Source

SceneGraph: don't use virtual calls when setting transformations.

Until now, all calls to e.g. `Object::translate()` were virtual, which
is _very_ bad for performance. The virtual call is only needed when
setting the transformation via some interface, e.g.
`AbstractTranslationRotation3D`, as the caller doesn't know which
transformation implementation is used.

Now all public-facing transformation methods are inline non-virtual
functions, which are in most cases calling directly the transformation
implementation. In `Abstract*` transformation interfaces these functions
call private virtual `do*()` implementations, which are (re)implemented
in subclasses, but aren't used anywhere except when transforming
directly through the `Abstract*` interfaces. This should have good
impact on performance when doing many transformations in every frame
(although I can't verify it anywhere, as I don't have any significantly
large animated demo). Except of course when doing it through the virtual
interfaces.

As the public-facing transformation methods are now non-virtual, there
are now no "covariant return" issues and they can now return proper
`Object<*Transformation*>` type instead of just `*Transformation*`,
which makes full non-WTF method chaining possible:

    Object2D* obj2;
    obj2->translate({0.5f, -1.0f})           // Transformation method
        ->setParentKeepTransformation(obj1); // Object method

Or even this:

    Object2D* obj = (new Object2D)->rotate(-15.0_degf);
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
3fc7ccafe5
  1. 13
      src/SceneGraph/AbstractTransformation.h
  2. 26
      src/SceneGraph/AbstractTranslationRotation2D.h
  3. 68
      src/SceneGraph/AbstractTranslationRotation3D.h
  4. 28
      src/SceneGraph/AbstractTranslationRotationScaling2D.h
  5. 43
      src/SceneGraph/AbstractTranslationRotationScaling3D.h
  6. 45
      src/SceneGraph/DualComplexTransformation.h
  7. 56
      src/SceneGraph/DualQuaternionTransformation.h
  8. 47
      src/SceneGraph/MatrixTransformation2D.h
  9. 67
      src/SceneGraph/MatrixTransformation3D.h
  10. 49
      src/SceneGraph/RigidMatrixTransformation2D.h
  11. 69
      src/SceneGraph/RigidMatrixTransformation3D.h

13
src/SceneGraph/AbstractTransformation.h

@ -142,7 +142,18 @@ class MAGNUM_SCENEGRAPH_EXPORT AbstractTransformation {
* @brief Reset object transformation
* @return Pointer to self (for method chaining)
*/
virtual AbstractTransformation<dimensions, T>* resetTransformation() = 0;
AbstractTransformation<dimensions, T>* resetTransformation() {
doResetTransformation();
return this;
}
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Polymorphic implementation for resetTransformation() */
virtual void doResetTransformation() = 0;
};
/** @brief Transformation type */

26
src/SceneGraph/AbstractTranslationRotation2D.h

@ -54,7 +54,10 @@ class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
*
* @see Vector2::xAxis(), Vector2::yAxis()
*/
virtual AbstractTranslationRotation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
doTranslate(vector, type);
return this;
}
/**
* @brief Rotate object
@ -62,12 +65,29 @@ class AbstractTranslationRotation2D: public AbstractTransformation<2, T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*/
virtual AbstractTranslationRotation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotate(angle, type);
return this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotation2D<T>* resetTransformation() override = 0;
AbstractTranslationRotation2D<T>* resetTransformation() {
AbstractTransformation<2, T>::resetTransformation();
return this;
}
#endif
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Polymorphic implementation for translate() */
virtual void doTranslate(const Math::Vector2<T>& vector, TransformationType type) = 0;
/** @brief Polymorphic implementation for rotate() */
virtual void doRotate(Math::Rad<T> angle, TransformationType type) = 0;
};
}}

68
src/SceneGraph/AbstractTranslationRotation3D.h

@ -55,7 +55,10 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
*
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()
*/
virtual AbstractTranslationRotation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
doTranslate(vector, type);
return this;
}
/**
* @brief Rotate object
@ -67,7 +70,10 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis()
*/
virtual AbstractTranslationRotation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
doRotate(angle, normalizedAxis, type);
return this;
}
/**
* @brief Rotate object around X axis
@ -78,8 +84,9 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* In some implementations faster than calling
* `rotate(angle, Vector3::xAxis())`.
*/
virtual AbstractTranslationRotation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::xAxis(), type);
AbstractTranslationRotation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateX(angle, type);
return this;
}
/**
@ -91,8 +98,9 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* In some implementations faster than calling
* `rotate(angle, Vector3::yAxis())`.
*/
virtual AbstractTranslationRotation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::yAxis(), type);
AbstractTranslationRotation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateX(angle, type);
return this;
}
/**
@ -104,14 +112,56 @@ class AbstractTranslationRotation3D: public AbstractTransformation<3, T> {
* In some implementations faster than calling
* `rotate(angle, Vector3::zAxis())`.
*/
virtual AbstractTranslationRotation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::zAxis(), type);
AbstractTranslationRotation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateZ(angle, type);
return this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotation3D<T>* resetTransformation() override = 0;
AbstractTranslationRotation3D<T>* resetTransformation() {
AbstractTransformation<2, T>::resetTransformation();
return this;
}
#endif
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Polymorphic implementation for translate() */
virtual void doTranslate(const Math::Vector3<T>& vector, TransformationType type) = 0;
/** @brief Polymorphic implementation for rotate() */
virtual void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type) = 0;
/**
* @brief Polymorphic implementation for rotateX()
*
* Default implementation calls rotate() with Math::Vector3::xAxis().
*/
virtual void doRotateX(Math::Rad<T> angle, TransformationType type) {
rotate(angle, Math::Vector3<T>::xAxis(), type);
}
/**
* @brief Polymorphic implementation for rotateY()
*
* Default implementation calls rotate() with Math::Vector3::yAxis().
*/
virtual void doRotateY(Math::Rad<T> angle, TransformationType type) {
rotate(angle, Math::Vector3<T>::yAxis(), type);
}
/**
* @brief Polymorphic implementation for rotateZ()
*
* Default implementation calls rotate() with Math::Vector3::zAxis().
*/
virtual void doRotateZ(Math::Rad<T> angle, TransformationType type) {
rotate(angle, Math::Vector3<T>::zAxis(), type);
}
};
}}

28
src/SceneGraph/AbstractTranslationRotationScaling2D.h

@ -54,14 +54,34 @@ class AbstractTranslationRotationScaling2D: public AbstractTranslationRotation2D
*
* @see Vector2::xScale(), Vector2::yScale()
*/
virtual AbstractTranslationRotationScaling2D<T>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling2D<T>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
doScale(vector, type);
return this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotationScaling2D<T>* resetTransformation() override = 0;
AbstractTranslationRotationScaling2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling2D<T>* resetTransformation() {
AbstractTranslationRotation2D<T>::resetTransformation();
return this;
}
AbstractTranslationRotationScaling2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation2D<T>::translate(vector, type);
return this;
}
AbstractTranslationRotationScaling2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation2D<T>::rotate(angle, type);
return this;
}
#endif
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Polymorphic implementation for scale() */
virtual void doScale(const Math::Vector2<T>& vector, TransformationType type) = 0;
};
}}

43
src/SceneGraph/AbstractTranslationRotationScaling3D.h

@ -54,17 +54,46 @@ class AbstractTranslationRotationScaling3D: public AbstractTranslationRotation3D
*
* @see Vector3::xScale(), Vector3::yScale(), Vector3::zScale()
*/
virtual AbstractTranslationRotationScaling3D<T>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling3D<T>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
doScale(vector, type);
return this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractTranslationRotationScaling3D<T>* resetTransformation() override = 0;
AbstractTranslationRotationScaling3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) = 0;
AbstractTranslationRotationScaling3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override = 0;
AbstractTranslationRotationScaling3D<T>* resetTransformation() {
AbstractTranslationRotation3D<T>::resetTransformation();
return this;
}
AbstractTranslationRotationScaling3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::translate(vector, type);
return this;
}
AbstractTranslationRotationScaling3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotate(angle, normalizedAxis, type);
return this;
}
AbstractTranslationRotationScaling3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotateX(angle, type);
return this;
}
AbstractTranslationRotationScaling3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotateY(angle, type);
return this;
}
AbstractTranslationRotationScaling3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractTranslationRotation3D<T>::rotateZ(angle, type);
return this;
}
#endif
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @brief Polymorphic implementation for scale() */
virtual void doScale(const Math::Vector3<T>& vector, TransformationType type) = 0;
};
}}

45
src/SceneGraph/DualComplexTransformation.h

@ -81,9 +81,9 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* the object subsequently.
* @see DualComplex::normalized()
*/
DualComplexTransformation<T>* normalizeRotation() {
Object<DualComplexTransformation<T>>* normalizeRotation() {
setTransformationInternal(_transformation.normalized());
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
/**
@ -93,16 +93,18 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* Expects that the dual complex number is normalized.
* @see DualComplex::isNormalized()
*/
DualComplexTransformation<T>* setTransformation(const Math::DualComplex<T>& transformation) {
Object<DualComplexTransformation<T>>* setTransformation(const Math::DualComplex<T>& transformation) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualComplexTransformation::setTransformation(): the dual complex number is not normalized", this);
"SceneGraph::DualComplexTransformation::setTransformation(): the dual complex number is not normalized",
static_cast<Object<DualComplexTransformation<T>>*>(this));
setTransformationInternal(transformation);
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
DualComplexTransformation<T>* resetTransformation() override {
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<DualComplexTransformation<T>>* resetTransformation() {
setTransformationInternal({});
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
/**
@ -114,20 +116,21 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* Expects that the dual complex number is normalized.
* @see DualComplex::isNormalized()
*/
DualComplexTransformation<T>* transform(const Math::DualComplex<T>& transformation, TransformationType type = TransformationType::Global) {
Object<DualComplexTransformation<T>>* transform(const Math::DualComplex<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized", this);
"SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized",
static_cast<Object<DualComplexTransformation<T>>*>(this));
transformInternal(transformation, type);
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with DualComplex::translation().
*/
DualComplexTransformation<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) override {
Object<DualComplexTransformation<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualComplex<T>::translation(vector), type);
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
/**
@ -139,9 +142,9 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* Same as calling transform() with DualComplex::rotation().
* @see normalizeRotation()
*/
DualComplexTransformation<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<DualComplexTransformation<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualComplex<T>::rotation(angle), type);
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
/**
@ -150,9 +153,9 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
* if you want to move it above all.
* @return Pointer to self (for method chaining)
*/
DualComplexTransformation<T>* move(Object<DualComplexTransformation<T>>* under) {
Object<DualComplexTransformation<T>>* move(Object<DualComplexTransformation<T>>* under) {
static_cast<Object<DualComplexTransformation>*>(this)->Containers::template LinkedList<Object<DualComplexTransformation<T>>>::move(this, under);
return this;
return static_cast<Object<DualComplexTransformation<T>>*>(this);
}
protected:
@ -160,6 +163,16 @@ class DualComplexTransformation: public AbstractTranslationRotation2D<T> {
explicit DualComplexTransformation() = default;
private:
void doResetTransformation() override final { resetTransformation(); }
void doTranslate(const Math::Vector2<T>& vector, TransformationType type) override final {
translate(vector, type);
}
void doRotate(Math::Rad<T> angle, TransformationType type) override final {
doRotate(angle, type);
}
/* No assertions fired, for internal use */
void setTransformationInternal(const Math::DualComplex<T>& transformation) {
/* Setting transformation is forbidden for the scene */

56
src/SceneGraph/DualQuaternionTransformation.h

@ -83,9 +83,9 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* the object subsequently.
* @see DualQuaternion::normalized()
*/
DualQuaternionTransformation<T>* normalizeRotation() {
Object<DualQuaternionTransformation<T>>* normalizeRotation() {
setTransformation(_transformation.normalized());
return this;
return static_cast<Object<DualQuaternionTransformation<T>>*>(this);
}
/**
@ -95,16 +95,18 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* Expects that the dual quaternion is normalized.
* @see DualQuaternion::isNormalized()
*/
DualQuaternionTransformation<T>* setTransformation(const Math::DualQuaternion<T>& transformation) {
Object<DualQuaternionTransformation<T>>* setTransformation(const Math::DualQuaternion<T>& transformation) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualQuaternionTransformation::setTransformation(): the dual quaternion is not normalized", this);
"SceneGraph::DualQuaternionTransformation::setTransformation(): the dual quaternion is not normalized",
static_cast<Object<DualQuaternionTransformation<T>>*>(this));
setTransformationInternal(transformation);
return this;
return static_cast<Object<DualQuaternionTransformation<T>>*>(this);
}
DualQuaternionTransformation<T>* resetTransformation() override {
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<DualQuaternionTransformation<T>>* resetTransformation() {
setTransformation({});
return this;
return static_cast<Object<DualQuaternionTransformation<T>>*>(this);
}
/**
@ -116,20 +118,21 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* Expects that the dual quaternion is normalized.
* @see DualQuaternion::isNormalized()
*/
DualQuaternionTransformation<T>* transform(const Math::DualQuaternion<T>& transformation, TransformationType type = TransformationType::Global) {
Object<DualQuaternionTransformation<T>>* transform(const Math::DualQuaternion<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized", this);
"SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized",
static_cast<Object<DualQuaternionTransformation<T>>*>(this));
transformInternal(transformation, type);
return this;
return static_cast<Object<DualQuaternionTransformation<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with DualQuaternion::translation().
*/
DualQuaternionTransformation<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) override {
Object<DualQuaternionTransformation<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualQuaternion<T>::translation(vector), type);
return this;
return static_cast<Object<DualQuaternionTransformation<T>>*>(this);
}
/**
@ -143,24 +146,21 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(),
* normalizeRotation()
*/
DualQuaternionTransformation<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) override {
Object<DualQuaternionTransformation<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualQuaternion<T>::rotation(angle, normalizedAxis), type);
return this;
return static_cast<Object<DualQuaternionTransformation<T>>*>(this);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
DualQuaternionTransformation<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
AbstractTranslationRotation3D<T>::rotateX(angle, type);
return this;
Object<DualQuaternionTransformation<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::xAxis(), type);
}
DualQuaternionTransformation<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
AbstractTranslationRotation3D<T>::rotateY(angle, type);
return this;
Object<DualQuaternionTransformation<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::yAxis(), type);
}
DualQuaternionTransformation<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
AbstractTranslationRotation3D<T>::rotateZ(angle, type);
return this;
Object<DualQuaternionTransformation<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::zAxis(), type);
}
#endif
@ -169,6 +169,16 @@ class DualQuaternionTransformation: public AbstractTranslationRotation3D<T> {
explicit DualQuaternionTransformation() = default;
private:
void doResetTransformation() override final { resetTransformation(); }
void doTranslate(const Math::Vector3<T>& vector, TransformationType type) override final {
translate(vector, type);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type) override final {
rotate(angle, normalizedAxis, type);
}
/* No assertions fired, for internal use */
void setTransformationInternal(const Math::DualQuaternion<T>& transformation) {
/* Setting transformation is forbidden for the scene */

47
src/SceneGraph/MatrixTransformation2D.h

@ -76,7 +76,7 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* @brief Set transformation
* @return Pointer to self (for method chaining)
*/
MatrixTransformation2D<T>* setTransformation(const Math::Matrix3<T>& transformation) {
Object<MatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */
@ -85,7 +85,7 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
static_cast<Object<MatrixTransformation2D<T>>*>(this)->setDirty();
}
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
/**
@ -94,42 +94,43 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*/
MatrixTransformation2D<T>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
Object<MatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation);
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
MatrixTransformation2D<T>* resetTransformation() override {
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<MatrixTransformation2D<T>>* resetTransformation() {
setTransformation({});
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation().
*/
MatrixTransformation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::translation(vector), type);
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::rotate()
* Same as calling transform() with Matrix3::rotation().
*/
MatrixTransformation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::rotation(angle), type);
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::scale()
* Same as calling transform() with Matrix3::scaling().
*/
MatrixTransformation2D<T>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation2D<T>>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::scaling(vector), type);
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
/**
@ -141,9 +142,9 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
*
* Same as calling transform() with Matrix3::reflection().
*/
MatrixTransformation2D<T>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
Object<MatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::reflection(normal), type);
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
/**
@ -152,9 +153,9 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
* if you want to move it above all.
* @return Pointer to self (for method chaining)
*/
MatrixTransformation2D<T>* move(Object<MatrixTransformation2D<T>>* under) {
Object<MatrixTransformation2D<T>>* move(Object<MatrixTransformation2D<T>>* under) {
static_cast<Object<MatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<MatrixTransformation2D<T>>>::move(this, under);
return this;
return static_cast<Object<MatrixTransformation2D<T>>*>(this);
}
protected:
@ -162,6 +163,20 @@ class MatrixTransformation2D: public AbstractTranslationRotationScaling2D<T> {
explicit MatrixTransformation2D() = default;
private:
void doResetTransformation() override final { resetTransformation(); }
void doTranslate(const Math::Vector2<T>& vector, TransformationType type) override final {
translate(vector, type);
}
void doRotate(Math::Rad<T> angle, TransformationType type) override final {
doRotate(angle, type);
}
void doScale(const Math::Vector2<T>& vector, TransformationType type) override final {
scale(vector, type);
}
Math::Matrix3<T> _transformation;
};

67
src/SceneGraph/MatrixTransformation3D.h

@ -76,7 +76,7 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* @brief Set transformation
* @return Pointer to self (for method chaining)
*/
MatrixTransformation3D<T>* setTransformation(const Math::Matrix4<T>& transformation) {
Object<MatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */
@ -85,12 +85,13 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
static_cast<Object<MatrixTransformation3D<T>>*>(this)->setDirty();
}
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
MatrixTransformation3D<T>* resetTransformation() override {
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<MatrixTransformation3D<T>>* resetTransformation() {
setTransformation({});
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
@ -99,28 +100,28 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*/
MatrixTransformation3D<T>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
Object<MatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation().
*/
MatrixTransformation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::translation(vector), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::rotate()
* Same as calling transform() with Matrix4::rotation().
*/
MatrixTransformation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
@ -131,9 +132,9 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
*
* Same as calling transform() with Matrix4::rotationX().
*/
MatrixTransformation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationX(angle), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
@ -144,9 +145,9 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
*
* Same as calling transform() with Matrix4::rotationY().
*/
MatrixTransformation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationY(angle), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
@ -157,18 +158,18 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
*
* Same as calling transform() with Matrix4::rotationZ().
*/
MatrixTransformation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationZ(angle), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::scale()
* Same as calling transform() with Matrix4::scaling().
*/
MatrixTransformation3D<T>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) override {
Object<MatrixTransformation3D<T>>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::scaling(vector), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
/**
@ -180,9 +181,9 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
*
* Same as calling transform() with Matrix4::reflection().
*/
MatrixTransformation3D<T>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
Object<MatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::reflection(normal), type);
return this;
return static_cast<Object<MatrixTransformation3D<T>>*>(this);
}
protected:
@ -190,6 +191,32 @@ class MatrixTransformation3D: public AbstractTranslationRotationScaling3D<T> {
explicit MatrixTransformation3D() = default;
private:
void doResetTransformation() override final { resetTransformation(); }
void doTranslate(const Math::Vector3<T>& vector, TransformationType type) override final {
translate(vector, type);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type) override final {
rotate(angle, normalizedAxis, type);
}
void doRotateX(Math::Rad<T> angle, TransformationType type) override final {
rotateX(angle, type);
}
void doRotateY(Math::Rad<T> angle, TransformationType type) override final {
rotateY(angle, type);
}
void doRotateZ(Math::Rad<T> angle, TransformationType type) override final {
rotateZ(angle, type);
}
void doScale(const Math::Vector3<T>& vector, TransformationType type) override final {
scale(vector, type);
}
Math::Matrix4<T> _transformation;
};

49
src/SceneGraph/RigidMatrixTransformation2D.h

@ -84,11 +84,11 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Normalizes the rotation part using Math::Algorithms::gramSchmidt()
* to prevent rounding errors when rotating the object subsequently.
*/
RigidMatrixTransformation2D<T>* normalizeRotation() {
Object<RigidMatrixTransformation2D<T>>* normalizeRotation() {
setTransformationInternal(Math::Matrix3<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation()));
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
/**
@ -98,16 +98,18 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation()
*/
RigidMatrixTransformation2D<T>* setTransformation(const Math::Matrix3<T>& transformation) {
Object<RigidMatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation", this);
"SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation2D<T>>*>(this));
setTransformationInternal(transformation);
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
RigidMatrixTransformation2D<T>* resetTransformation() override {
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<RigidMatrixTransformation2D<T>>* resetTransformation() {
setTransformationInternal({});
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
/**
@ -119,20 +121,21 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation()
*/
RigidMatrixTransformation2D<T>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
Object<RigidMatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation", this);
"SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation2D<T>>*>(this));
transformInternal(transformation, type);
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation().
*/
RigidMatrixTransformation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::translation(vector), type);
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
/**
@ -144,9 +147,9 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* Same as calling transform() with Matrix3::rotation().
* @see normalizeRotation()
*/
RigidMatrixTransformation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::rotation(angle), type);
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
/**
@ -158,9 +161,9 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
*
* Same as calling transform() with Matrix3::reflection().
*/
RigidMatrixTransformation2D<T>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
Object<RigidMatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::reflection(normal), type);
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
/**
@ -169,9 +172,9 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* if you want to move it above all.
* @return Pointer to self (for method chaining)
*/
RigidMatrixTransformation2D<T>* move(Object<RigidMatrixTransformation2D<T>>* under) {
Object<RigidMatrixTransformation2D<T>>* move(Object<RigidMatrixTransformation2D<T>>* under) {
static_cast<Object<RigidMatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<RigidMatrixTransformation2D<T>>>::move(this, under);
return this;
return static_cast<Object<RigidMatrixTransformation2D<T>>*>(this);
}
protected:
@ -179,6 +182,16 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
explicit RigidMatrixTransformation2D() = default;
private:
void doResetTransformation() override final { resetTransformation(); }
void doTranslate(const Math::Vector2<T>& vector, TransformationType type) override final {
translate(vector, type);
}
void doRotate(Math::Rad<T> angle, TransformationType type) override final {
doRotate(angle, type);
}
/* No assertions fired, for internal use */
void setTransformationInternal(const Math::Matrix3<T>& transformation) {
/* Setting transformation is forbidden for the scene */

69
src/SceneGraph/RigidMatrixTransformation3D.h

@ -84,11 +84,11 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Normalizes the rotation part using Math::Algorithms::gramSchmidt()
* to prevent rounding errors when rotating the object subsequently.
*/
RigidMatrixTransformation3D<T>* normalizeRotation() {
Object<RigidMatrixTransformation3D<T>>* normalizeRotation() {
setTransformation(Math::Matrix4<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation()));
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -98,16 +98,18 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation()
*/
RigidMatrixTransformation3D<T>* setTransformation(const Math::Matrix4<T>& transformation) {
Object<RigidMatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation", this);
"SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation3D<T>>*>(this));
setTransformationInternal(transformation);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
RigidMatrixTransformation3D<T>* resetTransformation() override {
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<RigidMatrixTransformation3D<T>>* resetTransformation() {
setTransformation({});
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -119,20 +121,21 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation()
*/
RigidMatrixTransformation3D<T>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
Object<RigidMatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation", this);
"SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation",
static_cast<Object<RigidMatrixTransformation3D<T>>*>(this));
transformInternal(transformation, type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation().
*/
RigidMatrixTransformation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::translation(vector), type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -146,9 +149,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis(), normalizeRotation()
*/
RigidMatrixTransformation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -160,9 +163,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Same as calling transform() with Matrix4::rotationX().
* @see normalizeRotation()
*/
RigidMatrixTransformation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationX(angle), type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -174,9 +177,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Same as calling transform() with Matrix4::rotationY().
* @see normalizeRotation()
*/
RigidMatrixTransformation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationY(angle), type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -188,9 +191,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* Same as calling transform() with Matrix4::rotationZ().
* @see normalizeRotation()
*/
RigidMatrixTransformation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
Object<RigidMatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationZ(angle), type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
/**
@ -202,9 +205,9 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
*
* Same as calling transform() with Matrix4::reflection().
*/
RigidMatrixTransformation3D<T>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
Object<RigidMatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::reflection(normal), type);
return this;
return static_cast<Object<RigidMatrixTransformation3D<T>>*>(this);
}
protected:
@ -212,6 +215,28 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
explicit RigidMatrixTransformation3D() = default;
private:
void doResetTransformation() override final { resetTransformation(); }
void doTranslate(const Math::Vector3<T>& vector, TransformationType type) override final {
translate(vector, type);
}
void doRotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type) override final {
rotate(angle, normalizedAxis, type);
}
void doRotateX(Math::Rad<T> angle, TransformationType type) override final {
rotateX(angle, type);
}
void doRotateY(Math::Rad<T> angle, TransformationType type) override final {
rotateY(angle, type);
}
void doRotateZ(Math::Rad<T> angle, TransformationType type) override final {
rotateZ(angle, type);
}
/* No assertions fired, for internal use */
void setTransformationInternal(const Math::Matrix4<T>& transformation) {
/* Setting transformation is forbidden for the scene */

Loading…
Cancel
Save