Browse Source

SceneGraph: test both float and double variants of the APIs.

Uncovered a few issues, fix in the next commit. If this didn't cause my
carpal tunnels to burst, then my hands are probably made from steel.
pull/491/head
Vladimír Vondruš 5 years ago
parent
commit
0b04a49134
  1. 131
      src/Magnum/SceneGraph/Test/AnimableTest.cpp
  2. 1
      src/Magnum/SceneGraph/Test/CMakeLists.txt
  3. 293
      src/Magnum/SceneGraph/Test/CameraTest.cpp
  4. 228
      src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp
  5. 271
      src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp
  6. 235
      src/Magnum/SceneGraph/Test/MatrixTransformation2DTest.cpp
  7. 263
      src/Magnum/SceneGraph/Test/MatrixTransformation3DTest.cpp
  8. 500
      src/Magnum/SceneGraph/Test/ObjectTest.cpp
  9. 262
      src/Magnum/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp
  10. 290
      src/Magnum/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp
  11. 42
      src/Magnum/SceneGraph/Test/SceneTest.cpp
  12. 319
      src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp
  13. 347
      src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation3DTest.cpp
  14. 157
      src/Magnum/SceneGraph/Test/TranslationTransformationTest.cpp

131
src/Magnum/SceneGraph/Test/AnimableTest.cpp

@ -27,47 +27,58 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/SceneGraph/Animable.h"
#include "Magnum/SceneGraph/AbstractFeature.hpp"
#include "Magnum/SceneGraph/Animable.hpp"
#include "Magnum/SceneGraph/AnimableGroup.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
#include "Magnum/SceneGraph/FeatureGroup.hpp"
#include "Magnum/SceneGraph/MatrixTransformation3D.hpp"
#include "Magnum/SceneGraph/Object.hpp"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
struct AnimableTest: TestSuite::Tester {
explicit AnimableTest();
void state();
void step();
void duration();
void repeat();
void stop();
void pause();
template<class T> void state();
template<class T> void step();
template<class T> void duration();
template<class T> void repeat();
template<class T> void stop();
template<class T> void pause();
void deleteWhileRunning();
void debug();
};
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
AnimableTest::AnimableTest() {
addTests({&AnimableTest::state,
&AnimableTest::step,
&AnimableTest::duration,
&AnimableTest::repeat,
&AnimableTest::stop,
&AnimableTest::pause,
addTests({&AnimableTest::state<Float>,
&AnimableTest::state<Double>,
&AnimableTest::step<Float>,
&AnimableTest::step<Double>,
&AnimableTest::duration<Float>,
&AnimableTest::duration<Double>,
&AnimableTest::repeat<Float>,
&AnimableTest::repeat<Double>,
&AnimableTest::stop<Float>,
&AnimableTest::stop<Double>,
&AnimableTest::pause<Float>,
&AnimableTest::pause<Double>,
&AnimableTest::deleteWhileRunning,
&AnimableTest::debug});
}
void AnimableTest::state() {
class StateTrackingAnimable: public SceneGraph::Animable3D {
template<class T> using Object3D = SceneGraph::Object<SceneGraph::BasicMatrixTransformation3D<T>>;
template<class T> void AnimableTest::state() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class StateTrackingAnimable: public SceneGraph::BasicAnimable3D<T> {
public:
StateTrackingAnimable(AbstractObject3D& object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group) {
setDuration(1.0f);
StateTrackingAnimable(AbstractBasicObject3D<T>& object, BasicAnimableGroup3D<T>* group = nullptr): SceneGraph::BasicAnimable3D<T>{object, group} {
this->setDuration(1.0f);
}
std::string trackedState;
@ -81,8 +92,8 @@ void AnimableTest::state() {
void animationStopped() override { trackedState += "stopped"; }
};
Object3D object;
AnimableGroup3D group;
Object3D<T> object;
BasicAnimableGroup3D<T> group;
CORRADE_COMPARE(group.runningCount(), 0);
/* Verify initial state */
@ -157,11 +168,11 @@ void AnimableTest::state() {
CORRADE_COMPARE(group.runningCount(), 2);
}
class OneShotAnimable: public SceneGraph::Animable3D {
template<class T> class OneShotAnimable: public SceneGraph::BasicAnimable3D<T> {
public:
OneShotAnimable(AbstractObject3D& object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group), time(-1.0f) {
setDuration(10.0f);
setState(AnimationState::Running);
explicit OneShotAnimable(AbstractBasicObject3D<T>& object, BasicAnimableGroup3D<T>* group = nullptr): SceneGraph::BasicAnimable3D<T>{object, group}, time{-1.0f} {
this->setDuration(10.0f);
this->setState(AnimationState::Running);
}
Float time;
@ -181,10 +192,12 @@ class OneShotAnimable: public SceneGraph::Animable3D {
}
};
void AnimableTest::step() {
class InifiniteAnimable: public SceneGraph::Animable3D {
template<class T> void AnimableTest::step() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class InifiniteAnimable: public SceneGraph::BasicAnimable3D<T> {
public:
InifiniteAnimable(AbstractObject3D& object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group), time(-1.0f), delta(0.0f) {}
InifiniteAnimable(AbstractBasicObject3D<T>& object, BasicAnimableGroup3D<T>* group = nullptr): SceneGraph::BasicAnimable3D<T>{object, group}, time{-1.0f}, delta{0.0f} {}
Float time, delta;
@ -195,9 +208,9 @@ void AnimableTest::step() {
}
};
Object3D object;
AnimableGroup3D group;
InifiniteAnimable animable(object, &group);
Object3D<T> object;
BasicAnimableGroup3D<T> group;
InifiniteAnimable animable{object, &group};
/* Calling step() if no object is running should do nothing */
group.step(5.0f, 0.5f);
@ -219,10 +232,12 @@ void AnimableTest::step() {
CORRADE_COMPARE(animable.delta, 0.75f);
}
void AnimableTest::duration() {
Object3D object;
AnimableGroup3D group;
OneShotAnimable animable(object, &group);
template<class T> void AnimableTest::duration() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> object;
BasicAnimableGroup3D<T> group;
OneShotAnimable<T> animable{object, &group};
CORRADE_VERIFY(!animable.isRepeated());
/* First animation step is in duration, verify that animation is still
@ -240,13 +255,15 @@ void AnimableTest::duration() {
CORRADE_COMPARE(animable.time, 0.0f);
}
void AnimableTest::repeat() {
class RepeatingAnimable: public SceneGraph::Animable3D {
template<class T> void AnimableTest::repeat() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class RepeatingAnimable: public SceneGraph::BasicAnimable3D<T> {
public:
RepeatingAnimable(AbstractObject3D& object, AnimableGroup3D* group = nullptr): SceneGraph::Animable3D(object, group), time(-1.0f) {
setDuration(10.0f);
setState(AnimationState::Running);
setRepeated(true);
RepeatingAnimable(AbstractBasicObject3D<T>& object, BasicAnimableGroup3D<T>* group = nullptr): SceneGraph::BasicAnimable3D<T>{object, group}, time(-1.0f) {
this->setDuration(10.0f);
this->setState(AnimationState::Running);
this->setRepeated(true);
}
Float time;
@ -257,9 +274,9 @@ void AnimableTest::repeat() {
}
};
Object3D object;
AnimableGroup3D group;
RepeatingAnimable animable(object, &group);
Object3D<T> object;
BasicAnimableGroup3D<T> group;
RepeatingAnimable animable{object, &group};
CORRADE_COMPARE(animable.repeatCount(), 0);
/* First animation steps is in first loop iteration */
@ -301,10 +318,12 @@ void AnimableTest::repeat() {
CORRADE_COMPARE(animable.state(), AnimationState::Stopped);
}
void AnimableTest::stop() {
Object3D object;
AnimableGroup3D group;
OneShotAnimable animable(object, &group);
template<class T> void AnimableTest::stop() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> object;
BasicAnimableGroup3D<T> group;
OneShotAnimable<T> animable(object, &group);
CORRADE_COMPARE(animable.repeatCount(), 0);
/* Eat up some absolute time */
@ -326,10 +345,12 @@ void AnimableTest::stop() {
CORRADE_COMPARE(animable.time, 0.0f);
}
void AnimableTest::pause() {
Object3D object;
AnimableGroup3D group;
OneShotAnimable animable(object, &group);
template<class T> void AnimableTest::pause() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> object;
BasicAnimableGroup3D<T> group;
OneShotAnimable<T> animable(object, &group);
/* First two steps, animation is running */
group.step(1.0f, 0.5f);
@ -357,12 +378,12 @@ void AnimableTest::pause() {
}
void AnimableTest::deleteWhileRunning() {
Object3D object;
Object3D<Float> object;
AnimableGroup3D group;
CORRADE_COMPARE(group.runningCount(), 0);
{
OneShotAnimable animable(object, &group);
OneShotAnimable<Float> animable(object, &group);
/* Eat up some absolute time */
group.step(1.0f, 0.5f);

1
src/Magnum/SceneGraph/Test/CMakeLists.txt

@ -40,6 +40,7 @@ corrade_add_test(SceneGraphTranslationTransfo___Test TranslationTransformationTe
set_property(TARGET
SceneGraphDualComplexTransfo___Test
SceneGraphDualQuaternionTran___Test
SceneGraphObjectTest
SceneGraphRigidMatrixTrans___2DTest
SceneGraphRigidMatrixTrans___3DTest
SceneGraphTranslationRotat___2DTest

293
src/Magnum/SceneGraph/Test/CameraTest.cpp

@ -27,11 +27,14 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/SceneGraph/Camera.hpp" /* only for aspectRatioFix(), so it doesn't have to be exported */
#include "Magnum/SceneGraph/AbstractFeature.hpp"
#include "Magnum/SceneGraph/Camera.hpp"
#include "Magnum/SceneGraph/Camera.h"
#include "Magnum/SceneGraph/Drawable.h"
#include "Magnum/SceneGraph/MatrixTransformation2D.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
#include "Magnum/SceneGraph/Drawable.hpp"
#include "Magnum/SceneGraph/FeatureGroup.hpp"
#include "Magnum/SceneGraph/MatrixTransformation2D.hpp"
#include "Magnum/SceneGraph/MatrixTransformation3D.hpp"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
@ -39,97 +42,117 @@ namespace Magnum { namespace SceneGraph { namespace Test { namespace {
struct CameraTest: TestSuite::Tester {
explicit CameraTest();
void fixAspectRatio();
void defaultProjection2D();
void defaultProjection3D();
void projectionCorrectedInvertedY();
void projectionSize2D();
void projectionSizeOrthographic();
void projectionSizePerspective();
void projectionSizeViewport();
void draw();
void drawOrdered();
template<class T> void fixAspectRatio();
template<class T> void defaultProjection2D();
template<class T> void defaultProjection3D();
template<class T> void projectionCorrectedInvertedY();
template<class T> void projectionSize2D();
template<class T> void projectionSizeOrthographic();
template<class T> void projectionSizePerspective();
template<class T> void projectionSizeViewport();
template<class T> void draw();
template<class T> void drawOrdered();
};
typedef SceneGraph::Object<SceneGraph::MatrixTransformation2D> Object2D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
CameraTest::CameraTest() {
addTests({&CameraTest::fixAspectRatio,
&CameraTest::defaultProjection2D,
&CameraTest::defaultProjection3D,
&CameraTest::projectionCorrectedInvertedY,
&CameraTest::projectionSize2D,
&CameraTest::projectionSizeOrthographic,
&CameraTest::projectionSizePerspective,
&CameraTest::projectionSizeViewport,
&CameraTest::draw,
&CameraTest::drawOrdered});
addTests<CameraTest>({
&CameraTest::fixAspectRatio<Float>,
&CameraTest::fixAspectRatio<Double>,
&CameraTest::defaultProjection2D<Float>,
&CameraTest::defaultProjection2D<Double>,
&CameraTest::defaultProjection3D<Float>,
&CameraTest::defaultProjection3D<Double>,
&CameraTest::projectionCorrectedInvertedY<Float>,
&CameraTest::projectionCorrectedInvertedY<Double>,
&CameraTest::projectionSize2D<Float>,
&CameraTest::projectionSize2D<Double>,
&CameraTest::projectionSizeOrthographic<Float>,
&CameraTest::projectionSizeOrthographic<Double>,
&CameraTest::projectionSizePerspective<Float>,
&CameraTest::projectionSizePerspective<Double>,
&CameraTest::projectionSizeViewport<Float>,
&CameraTest::projectionSizeViewport<Double>,
&CameraTest::draw<Float>,
&CameraTest::draw<Double>,
&CameraTest::drawOrdered<Float>,
&CameraTest::drawOrdered<Double>});
}
void CameraTest::fixAspectRatio() {
Vector2 projectionScale(0.5f, 1.0f/3.0f);
template<class T> using Object2D = SceneGraph::Object<SceneGraph::BasicMatrixTransformation2D<T>>;
template<class T> using Object3D = SceneGraph::Object<SceneGraph::BasicMatrixTransformation3D<T>>;
template<class T> using Scene3D = SceneGraph::Scene<SceneGraph::BasicMatrixTransformation3D<T>>;
template<class T> void CameraTest::fixAspectRatio() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Vector2<T> projectionScale(T(0.5), T(1.0)/T(3.0));
Vector2i size(400, 300);
/* Division by zero */
Vector2 projectionScaleZeroY(0.5f, 0.0f);
Vector2 projectionScaleZeroX(0.0f, 0.5f);
Math::Vector2<T> projectionScaleZeroY(T(0.5), T(0.0));
Math::Vector2<T> projectionScaleZeroX(T(0.0), T(0.5));
Vector2i sizeZeroY(400, 0);
Vector2i sizeZeroX(0, 300);
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Clip, projectionScaleZeroX, size)), Matrix4());
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Clip, projectionScaleZeroY, size)), Matrix4());
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Clip, projectionScale, sizeZeroY)), Matrix4());
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Extend, projectionScale, sizeZeroX)), Matrix4());
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Clip, projectionScaleZeroX, size)), Math::Matrix4<T>{});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Clip, projectionScaleZeroY, size)), Math::Matrix4<T>{});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Clip, projectionScale, sizeZeroY)), Math::Matrix4<T>{});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Extend, projectionScale, sizeZeroX)), Math::Matrix4<T>{});
/* Not preserved */
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::NotPreserved, projectionScale, size)), Matrix4());
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::NotPreserved, projectionScale, size)), Math::Matrix4<T>{});
/* Clip */
Matrix4 expectedClip({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 4.0f/3.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Clip, Vector2(0.5f), size)), expectedClip);
Math::Matrix4<T> expectedClip(
{T(1.0), T(0.0), T(0.0), T(0.0)},
{T(0.0), T(4.0)/T(3.0), T(0.0), T(0.0)},
{T(0.0), T(0.0), T(1.0), T(0.0)},
{T(0.0), T(0.0), T(0.0), T(1.0)});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Clip, Math::Vector2<T>{T(0.5)}, size)), expectedClip);
Matrix4 expectedClipRectangle({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 2.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Clip, projectionScale, size)), expectedClipRectangle);
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Clip, projectionScale, size)), Math::Matrix4<T>{expectedClipRectangle});
/* Extend */
Matrix4 expectedExtend({3.0f/4.0f, 0.0f, 0.0f, 0.0f},
{ 0.0f, 1.0f, 0.0f, 0.0f},
{ 0.0f, 0.0f, 1.0f, 0.0f},
{ 0.0f, 0.0f, 0.0f, 1.0f});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Extend, Vector2(0.5f), size)), expectedExtend);
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Extend, Math::Vector2<T>{T(0.5)}, size)), Math::Matrix4<T>{expectedExtend});
Matrix4 expectedExtendRectangle({0.5f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
CORRADE_COMPARE((Implementation::aspectRatioFix<3, Float>(AspectRatioPolicy::Extend, projectionScale, size)), expectedExtendRectangle);
CORRADE_COMPARE((Implementation::aspectRatioFix<3, T>(AspectRatioPolicy::Extend, projectionScale, size)), Math::Matrix4<T>{expectedExtendRectangle});
}
void CameraTest::defaultProjection2D() {
Object2D o;
Camera2D camera(o);
CORRADE_COMPARE(camera.projectionMatrix(), Matrix3());
CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f));
template<class T> void CameraTest::defaultProjection2D() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
BasicCamera2D<T> camera{o};
CORRADE_COMPARE(camera.projectionMatrix(), Math::Matrix3<T>{});
CORRADE_COMPARE(camera.projectionSize(), Math::Vector2<T>{T(2.0)});
}
void CameraTest::defaultProjection3D() {
Object3D o;
Camera3D camera(o);
CORRADE_COMPARE(camera.projectionMatrix(), Matrix4());
CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f));
template<class T> void CameraTest::defaultProjection3D() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
BasicCamera3D<T> camera{o};
CORRADE_COMPARE(camera.projectionMatrix(), Math::Matrix4<T>{});
CORRADE_COMPARE(camera.projectionSize(), Math::Vector2<T>{T(2.0)});
}
void CameraTest::projectionCorrectedInvertedY() {
Object2D o;
Camera2D camera(o);
camera.setProjectionMatrix(Matrix3::projection({4.0f, -2.0f}))
template<class T> void CameraTest::projectionCorrectedInvertedY() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
BasicCamera2D<T> camera{o};
camera.setProjectionMatrix(Math::Matrix3<T>::projection({T(4.0), T(-2.0)}))
.setAspectRatioPolicy(AspectRatioPolicy::Extend)
.setViewport({4, 4});
@ -137,133 +160,145 @@ void CameraTest::projectionCorrectedInvertedY() {
Matrix3 expected{{0.5f, 0.0f, 0.0f},
{0.0f, -0.5f, 0.0f},
{0.0f, 0.0f, 1.0f}};
CORRADE_COMPARE(camera.projectionMatrix(), expected);
CORRADE_COMPARE(camera.projectionMatrix(), Math::Matrix3<T>{expected});
}
void CameraTest::projectionSize2D() {
Vector2 projectionSize(4.0f, 3.0f);
Object2D o;
Camera2D camera(o);
camera.setProjectionMatrix(Matrix3::projection(projectionSize));
template<class T> void CameraTest::projectionSize2D() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Vector2<T> projectionSize{T(4.0), T(3.0)};
Object2D<T> o;
BasicCamera2D<T> camera{o};
camera.setProjectionMatrix(Math::Matrix3<T>::projection(projectionSize));
CORRADE_COMPARE(camera.projectionSize(), projectionSize);
}
void CameraTest::projectionSizeOrthographic() {
Vector2 projectionSizeRectangle(5.0f, 4.0f);
Object3D o;
Camera3D camera(o);
camera.setProjectionMatrix(Matrix4::orthographicProjection(projectionSizeRectangle, 1, 9));
template<class T> void CameraTest::projectionSizeOrthographic() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Vector2<T> projectionSizeRectangle{T(5.0), T(4.0)};
Object3D<T> o;
BasicCamera3D<T> camera{o};
camera.setProjectionMatrix(Math::Matrix4<T>::orthographicProjection(projectionSizeRectangle, 1, 9));
CORRADE_COMPARE(camera.projectionSize(), projectionSizeRectangle);
}
void CameraTest::projectionSizePerspective() {
Object3D o;
Camera3D camera(o);
camera.setProjectionMatrix(Matrix4::perspectiveProjection(Deg(27.0f), 2.35f, 32.0f, 100));
CORRADE_COMPARE(camera.projectionSize(), Vector2(0.48015756f, 0.204322f));
template<class T> void CameraTest::projectionSizePerspective() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
BasicCamera3D<T> camera{o};
camera.setProjectionMatrix(Math::Matrix4<T>::perspectiveProjection(Math::Deg<T>(T(27.0)), T(2.35), T(32.0), 100));
CORRADE_COMPARE(camera.projectionSize(), (Math::Vector2<T>{T(0.480157518160232), T(0.20432234815329)}));
}
void CameraTest::projectionSizeViewport() {
Object3D o;
Camera3D camera(o);
template<class T> void CameraTest::projectionSizeViewport() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
BasicCamera3D<T> camera(o);
camera.setViewport({200, 300});
CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f, 2.0f));
CORRADE_COMPARE(camera.projectionSize(), (Math::Vector2<T>{T(2.0), T(2.0)}));
camera.setAspectRatioPolicy(AspectRatioPolicy::Extend);
CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f, 3.0f));
CORRADE_COMPARE(camera.projectionSize(), (Math::Vector2<T>{T(2.0), T(3.0)}));
camera.setAspectRatioPolicy(AspectRatioPolicy::Clip);
CORRADE_COMPARE(camera.projectionSize(), Vector2(4.0f/3.0f, 2.0f));
CORRADE_COMPARE(camera.projectionSize(), (Math::Vector2<T>{T(4.0)/T(3.0), T(2.0)}));
}
void CameraTest::draw() {
class Drawable: public SceneGraph::Drawable3D {
template<class T> void CameraTest::draw() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class Drawable: public SceneGraph::BasicDrawable3D<T> {
public:
Drawable(AbstractObject3D& object, DrawableGroup3D* group, Matrix4& result): SceneGraph::Drawable3D(object, group), result(result) {}
Drawable(AbstractBasicObject3D<T>& object, BasicDrawableGroup3D<T>* group, Math::Matrix4<T>& result): SceneGraph::BasicDrawable3D<T>{object, group}, result(result) {}
protected:
void draw(const Matrix4& transformationMatrix, Camera3D&) override {
void draw(const Math::Matrix4<T>& transformationMatrix, BasicCamera3D<T>&) override {
result = transformationMatrix;
}
private:
Matrix4& result;
Math::Matrix4<T>& result;
};
DrawableGroup3D group;
Scene3D scene;
BasicDrawableGroup3D<T> group;
Scene3D<T> scene;
Object3D first(&scene);
Matrix4 firstTransformation;
first.scale(Vector3(5.0f));
new Drawable(first, &group, firstTransformation);
Object3D<T> first(&scene);
Math::Matrix4<T> firstTransformation;
first.scale(Math::Vector3<T>{T(5.0)});
new Drawable{first, &group, firstTransformation};
Object3D second(&scene);
Matrix4 secondTransformation;
second.translate(Vector3::yAxis(3.0f));
new Drawable(second, &group, secondTransformation);
Object3D<T> second(&scene);
Math::Matrix4<T> secondTransformation;
second.translate(Math::Vector3<T>::yAxis(T(3.0)));
new Drawable{second, &group, secondTransformation};
Object3D third(&second);
Matrix4 thirdTransformation;
third.translate(Vector3::zAxis(-1.5f));
new Drawable(third, &group, thirdTransformation);
Object3D<T> third(&second);
Math::Matrix4<T> thirdTransformation;
third.translate(Math::Vector3<T>::zAxis(T(-1.5)));
new Drawable{third, &group, thirdTransformation};
Camera3D camera(third);
BasicCamera3D<T> camera{third};
camera.draw(group);
CORRADE_COMPARE(firstTransformation, Matrix4::translation({0.0f, -3.0f, 1.5f})*Matrix4::scaling(Vector3(5.0f)));
CORRADE_COMPARE(secondTransformation, Matrix4::translation(Vector3::zAxis(1.5f)));
CORRADE_COMPARE(thirdTransformation, Matrix4());
CORRADE_COMPARE(firstTransformation, Math::Matrix4<T>::translation({T(0.0), T(-3.0), T(1.5)})*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(5.0))));
CORRADE_COMPARE(secondTransformation, Math::Matrix4<T>::translation(Math::Vector3<T>::zAxis(T(1.5))));
CORRADE_COMPARE(thirdTransformation, Math::Matrix4<T>{});
}
void CameraTest::drawOrdered() {
class Drawable: public SceneGraph::Drawable3D {
template<class T> void CameraTest::drawOrdered() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class Drawable: public SceneGraph::BasicDrawable3D<T> {
public:
Drawable(AbstractObject3D& object, DrawableGroup3D* group, std::vector<Matrix4>& result): SceneGraph::Drawable3D(object, group), _result(result) {}
Drawable(AbstractBasicObject3D<T>& object, BasicDrawableGroup3D<T>* group, std::vector<Math::Matrix4<T>>& result): SceneGraph::BasicDrawable3D<T>{object, group}, _result(result) {}
protected:
void draw(const Matrix4& transformationMatrix, Camera3D&) override {
void draw(const Math::Matrix4<T>& transformationMatrix, BasicCamera3D<T>&) override {
_result.push_back(transformationMatrix);
}
private:
std::vector<Matrix4>& _result;
std::vector<Math::Matrix4<T>>& _result;
};
DrawableGroup3D group;
Scene3D scene;
BasicDrawableGroup3D<T> group;
Scene3D<T> scene;
std::vector<Matrix4> transformations;
std::vector<Math::Matrix4<T>> transformations;
Object3D first(&scene);
first.scale(Vector3(5.0f))
.translate(Vector3::zAxis(-1.0f));
Object3D<T> first{&scene};
first.scale(Math::Vector3<T>{T(5.0)})
.translate(Math::Vector3<T>::zAxis(T(-1.0)));
new Drawable{first, &group, transformations};
Object3D second(&scene);
second.translate(Vector3::zAxis(3.0f));
Object3D<T> second{&scene};
second.translate(Math::Vector3<T>::zAxis(T(3.0)));
new Drawable{second, &group, transformations};
Object3D third(&second);
third.translate(Vector3::zAxis(-1.5f));
Object3D<T> third{&second};
third.translate(Math::Vector3<T>::zAxis(T(-1.5)));
new Drawable{third, &group, transformations};
Camera3D camera(third);
BasicCamera3D<T> camera{third};
std::vector<std::pair<std::reference_wrapper<SceneGraph::Drawable3D>, Matrix4>> drawableTransformations = camera.drawableTransformations(group);
std::vector<std::pair<std::reference_wrapper<SceneGraph::BasicDrawable3D<T>>, Math::Matrix4<T>>> drawableTransformations = camera.drawableTransformations(group);
std::sort(drawableTransformations.begin(), drawableTransformations.end(),
[](const std::pair<std::reference_wrapper<SceneGraph::Drawable3D>, Matrix4>& a,
const std::pair<std::reference_wrapper<SceneGraph::Drawable3D>, Matrix4>& b) {
[](const std::pair<std::reference_wrapper<SceneGraph::BasicDrawable3D<T>>, Math::Matrix4<T>>& a,
const std::pair<std::reference_wrapper<SceneGraph::BasicDrawable3D<T>>, Math::Matrix4<T>>& b) {
return a.second.translation().z() < b.second.translation().z();
});
camera.draw(drawableTransformations);
/* Should be ordered front to back, most negative Z first */
CORRADE_COMPARE_AS(transformations, (std::vector<Matrix4>{
Matrix4::translation(Vector3::zAxis(-2.5f))*Matrix4::scaling(Vector3{5.0f}), /* first */
Matrix4{}, /* third */
Matrix4::translation(Vector3::zAxis(1.5f)) /* second */
CORRADE_COMPARE_AS(transformations, (std::vector<Math::Matrix4<T>>{
Math::Matrix4<T>::translation(Math::Vector3<T>::zAxis(T(-2.5)))*Math::Matrix4<T>::scaling(Math::Vector3<T>{T(5.0)}), /* first */
Math::Matrix4<T>{}, /* third */
Math::Matrix4<T>::translation(Math::Vector3<T>::zAxis(T(1.5))) /* second */
}), TestSuite::Compare::Container);
}

228
src/Magnum/SceneGraph/Test/DualComplexTransformationTest.cpp

@ -28,174 +28,212 @@
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/SceneGraph/DualComplexTransformation.h"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<DualComplexTransformation> Object2D;
typedef Scene<DualComplexTransformation> Scene2D;
struct DualComplexTransformationTest: TestSuite::Tester {
explicit DualComplexTransformationTest();
void fromMatrix();
void toMatrix();
void compose();
void inverted();
void setTransformation();
void setTransformationInvalid();
void resetTransformation();
void transform();
void transformInvalid();
void translate();
void rotate();
void normalizeRotation();
template<class T> void fromMatrix();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
template<class T> void setTransformation();
template<class T> void setTransformationInvalid();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void transformInvalid();
template<class T> void translate();
template<class T> void rotate();
template<class T> void normalizeRotation();
};
DualComplexTransformationTest::DualComplexTransformationTest() {
addTests({&DualComplexTransformationTest::fromMatrix,
&DualComplexTransformationTest::toMatrix,
&DualComplexTransformationTest::compose,
&DualComplexTransformationTest::inverted,
&DualComplexTransformationTest::setTransformation,
&DualComplexTransformationTest::setTransformationInvalid,
&DualComplexTransformationTest::resetTransformation,
&DualComplexTransformationTest::transform,
&DualComplexTransformationTest::transformInvalid,
&DualComplexTransformationTest::translate,
&DualComplexTransformationTest::rotate,
&DualComplexTransformationTest::normalizeRotation});
addTests<DualComplexTransformationTest>({
&DualComplexTransformationTest::fromMatrix<Float>,
&DualComplexTransformationTest::fromMatrix<Double>,
&DualComplexTransformationTest::toMatrix<Float>,
&DualComplexTransformationTest::toMatrix<Double>,
&DualComplexTransformationTest::compose<Float>,
&DualComplexTransformationTest::compose<Double>,
&DualComplexTransformationTest::inverted<Float>,
&DualComplexTransformationTest::inverted<Double>,
&DualComplexTransformationTest::setTransformation<Float>,
&DualComplexTransformationTest::setTransformation<Double>,
&DualComplexTransformationTest::setTransformationInvalid<Float>,
&DualComplexTransformationTest::setTransformationInvalid<Double>,
&DualComplexTransformationTest::resetTransformation<Float>,
&DualComplexTransformationTest::resetTransformation<Double>,
&DualComplexTransformationTest::transform<Float>,
&DualComplexTransformationTest::transform<Double>,
&DualComplexTransformationTest::transformInvalid<Float>,
&DualComplexTransformationTest::transformInvalid<Double>,
&DualComplexTransformationTest::translate<Float>,
&DualComplexTransformationTest::translate<Double>,
&DualComplexTransformationTest::rotate<Float>,
&DualComplexTransformationTest::rotate<Double>,
&DualComplexTransformationTest::normalizeRotation<Float>,
&DualComplexTransformationTest::normalizeRotation<Double>});
}
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});
CORRADE_COMPARE(Implementation::Transformation<DualComplexTransformation>::fromMatrix(m), c);
template<class T> using Object2D = Object<BasicDualComplexTransformation<T>>;
template<class T> using Scene2D = Scene<BasicDualComplexTransformation<T>>;
template<class T> void DualComplexTransformationTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
Math::DualComplex<T> c = Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)})*Math::DualComplex<T>::translation({1.0, T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualComplexTransformation<T>>::fromMatrix(m), c);
}
void DualComplexTransformationTest::toMatrix() {
DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f});
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<DualComplexTransformation>::toMatrix(c), m);
template<class T> void DualComplexTransformationTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::DualComplex<T> c = Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)})*Math::DualComplex<T>::translation({T(1.0), T(-0.3)});
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualComplexTransformation<T>>::toMatrix(c), m);
}
void DualComplexTransformationTest::compose() {
DualComplex parent = DualComplex::rotation(Deg(17.0f));
DualComplex child = DualComplex::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<DualComplexTransformation>::compose(parent, child), parent*child);
template<class T> void DualComplexTransformationTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::DualComplex<T> parent = Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)});
Math::DualComplex<T> child = Math::DualComplex<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualComplexTransformation<T>>::compose(parent, child), parent*child);
}
void DualComplexTransformationTest::inverted() {
DualComplex c = DualComplex::rotation(Deg(17.0f))*DualComplex::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<DualComplexTransformation>::inverted(c)*c, DualComplex());
template<class T> void DualComplexTransformationTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::DualComplex<T> c = Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)})*Math::DualComplex<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualComplexTransformation<T>>::inverted(c)*c, Math::DualComplex<T>{});
}
void DualComplexTransformationTest::setTransformation() {
Object2D o;
template<class T> void DualComplexTransformationTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
/* Dirty after setting transformation */
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
/* Scene cannot be transformed */
Scene2D s;
Scene2D<T> s;
s.setClean();
s.setTransformation(DualComplex::rotation(Deg(17.0f)));
s.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix3());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix3<T>{});
}
void DualComplexTransformationTest::setTransformationInvalid() {
template<class T> void DualComplexTransformationTest::setTransformationInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Object2D o;
Object2D<T> o;
/* Can't transform with non-rigid transformation */
std::ostringstream out;
Error redirectError{&out};
o.setTransformation(DualComplex({1.0f, 2.0f}, {}));
o.setTransformation(Math::DualComplex<T>({T(1.0), T(2.0)}, {}));
CORRADE_COMPARE(out.str(), "SceneGraph::DualComplexTransformation::setTransformation(): the dual complex number is not normalized\n");
}
void DualComplexTransformationTest::resetTransformation() {
Object2D o;
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
CORRADE_VERIFY(o.transformationMatrix() != Matrix3());
template<class T> void DualComplexTransformationTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix3<T>{});
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>{});
}
void DualComplexTransformationTest::transform() {
template<class T> void DualComplexTransformationTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
o.transform(DualComplex::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
o.transform(Math::DualComplex<T>::translation({T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
o.transformLocal(DualComplex::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
o.transformLocal(Math::DualComplex<T>::translation({T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
}
}
void DualComplexTransformationTest::transformInvalid() {
template<class T> void DualComplexTransformationTest::transformInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
/* Can't transform with non-rigid transformation */
Object2D o;
Object2D<T> o;
std::ostringstream out;
Error redirectError{&out};
o.transform(DualComplex({1.0f, 2.0f}, {}));
o.transform(Math::DualComplex<T>{{T(1.0), T(2.0)}, {}});
CORRADE_COMPARE(out.str(), "SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized\n");
}
void DualComplexTransformationTest::translate() {
template<class T> void DualComplexTransformationTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
o.translate({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translate({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
o.translateLocal({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translateLocal({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
}
}
void DualComplexTransformationTest::rotate() {
template<class T> void DualComplexTransformationTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
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<T> o;
o.setTransformation(Math::DualComplex<T>::translation({T(1.0), T(-0.3)}))
.rotate(Math::Complex<T>::rotation(Math::Deg<T>{T(7.0)}))
.rotate(Math::Deg<T>{T(10.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
} {
Object2D o;
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)));
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::translation({T(1.0), T(-0.3)}))
.rotateLocal(Math::Complex<T>::rotation(Math::Deg<T>{T(7.0)}))
.rotateLocal(Math::Deg<T>{T(10.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
}
}
void DualComplexTransformationTest::normalizeRotation() {
Object2D o;
o.setTransformation(DualComplex::rotation(Deg(17.0f)));
template<class T> void DualComplexTransformationTest::normalizeRotation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation(Math::DualComplex<T>::rotation(Math::Deg<T>{T(17.0)}));
o.normalizeRotation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
}
}}}}

271
src/Magnum/SceneGraph/Test/DualQuaternionTransformationTest.cpp

@ -28,204 +28,245 @@
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/SceneGraph/DualQuaternionTransformation.h"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<DualQuaternionTransformation> Object3D;
typedef Scene<DualQuaternionTransformation> Scene3D;
struct DualQuaternionTransformationTest: TestSuite::Tester {
explicit DualQuaternionTransformationTest();
void fromMatrix();
void fromMatrixInvalid();
void toMatrix();
void compose();
void inverted();
void setTransformation();
void setTransformationInvalid();
void resetTransformation();
void transform();
void transformInvalid();
void translate();
void rotate();
void normalizeRotation();
template<class T> void fromMatrix();
template<class T> void fromMatrixInvalid();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
template<class T> void setTransformation();
template<class T> void setTransformationInvalid();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void transformInvalid();
template<class T> void translate();
template<class T> void rotate();
template<class T> void normalizeRotation();
};
DualQuaternionTransformationTest::DualQuaternionTransformationTest() {
addTests({&DualQuaternionTransformationTest::fromMatrix,
&DualQuaternionTransformationTest::fromMatrixInvalid,
&DualQuaternionTransformationTest::toMatrix,
&DualQuaternionTransformationTest::compose,
&DualQuaternionTransformationTest::inverted,
&DualQuaternionTransformationTest::setTransformation,
&DualQuaternionTransformationTest::setTransformationInvalid,
&DualQuaternionTransformationTest::resetTransformation,
&DualQuaternionTransformationTest::transform,
&DualQuaternionTransformationTest::transformInvalid,
&DualQuaternionTransformationTest::translate,
&DualQuaternionTransformationTest::rotate,
&DualQuaternionTransformationTest::normalizeRotation});
addTests<DualQuaternionTransformationTest>({
&DualQuaternionTransformationTest::fromMatrix<Float>,
&DualQuaternionTransformationTest::fromMatrix<Double>,
&DualQuaternionTransformationTest::fromMatrixInvalid<Float>,
&DualQuaternionTransformationTest::fromMatrixInvalid<Double>,
&DualQuaternionTransformationTest::toMatrix<Float>,
&DualQuaternionTransformationTest::toMatrix<Double>,
&DualQuaternionTransformationTest::compose<Float>,
&DualQuaternionTransformationTest::compose<Double>,
&DualQuaternionTransformationTest::inverted<Float>,
&DualQuaternionTransformationTest::inverted<Double>,
&DualQuaternionTransformationTest::setTransformation<Float>,
&DualQuaternionTransformationTest::setTransformation<Double>,
&DualQuaternionTransformationTest::setTransformationInvalid<Float>,
&DualQuaternionTransformationTest::setTransformationInvalid<Double>,
&DualQuaternionTransformationTest::resetTransformation<Float>,
&DualQuaternionTransformationTest::resetTransformation<Double>,
&DualQuaternionTransformationTest::transform<Float>,
&DualQuaternionTransformationTest::transform<Double>,
&DualQuaternionTransformationTest::transformInvalid<Float>,
&DualQuaternionTransformationTest::transformInvalid<Double>,
&DualQuaternionTransformationTest::translate<Float>,
&DualQuaternionTransformationTest::translate<Double>,
&DualQuaternionTransformationTest::rotate<Float>,
&DualQuaternionTransformationTest::rotate<Double>,
&DualQuaternionTransformationTest::normalizeRotation<Float>,
&DualQuaternionTransformationTest::normalizeRotation<Double>});
}
using namespace Math::Literals;
void DualQuaternionTransformationTest::fromMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<DualQuaternionTransformation>::fromMatrix(m), q);
template<class T> using Object3D = Object<BasicDualQuaternionTransformation<T>>;
template<class T> using Scene3D = Scene<BasicDualQuaternionTransformation<T>>;
template<class T> void DualQuaternionTransformationTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
Math::DualQuaternion<T> q = Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis())*Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualQuaternionTransformation<T>>::fromMatrix(m), q);
}
void DualQuaternionTransformationTest::fromMatrixInvalid() {
template<class T> void DualQuaternionTransformationTest::fromMatrixInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
Implementation::Transformation<DualQuaternionTransformation>::fromMatrix(Matrix4::scaling(Vector3(4.0f)));
Implementation::Transformation<BasicDualQuaternionTransformation<T>>::fromMatrix(Math::Matrix4<T>::scaling(Math::Vector3<T>{T(4.0)}));
CORRADE_COMPARE(out.str(), "SceneGraph::DualQuaternionTransformation: the matrix doesn't represent rigid transformation\n");
}
void DualQuaternionTransformationTest::toMatrix() {
DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f});
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<DualQuaternionTransformation>::toMatrix(q), m);
template<class T> void DualQuaternionTransformationTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::DualQuaternion<T> q = Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis())*Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)});
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualQuaternionTransformation<T>>::toMatrix(q), m);
}
void DualQuaternionTransformationTest::compose() {
DualQuaternion parent = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis());
DualQuaternion child = DualQuaternion::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<DualQuaternionTransformation>::compose(parent, child), parent*child);
template<class T> void DualQuaternionTransformationTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::DualQuaternion<T> parent = Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis());
Math::DualQuaternion<T> child = Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualQuaternionTransformation<T>>::compose(parent, child), parent*child);
}
void DualQuaternionTransformationTest::inverted() {
DualQuaternion q = DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis())*DualQuaternion::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<DualQuaternionTransformation>::inverted(q)*q, DualQuaternion());
template<class T> void DualQuaternionTransformationTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::DualQuaternion<T> q = Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis())*Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicDualQuaternionTransformation<T>>::inverted(q)*q, Math::DualQuaternion<T>{});
}
void DualQuaternionTransformationTest::setTransformation() {
Object3D o;
template<class T> void DualQuaternionTransformationTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
/* Dirty after setting transformation */
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
/* Scene cannot be transformed */
Scene3D s;
Scene3D<T> s;
s.setClean();
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
s.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix4());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix4<T>{});
}
void DualQuaternionTransformationTest::setTransformationInvalid() {
template<class T> void DualQuaternionTransformationTest::setTransformationInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Object3D o;
Object3D<T> o;
/* Can't transform with non-rigid transformation */
std::ostringstream out;
Error redirectError{&out};
o.setTransformation(DualQuaternion({{1.0f, 2.0f, 3.0f}, 4.0f}, {}));
o.setTransformation(Math::DualQuaternion<T>({{T(1.0), T(2.0), T(3.0)}, T(4.0)}, {}));
CORRADE_COMPARE(out.str(), "SceneGraph::DualQuaternionTransformation::setTransformation(): the dual quaternion is not normalized\n");
}
void DualQuaternionTransformationTest::resetTransformation() {
Object3D o;
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
CORRADE_VERIFY(o.transformationMatrix() != Matrix4());
template<class T> void DualQuaternionTransformationTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix4<T>{});
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>{});
}
void DualQuaternionTransformationTest::transform() {
template<class T> void DualQuaternionTransformationTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
o.transform(Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
o.transformLocal(DualQuaternion::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
o.transformLocal(Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
}
}
void DualQuaternionTransformationTest::transformInvalid() {
template<class T> void DualQuaternionTransformationTest::transformInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
/* Can't transform with non-rigid transformation */
Object3D o;
Object3D<T> o;
std::ostringstream out;
Error redirectError{&out};
o.transform(DualQuaternion({{1.0f, 2.0f, 3.0f}, 4.0f}, {}));
o.transform(Math::DualQuaternion<T>({{T(1.0), T(2.0), T(3.0)}, T(4.0)}, {}));
CORRADE_COMPARE(out.str(), "SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized\n");
}
void DualQuaternionTransformationTest::translate() {
template<class T> void DualQuaternionTransformationTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
o.translate({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
o.translate({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
o.translateLocal({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
o.translateLocal({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
}
}
void DualQuaternionTransformationTest::rotate() {
template<class T> void DualQuaternionTransformationTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
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))*
Matrix4::rotationY(Deg(25.0f))*
Matrix4::rotationX(Deg(17.0f))*
Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.transform(Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)}))
.rotateX(Math::Deg<T>{T(17.0)})
.rotateY(Math::Deg<T>{T(25.0)})
.rotateZ(-Math::Deg<T>{T(23.0)})
.rotate(Math::Quaternion<T>::rotation(Math::Deg<T>{T(36.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}))
.rotate(Math::Deg<T>{T(60.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>{
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})});
} {
Object3D o;
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))*
Matrix4::rotationY(Deg(25.0f))*
Matrix4::rotationZ(Deg(-23.0f))*
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())));
Object3D<T> o;
o.transform(Math::DualQuaternion<T>::translation({T(1.0), T(-0.3), T(2.3)}))
.rotateXLocal(Math::Deg<T>{T(17.0)})
.rotateYLocal(Math::Deg<T>{T(25.0)})
.rotateZLocal(-Math::Deg<T>{T(23.0)})
.rotateLocal(Math::Quaternion<T>::rotation(Math::Deg<T>{T(36.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}))
.rotateLocal(Math::Deg<T>{T(60.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>{
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()})});
}
}
void DualQuaternionTransformationTest::normalizeRotation() {
Object3D o;
o.setTransformation(DualQuaternion::rotation(Deg(17.0f), Vector3::xAxis()));
template<class T> void DualQuaternionTransformationTest::normalizeRotation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.setTransformation(Math::DualQuaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
o.normalizeRotation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
}
}}}}

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

@ -26,164 +26,199 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/Complex.h"
#include "Magnum/SceneGraph/MatrixTransformation2D.h"
#include "Magnum/SceneGraph/MatrixTransformation2D.hpp"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<MatrixTransformation2D> Object2D;
typedef Scene<MatrixTransformation2D> Scene2D;
struct MatrixTransformation2DTest: TestSuite::Tester {
explicit MatrixTransformation2DTest();
void fromMatrix();
void toMatrix();
void compose();
void inverted();
void setTransformation();
void resetTransformation();
void transform();
void translate();
void rotate();
void scale();
void reflect();
template<class T> void fromMatrix();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
template<class T> void setTransformation();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void translate();
template<class T> void rotate();
template<class T> void scale();
template<class T> void reflect();
};
MatrixTransformation2DTest::MatrixTransformation2DTest() {
addTests({&MatrixTransformation2DTest::fromMatrix,
&MatrixTransformation2DTest::toMatrix,
&MatrixTransformation2DTest::compose,
&MatrixTransformation2DTest::inverted,
&MatrixTransformation2DTest::setTransformation,
&MatrixTransformation2DTest::resetTransformation,
&MatrixTransformation2DTest::transform,
&MatrixTransformation2DTest::translate,
&MatrixTransformation2DTest::rotate,
&MatrixTransformation2DTest::scale,
&MatrixTransformation2DTest::reflect});
addTests<MatrixTransformation2DTest>({
&MatrixTransformation2DTest::fromMatrix<Float>,
&MatrixTransformation2DTest::fromMatrix<Double>,
&MatrixTransformation2DTest::toMatrix<Float>,
&MatrixTransformation2DTest::toMatrix<Double>,
&MatrixTransformation2DTest::compose<Float>,
&MatrixTransformation2DTest::compose<Double>,
&MatrixTransformation2DTest::inverted<Float>,
&MatrixTransformation2DTest::inverted<Double>,
&MatrixTransformation2DTest::setTransformation<Float>,
&MatrixTransformation2DTest::setTransformation<Double>,
&MatrixTransformation2DTest::resetTransformation<Float>,
&MatrixTransformation2DTest::resetTransformation<Double>,
&MatrixTransformation2DTest::transform<Float>,
&MatrixTransformation2DTest::transform<Double>,
&MatrixTransformation2DTest::translate<Float>,
&MatrixTransformation2DTest::translate<Double>,
&MatrixTransformation2DTest::rotate<Float>,
&MatrixTransformation2DTest::rotate<Double>,
&MatrixTransformation2DTest::scale<Float>,
&MatrixTransformation2DTest::scale<Double>,
&MatrixTransformation2DTest::reflect<Float>,
&MatrixTransformation2DTest::reflect<Double>});
}
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);
template<class T> using Object2D = Object<BasicMatrixTransformation2D<T>>;
template<class T> using Scene2D = Scene<BasicMatrixTransformation2D<T>>;
template<class T> void MatrixTransformation2DTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation2D<T>>::fromMatrix(m), m);
}
void MatrixTransformation2DTest::toMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<MatrixTransformation2D>::toMatrix(m), m);
template<class T> void MatrixTransformation2DTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation2D<T>>::toMatrix(m), m);
}
void MatrixTransformation2DTest::compose() {
Matrix3 parent = Matrix3::rotation(Deg(17.0f));
Matrix3 child = Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<MatrixTransformation2D>::compose(parent, child), parent*child);
template<class T> void MatrixTransformation2DTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> parent = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)});
Math::Matrix3<T> child = Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation2D<T>>::compose(parent, child), parent*child);
}
void MatrixTransformation2DTest::inverted() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<MatrixTransformation2D>::inverted(m)*m, Matrix3());
template<class T> void MatrixTransformation2DTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation2D<T>>::inverted(m)*m, Math::Matrix3<T>{});
}
void MatrixTransformation2DTest::setTransformation() {
template<class T> void MatrixTransformation2DTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
/* Dirty after setting transformation */
Object2D o;
Object2D<T> o;
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
/* Scene cannot be transformed */
Scene2D s;
Scene2D<T> s;
s.setClean();
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(Matrix3::rotation(Deg(17.0f)));
s.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix3());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix3<T>{});
}
void MatrixTransformation2DTest::resetTransformation() {
Object2D o;
o.rotate(Deg(17.0f));
CORRADE_VERIFY(o.transformationMatrix() != Matrix3());
template<class T> void MatrixTransformation2DTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.rotate(Math::Deg<T>{T(17.0)});
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix3<T>{});
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>{});
}
void MatrixTransformation2DTest::transform() {
template<class T> void MatrixTransformation2DTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.transform(Matrix3::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.transform(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.transformLocal(Matrix3::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.transformLocal(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
}
}
void MatrixTransformation2DTest::translate() {
template<class T> void MatrixTransformation2DTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.translate({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translate({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.translateLocal({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translateLocal({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
}
}
void MatrixTransformation2DTest::rotate() {
template<class T> void MatrixTransformation2DTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
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<T> o;
o.setTransformation(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}))
.rotate(Math::Complex<T>::rotation(Math::Deg<T>{T(7.0)}))
.rotate(Math::Deg<T>{T(10.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
} {
Object2D o;
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)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}))
.rotateLocal(Math::Complex<T>::rotation(Math::Deg<T>{T(7.0)}))
.rotateLocal(Math::Deg<T>{T(10.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
}
}
void MatrixTransformation2DTest::scale() {
template<class T> void MatrixTransformation2DTest::scale() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.scale({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::scaling({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.scale({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::scaling({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.scaleLocal({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::scaling({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.scaleLocal({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::scaling({T(1.0), T(-0.3)}));
}
}
void MatrixTransformation2DTest::reflect() {
template<class T> void MatrixTransformation2DTest::reflect() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.reflect(Vector2(-1.0f/Constants::sqrt2()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2()))*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.reflect(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::reflection(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.reflectLocal(Vector2(-1.0f/Constants::sqrt2()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2())));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.reflectLocal(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::reflection(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()}));
}
}

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

@ -26,180 +26,215 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/Quaternion.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.hpp"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<MatrixTransformation3D> Object3D;
typedef Scene<MatrixTransformation3D> Scene3D;
struct MatrixTransformation3DTest: TestSuite::Tester {
explicit MatrixTransformation3DTest();
void fromMatrix();
void toMatrix();
void compose();
void inverted();
void setTransformation();
void resetTransformation();
void transform();
void translate();
void rotate();
void scale();
void reflect();
template<class T> void fromMatrix();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
template<class T> void setTransformation();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void translate();
template<class T> void rotate();
template<class T> void scale();
template<class T> void reflect();
};
MatrixTransformation3DTest::MatrixTransformation3DTest() {
addTests({&MatrixTransformation3DTest::fromMatrix,
&MatrixTransformation3DTest::toMatrix,
&MatrixTransformation3DTest::compose,
&MatrixTransformation3DTest::inverted,
&MatrixTransformation3DTest::setTransformation,
&MatrixTransformation3DTest::resetTransformation,
&MatrixTransformation3DTest::transform,
&MatrixTransformation3DTest::translate,
&MatrixTransformation3DTest::rotate,
&MatrixTransformation3DTest::scale,
&MatrixTransformation3DTest::reflect});
addTests<MatrixTransformation3DTest>({
&MatrixTransformation3DTest::fromMatrix<Float>,
&MatrixTransformation3DTest::fromMatrix<Double>,
&MatrixTransformation3DTest::toMatrix<Float>,
&MatrixTransformation3DTest::toMatrix<Double>,
&MatrixTransformation3DTest::compose<Float>,
&MatrixTransformation3DTest::compose<Double>,
&MatrixTransformation3DTest::inverted<Float>,
&MatrixTransformation3DTest::inverted<Double>,
&MatrixTransformation3DTest::setTransformation<Float>,
&MatrixTransformation3DTest::setTransformation<Double>,
&MatrixTransformation3DTest::resetTransformation<Float>,
&MatrixTransformation3DTest::resetTransformation<Double>,
&MatrixTransformation3DTest::transform<Float>,
&MatrixTransformation3DTest::transform<Double>,
&MatrixTransformation3DTest::translate<Float>,
&MatrixTransformation3DTest::translate<Double>,
&MatrixTransformation3DTest::rotate<Float>,
&MatrixTransformation3DTest::rotate<Double>,
&MatrixTransformation3DTest::scale<Float>,
&MatrixTransformation3DTest::scale<Double>,
&MatrixTransformation3DTest::reflect<Float>,
&MatrixTransformation3DTest::reflect<Double>});
}
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);
template<class T> using Object3D = Object<BasicMatrixTransformation3D<T>>;
template<class T> using Scene3D = Scene<BasicMatrixTransformation3D<T>>;
template<class T> void MatrixTransformation3DTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::scaling({T(2.0), T(1.4), T(-2.1)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation3D<T>>::fromMatrix(m), m);
}
void MatrixTransformation3DTest::toMatrix() {
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>::toMatrix(m), m);
template<class T> void MatrixTransformation3DTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::scaling({T(2.0), T(1.4), T(-2.1)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation3D<T>>::toMatrix(m), m);
}
void MatrixTransformation3DTest::compose() {
Matrix4 parent = Matrix4::rotationX(Deg(17.0f));
Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<MatrixTransformation3D>::compose(parent, child), parent*child);
template<class T> void MatrixTransformation3DTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> parent = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)});
Math::Matrix4<T> child = Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation3D<T>>::compose(parent, child), parent*child);
}
void MatrixTransformation3DTest::inverted() {
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>::inverted(m)*m, Matrix4());
template<class T> void MatrixTransformation3DTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::scaling({T(2.0), T(1.4), T(-2.1)});
CORRADE_COMPARE(Implementation::Transformation<BasicMatrixTransformation3D<T>>::inverted(m)*m, Math::Matrix4<T>{});
}
void MatrixTransformation3DTest::setTransformation() {
template<class T> void MatrixTransformation3DTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
/* Dirty after setting transformation */
Object3D o;
Object3D<T> o;
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
/* Scene cannot be transformed */
Scene3D s;
Scene3D<T> s;
s.setClean();
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(Matrix4::rotationX(Deg(17.0f)));
s.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix4());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix4<T>());
}
void MatrixTransformation3DTest::resetTransformation() {
Object3D o;
o.rotateX(Deg(17.0f));
CORRADE_VERIFY(o.transformationMatrix() != Matrix4());
template<class T> void MatrixTransformation3DTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.rotateX(Math::Deg<T>{T(17.0)});
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix4<T>());
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>());
}
void MatrixTransformation3DTest::transform() {
template<class T> void MatrixTransformation3DTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.transform(Matrix4::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.transform(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.transformLocal(Matrix4::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.transformLocal(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
}
}
void MatrixTransformation3DTest::translate() {
template<class T> void MatrixTransformation3DTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.translate({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.translate({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.translateLocal({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.translateLocal({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
}
}
void MatrixTransformation3DTest::rotate() {
template<class T> void MatrixTransformation3DTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
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()});
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}))
.rotateX(Math::Deg<T>{T(17.0)})
.rotateY(Math::Deg<T>{T(25.0)})
.rotateZ(Math::Deg<T>{T(-23.0)})
.rotate(Math::Quaternion<T>::rotation(Math::Deg<T>{T(36.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}))
.rotate(Math::Deg<T>{T(60.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))*
Matrix4::rotationZ(Deg(-23.0f))*
Matrix4::rotationY(Deg(25.0f))*
Matrix4::rotationX(Deg(17.0f))*
Matrix4::translation({1.0f, -0.3f, 2.3f}));
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
} {
Object3D o;
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()});
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}))
.rotateXLocal(Math::Deg<T>{T(17.0)})
.rotateYLocal(Math::Deg<T>{T(25.0)})
.rotateZLocal(Math::Deg<T>{T(-23.0)})
.rotateLocal(Math::Quaternion<T>::rotation(Math::Deg<T>{T(36.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}))
.rotateLocal(Math::Deg<T>{T(60.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(Deg(17.0f))*
Matrix4::rotationY(Deg(25.0f))*
Matrix4::rotationZ(Deg(-23.0f))*
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())));
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}));
}
}
void MatrixTransformation3DTest::scale() {
template<class T> void MatrixTransformation3DTest::scale() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.scale({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::scaling({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.scale({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::scaling({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.scaleLocal({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::scaling({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.scaleLocal({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::scaling({T(1.0), T(-0.3), T(2.3)}));
}
}
void MatrixTransformation3DTest::reflect() {
template<class T> void MatrixTransformation3DTest::reflect() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.reflect(Vector3(-1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3()))*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.reflect(Math::Vector3<T>{T(-1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::reflection(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3()))*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.reflectLocal(Vector3(-1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3())));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.reflectLocal(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::reflection(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3())));
}
}

500
src/Magnum/SceneGraph/Test/ObjectTest.cpp

@ -28,7 +28,9 @@
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
#include "Magnum/SceneGraph/AbstractFeature.hpp"
#include "Magnum/SceneGraph/MatrixTransformation3D.hpp"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
@ -36,86 +38,108 @@ namespace Magnum { namespace SceneGraph { namespace Test { namespace {
struct ObjectTest: TestSuite::Tester {
explicit ObjectTest();
void addFeature();
void parenting();
void addChild();
void move();
void scene();
void setParentKeepTransformation();
void setParentKeepTransformationInvalid();
void absoluteTransformation();
void transformations();
void transformationsRelative();
void transformationsOrphan();
void transformationsDuplicate();
void setClean();
void setCleanListHierarchy();
void setCleanListBulk();
void rangeBasedForChildren();
void rangeBasedForFeatures();
template<class T> void addFeature();
template<class T> void parenting();
template<class T> void addChild();
template<class T> void move();
template<class T> void scene();
template<class T> void setParentKeepTransformation();
template<class T> void setParentKeepTransformationInvalid();
template<class T> void absoluteTransformation();
template<class T> void transformations();
template<class T> void transformationsRelative();
template<class T> void transformationsOrphan();
template<class T> void transformationsDuplicate();
template<class T> void setClean();
template<class T> void setCleanListHierarchy();
template<class T> void setCleanListBulk();
template<class T> void rangeBasedForChildren();
template<class T> void rangeBasedForFeatures();
};
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
ObjectTest::ObjectTest() {
addTests<ObjectTest>({
&ObjectTest::addFeature<Float>,
&ObjectTest::addFeature<Double>,
&ObjectTest::parenting<Float>,
&ObjectTest::parenting<Double>,
&ObjectTest::addChild<Float>,
&ObjectTest::addChild<Double>,
&ObjectTest::move<Float>,
&ObjectTest::move<Double>,
&ObjectTest::scene<Float>,
&ObjectTest::scene<Double>,
&ObjectTest::setParentKeepTransformation<Float>,
&ObjectTest::setParentKeepTransformation<Double>,
&ObjectTest::setParentKeepTransformationInvalid<Float>,
&ObjectTest::setParentKeepTransformationInvalid<Double>,
&ObjectTest::absoluteTransformation<Float>,
&ObjectTest::absoluteTransformation<Double>,
&ObjectTest::transformations<Float>,
&ObjectTest::transformations<Double>,
&ObjectTest::transformationsRelative<Float>,
&ObjectTest::transformationsRelative<Double>,
&ObjectTest::transformationsOrphan<Float>,
&ObjectTest::transformationsOrphan<Double>,
&ObjectTest::transformationsDuplicate<Float>,
&ObjectTest::transformationsDuplicate<Double>,
&ObjectTest::setClean<Float>,
&ObjectTest::setClean<Double>,
&ObjectTest::setCleanListHierarchy<Float>,
&ObjectTest::setCleanListHierarchy<Double>,
&ObjectTest::setCleanListBulk<Float>,
&ObjectTest::setCleanListBulk<Double>,
&ObjectTest::rangeBasedForChildren<Float>,
&ObjectTest::rangeBasedForChildren<Double>,
&ObjectTest::rangeBasedForFeatures<Float>,
&ObjectTest::rangeBasedForFeatures<Double>});
}
template<class T> using Object3D = SceneGraph::Object<SceneGraph::BasicMatrixTransformation3D<T>>;
template<class T> using Scene3D = SceneGraph::Scene<SceneGraph::BasicMatrixTransformation3D<T>>;
class CachingObject: public Object3D, AbstractFeature3D {
template<class T> class CachingObject: public Object3D<T>, AbstractBasicFeature3D<T> {
public:
CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature3D(*this) {
setCachedTransformations(CachedTransformation::Absolute);
CachingObject(Object3D<T>* parent = nullptr): Object3D<T>(parent), AbstractBasicFeature3D<T>{*this} {
this->setCachedTransformations(CachedTransformation::Absolute);
}
Matrix4 cleanedAbsoluteTransformation;
Math::Matrix4<T> cleanedAbsoluteTransformation;
protected:
void clean(const Matrix4& absoluteTransformation) override {
void clean(const Math::Matrix4<T>& absoluteTransformation) override {
cleanedAbsoluteTransformation = absoluteTransformation;
}
};
ObjectTest::ObjectTest() {
addTests({&ObjectTest::addFeature,
&ObjectTest::parenting,
&ObjectTest::addChild,
&ObjectTest::move,
&ObjectTest::scene,
&ObjectTest::setParentKeepTransformation,
&ObjectTest::setParentKeepTransformationInvalid,
&ObjectTest::absoluteTransformation,
&ObjectTest::transformations,
&ObjectTest::transformationsRelative,
&ObjectTest::transformationsOrphan,
&ObjectTest::transformationsDuplicate,
&ObjectTest::setClean,
&ObjectTest::setCleanListHierarchy,
&ObjectTest::setCleanListBulk,
&ObjectTest::rangeBasedForChildren,
&ObjectTest::rangeBasedForFeatures});
}
template<class T> void ObjectTest::addFeature() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
void ObjectTest::addFeature() {
class MyFeature: public AbstractFeature3D {
class MyFeature: public AbstractBasicFeature3D<T> {
public:
explicit MyFeature(AbstractObject3D& object, Int&, Containers::Pointer<int>&&): AbstractFeature3D{object} {}
explicit MyFeature(AbstractBasicObject3D<T>& object, Int&, Containers::Pointer<int>&&): AbstractBasicFeature3D<T>{object} {}
};
Object3D o;
Object3D<T> o;
CORRADE_VERIFY(o.features().isEmpty());
/* Test perfect forwarding as well */
int a = 0;
MyFeature& f = o.addFeature<MyFeature>(a, Containers::Pointer<int>{});
MyFeature& f = o.template addFeature<MyFeature>(a, Containers::Pointer<int>{});
CORRADE_VERIFY(!o.features().isEmpty());
CORRADE_COMPARE(&f.object(), &o);
}
void ObjectTest::parenting() {
Object3D root;
template<class T> void ObjectTest::parenting() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D* childOne = new Object3D(&root);
Object3D* childTwo = new Object3D(&root);
Object3D<T> root;
Object3D<T>* childOne = new Object3D<T>(&root);
Object3D<T>* childTwo = new Object3D<T>(&root);
CORRADE_VERIFY(childOne->parent() == &root);
CORRADE_VERIFY(childTwo->parent() == &root);
@ -141,26 +165,30 @@ void ObjectTest::parenting() {
CORRADE_VERIFY(childOne->children().isEmpty());
}
void ObjectTest::addChild() {
class MyObject: public Object3D {
template<class T> void ObjectTest::addChild() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class MyObject: public Object3D<T> {
public:
explicit MyObject(Int&, Containers::Pointer<int>&&, Object3D* parent = nullptr): Object3D{parent} {}
explicit MyObject(Int&, Containers::Pointer<int>&&, Object3D<T>* parent = nullptr): Object3D<T>{parent} {}
};
Object3D o;
Object3D<T> o;
CORRADE_VERIFY(o.children().isEmpty());
/* Test perfect forwarding as well */
int a = 0;
MyObject& p = o.addChild<MyObject>(a, Containers::Pointer<int>{});
MyObject& p = o.template addChild<MyObject>(a, Containers::Pointer<int>{});
CORRADE_VERIFY(!o.children().isEmpty());
CORRADE_COMPARE(p.parent(), &o);
}
void ObjectTest::move() {
Scene3D scene;
Object3D* a = new Object3D{&scene};
Object3D* b = new Object3D{&scene};
Object3D* c = new Object3D{&scene};
template<class T> void ObjectTest::move() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> scene;
Object3D<T>* a = new Object3D<T>{&scene};
Object3D<T>* b = new Object3D<T>{&scene};
Object3D<T>* c = new Object3D<T>{&scene};
CORRADE_COMPARE(a->nextSibling(), b);
CORRADE_COMPARE(b->nextSibling(), c);
@ -177,29 +205,33 @@ void ObjectTest::move() {
CORRADE_COMPARE(a->nextSibling(), nullptr);
}
void ObjectTest::scene() {
Scene3D scene;
template<class T> void ObjectTest::scene() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> scene;
CORRADE_VERIFY(scene.scene() == &scene);
Object3D* childOne = new Object3D(&scene);
Object3D* childTwo = new Object3D(childOne);
Object3D<T>* childOne = new Object3D<T>(&scene);
Object3D<T>* childTwo = new Object3D<T>(childOne);
Object3D orphan;
Object3D* childOfOrphan = new Object3D(&orphan);
Object3D<T> orphan;
Object3D<T>* childOfOrphan = new Object3D<T>(&orphan);
CORRADE_VERIFY(childTwo->scene() == &scene);
CORRADE_VERIFY(childOfOrphan->scene() == nullptr);
}
void ObjectTest::setParentKeepTransformation() {
Object3D root;
root.rotateZ(Deg(35.0f));
template<class T> void ObjectTest::setParentKeepTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> root;
root.rotateZ(Math::Deg<T>{T(35.0)});
Object3D* childOne = new Object3D(&root);
Object3D* childTwo = new Object3D(&root);
Object3D<T>* childOne = new Object3D<T>(&root);
Object3D<T>* childTwo = new Object3D<T>(&root);
childOne->translate(Vector3::xAxis(2.0f));
childTwo->rotateY(Deg(90.0f));
childOne->translate(Math::Vector3<T>::xAxis(T(2.0)));
childTwo->rotateY(Math::Deg<T>{90.0});
/* Reparent to another and keep absolute transformation */
auto transformation = childOne->absoluteTransformation();
@ -208,116 +240,126 @@ void ObjectTest::setParentKeepTransformation() {
CORRADE_COMPARE(childOne->absoluteTransformation(), transformation);
}
void ObjectTest::setParentKeepTransformationInvalid() {
template<class T> void ObjectTest::setParentKeepTransformationInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Object3D root;
root.rotateZ(Deg(35.0f));
Object3D<T> root;
root.rotateZ(Math::Deg<T>{35.0});
Object3D* child = new Object3D(&root);
Object3D<T>* child = new Object3D<T>(&root);
/* Old parent and new parent must share the same scene */
std::ostringstream o;
Error redirectError{&o};
Scene3D scene;
Scene3D<T> scene;
child->setParentKeepTransformation(&scene);
CORRADE_COMPARE(o.str(), "SceneGraph::Object::setParentKeepTransformation(): both parents must be in the same scene\n");
}
void ObjectTest::absoluteTransformation() {
Scene3D s;
template<class T> void ObjectTest::absoluteTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> s;
/* Proper transformation composition */
Object3D o(&s);
o.translate(Vector3::xAxis(2.0f));
CORRADE_COMPARE(o.transformation(), Matrix4::translation(Vector3::xAxis(2.0f)));
Object3D<T> o(&s);
o.translate(Math::Vector3<T>::xAxis(T(2.0)));
CORRADE_COMPARE(o.transformation(), Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(2.0))));
CORRADE_COMPARE(o.transformation(), o.transformationMatrix());
Object3D o2(&o);
o2.rotateY(Deg(90.0f));
Object3D<T> o2(&o);
o2.rotateY(Math::Deg<T>{90.0});
CORRADE_COMPARE(o2.absoluteTransformation(),
Matrix4::translation(Vector3::xAxis(2.0f))*Matrix4::rotationY(Deg(90.0f)));
Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(2.0)))*Math::Matrix4<T>::rotationY(Math::Deg<T>{90.0}));
CORRADE_COMPARE(o2.absoluteTransformation(), o2.absoluteTransformationMatrix());
/* Transformation of root object */
Object3D o3;
o3.translate({1.0f, 2.0f, 3.0f});
CORRADE_COMPARE(o3.absoluteTransformation(), Matrix4::translation({1.0f, 2.0f, 3.0f}));
Object3D<T> o3;
o3.translate({T(1.0), T(2.0), T(3.0)});
CORRADE_COMPARE(o3.absoluteTransformation(), Math::Matrix4<T>::translation({T(1.0), T(2.0), T(3.0)}));
}
void ObjectTest::transformations() {
Scene3D s;
template<class T> void ObjectTest::transformations() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> s;
Matrix4 initial = Matrix4::rotationX(Deg(90.0f)).inverted();
Math::Matrix4<T> initial = Math::Matrix4<T>::rotationX(Math::Deg<T>{90.0}).inverted();
/* Empty list */
CORRADE_COMPARE(s.transformations({}, initial), std::vector<Matrix4>());
CORRADE_COMPARE(s.transformations({}, initial), std::vector<Math::Matrix4<T>>{});
/* Scene alone */
CORRADE_COMPARE(s.transformations({s}, initial), std::vector<Matrix4>{initial});
CORRADE_COMPARE(s.transformations({s}, initial), std::vector<Math::Matrix4<T>>{initial});
/* One object */
Object3D first(&s);
first.rotateZ(Deg(30.0f));
Object3D second(&first);
second.scale(Vector3(0.5f));
CORRADE_COMPARE(s.transformations({second}, initial), std::vector<Matrix4>{
initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f))
Object3D<T> first(&s);
first.rotateZ(Math::Deg<T>{30.0});
Object3D<T> second(&first);
second.scale(Math::Vector3<T>(T(0.5)));
CORRADE_COMPARE(s.transformations({second}, initial), std::vector<Math::Matrix4<T>>{
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(0.5)))
});
/* One object and scene */
CORRADE_COMPARE(s.transformations({second, s}, initial), (std::vector<Matrix4>{
initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)),
CORRADE_COMPARE(s.transformations({second, s}, initial), (std::vector<Math::Matrix4<T>>{
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(0.5))),
initial
}));
/* Two objects with foreign joint */
Object3D third(&first);
third.translate(Vector3::xAxis(5.0f));
CORRADE_COMPARE(s.transformations({second, third}, initial), (std::vector<Matrix4>{
initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)),
initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::translation(Vector3::xAxis(5.0f)),
Object3D<T> third(&first);
third.translate(Math::Vector3<T>::xAxis(T(5.0)));
CORRADE_COMPARE(s.transformations({second, third}, initial), (std::vector<Math::Matrix4<T>>{
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(0.5))),
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(5.0))),
}));
/* Three objects with joint as one of them */
CORRADE_COMPARE(s.transformations({second, third, first}, initial), (std::vector<Matrix4>{
initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)),
initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::translation(Vector3::xAxis(5.0f)),
initial*Matrix4::rotationZ(Deg(30.0f)),
CORRADE_COMPARE(s.transformations({second, third, first}, initial), (std::vector<Math::Matrix4<T>>{
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(0.5))),
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(5.0))),
initial*Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0}),
}));
}
void ObjectTest::transformationsRelative() {
template<class T> void ObjectTest::transformationsRelative() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
CORRADE_SKIP("Transformations not relative to scene are not implemented yet.");
Scene3D s;
Object3D first(&s);
first.rotateZ(Deg(30.0f));
Object3D second(&first);
second.scale(Vector3(0.5f));
Object3D third(&first);
third.translate(Vector3::xAxis(5.0f));
Scene3D<T> s;
Object3D<T> first(&s);
first.rotateZ(Math::Deg<T>{30.0});
Object3D<T> second(&first);
second.scale(Math::Vector3<T>(T(0.5)));
Object3D<T> third(&first);
third.translate(Math::Vector3<T>::xAxis(T(5.0)));
/* Transformation relative to another object */
CORRADE_COMPARE(second.transformations({third}), std::vector<Matrix4>{
Matrix4::scaling(Vector3(0.5f)).inverted()*Matrix4::translation(Vector3::xAxis(5.0f))
CORRADE_COMPARE(second.transformations({third}), std::vector<Math::Matrix4<T>>{
Math::Matrix4<T>::scaling(Math::Vector3<T>(T(0.5))).inverted()*Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(5.0)))
});
/* Transformation relative to another object, not part of any scene (but should work) */
Object3D orphanParent1;
orphanParent1.rotate(Deg(31.0f), Vector3(1.0f).normalized());
Object3D orphanParent(&orphanParent1);
Object3D orphan1(&orphanParent);
orphan1.scale(Vector3::xScale(3.0f));
Object3D orphan2(&orphanParent);
orphan2.translate(Vector3::zAxis(5.0f));
CORRADE_COMPARE(orphan1.transformations({orphan2}), std::vector<Matrix4>{
Matrix4::scaling(Vector3::xScale(3.0f)).inverted()*Matrix4::translation(Vector3::zAxis(5.0f))
Object3D<T> orphanParent1;
orphanParent1.rotate(Math::Deg<T>{31.0}, Math::Vector3<T>(T(1.0)).normalized());
Object3D<T> orphanParent(&orphanParent1);
Object3D<T> orphan1(&orphanParent);
orphan1.scale(Math::Vector3<T>::xScale(T(3.0)));
Object3D<T> orphan2(&orphanParent);
orphan2.translate(Math::Vector3<T>::zAxis(T(5.0)));
CORRADE_COMPARE(orphan1.transformations({orphan2}), std::vector<Math::Matrix4<T>>{
Math::Matrix4<T>::scaling(Math::Vector3<T>::xScale(T(3.0))).inverted()*Math::Matrix4<T>::translation(Math::Vector3<T>::zAxis(T(5.0)))
});
}
void ObjectTest::transformationsOrphan() {
template<class T> void ObjectTest::transformationsOrphan() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
@ -326,68 +368,72 @@ void ObjectTest::transformationsOrphan() {
Error redirectError{&o};
/* Transformation of objects not part of the same scene */
Scene3D s;
Object3D orphan;
CORRADE_COMPARE(s.transformations({orphan}), std::vector<Matrix4>());
Scene3D<T> s;
Object3D<T> orphan;
CORRADE_COMPARE(s.transformations({orphan}), std::vector<Math::Matrix4<T>>{});
CORRADE_COMPARE(o.str(), "SceneGraph::Object::transformations(): the objects are not part of the same tree\n");
}
void ObjectTest::transformationsDuplicate() {
Scene3D s;
Object3D first(&s);
first.rotateZ(Deg(30.0f));
Object3D second(&first);
second.scale(Vector3(0.5f));
Object3D third(&first);
third.translate(Vector3::xAxis(5.0f));
Matrix4 firstExpected = Matrix4::rotationZ(Deg(30.0f));
Matrix4 secondExpected = Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f));
Matrix4 thirdExpected = Matrix4::rotationZ(Deg(30.0f))*Matrix4::translation(Vector3::xAxis(5.0f));
CORRADE_COMPARE(s.transformations({second, third, second, first, third}), (std::vector<Matrix4>{
template<class T> void ObjectTest::transformationsDuplicate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> s;
Object3D<T> first(&s);
first.rotateZ(Math::Deg<T>{T(30.0)});
Object3D<T> second(&first);
second.scale(Math::Vector3<T>(T(0.5)));
Object3D<T> third(&first);
third.translate(Math::Vector3<T>::xAxis(T(5.0)));
Math::Matrix4<T> firstExpected = Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0});
Math::Matrix4<T> secondExpected = Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(0.5)));
Math::Matrix4<T> thirdExpected = Math::Matrix4<T>::rotationZ(Math::Deg<T>{30.0})*Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(5.0)));
CORRADE_COMPARE(s.transformations({second, third, second, first, third}), (std::vector<Math::Matrix4<T>>{
secondExpected, thirdExpected, secondExpected, firstExpected, thirdExpected
}));
}
void ObjectTest::setClean() {
Scene3D scene;
template<class T> void ObjectTest::setClean() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
class CachingFeature: public AbstractFeature3D {
Scene3D<T> scene;
class CachingFeature: public AbstractBasicFeature3D<T> {
public:
explicit CachingFeature(AbstractObject3D& object): AbstractFeature3D{object} {
setCachedTransformations(CachedTransformation::Absolute);
explicit CachingFeature(AbstractBasicObject3D<T>& object): AbstractBasicFeature3D<T>{object} {
this->setCachedTransformations(CachedTransformation::Absolute);
}
Matrix4 cleanedAbsoluteTransformation;
Math::Matrix4<T> cleanedAbsoluteTransformation;
void clean(const Matrix4& absoluteTransformation) override {
void clean(const Math::Matrix4<T>& absoluteTransformation) override {
cleanedAbsoluteTransformation = absoluteTransformation;
}
};
class CachingInvertedFeature: public AbstractFeature3D {
class CachingInvertedFeature: public AbstractBasicFeature3D<T> {
public:
explicit CachingInvertedFeature(AbstractObject3D& object): AbstractFeature3D{object} {
setCachedTransformations(CachedTransformation::InvertedAbsolute);
explicit CachingInvertedFeature(AbstractBasicObject3D<T>& object): AbstractBasicFeature3D<T>{object} {
this->setCachedTransformations(CachedTransformation::InvertedAbsolute);
}
Matrix4 cleanedInvertedAbsoluteTransformation;
Math::Matrix4<T> cleanedInvertedAbsoluteTransformation;
void cleanInverted(const Matrix4& invertedAbsoluteTransformation) override {
void cleanInverted(const Math::Matrix4<T>& invertedAbsoluteTransformation) override {
cleanedInvertedAbsoluteTransformation = invertedAbsoluteTransformation;
}
};
CachingObject* childOne = new CachingObject(&scene);
childOne->scale(Vector3(2.0f));
CachingObject<T>* childOne = new CachingObject<T>{&scene};
childOne->scale(Math::Vector3<T>(T(2.0)));
CachingObject* childTwo = new CachingObject(childOne);
childTwo->translate(Vector3::xAxis(1.0f));
CachingObject<T>* childTwo = new CachingObject<T>{childOne};
childTwo->translate(Math::Vector3<T>::xAxis(T(1.0)));
CachingFeature* childTwoFeature = new CachingFeature(*childTwo);
CachingInvertedFeature* childTwoFeature2 = new CachingInvertedFeature(*childTwo);
CachingObject* childThree = new CachingObject(childTwo);
childThree->rotate(Deg(90.0f), Vector3::yAxis());
CachingObject<T>* childThree = new CachingObject<T>{childTwo};
childThree->rotate(Math::Deg<T>{90.0}, Math::Vector3<T>::yAxis());
/* Object is dirty at the beginning */
CORRADE_VERIFY(scene.isDirty());
@ -416,16 +462,16 @@ void ObjectTest::setClean() {
CORRADE_VERIFY(childThree->isDirty());
/* If the object itself is already clean, it shouldn't clean it again */
childOne->cleanedAbsoluteTransformation = Matrix4{Math::ZeroInit};
childOne->cleanedAbsoluteTransformation = Math::Matrix4<T>{Math::ZeroInit};
CORRADE_VERIFY(!childOne->isDirty());
childOne->setClean();
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Matrix4{Math::ZeroInit});
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Math::Matrix4<T>{Math::ZeroInit});
/* If any object in the hierarchy is already clean, it shouldn't clean it again */
CORRADE_VERIFY(!childOne->isDirty());
CORRADE_VERIFY(childTwo->isDirty());
childTwo->setClean();
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Matrix4{Math::ZeroInit});
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Math::Matrix4<T>{Math::ZeroInit});
/* Remove object from tree => make it and its children dirty */
childThree->setClean();
@ -441,40 +487,42 @@ void ObjectTest::setClean() {
/* Set object transformation => make it and its children dirty (but not parents) */
childThree->setClean();
childTwo->setTransformation(Matrix4::translation(Vector3::xAxis(1.0f)));
childTwo->setTransformation(Math::Matrix4<T>::translation(Math::Vector3<T>::xAxis(T(1.0))));
CORRADE_VERIFY(!scene.isDirty());
CORRADE_VERIFY(childTwo->isDirty());
CORRADE_VERIFY(childThree->isDirty());
}
void ObjectTest::setCleanListHierarchy() {
Scene3D scene;
template<class T> void ObjectTest::setCleanListHierarchy() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> scene;
class CachingFeature: public AbstractFeature3D {
class CachingFeature: public AbstractBasicFeature3D<T> {
public:
explicit CachingFeature(AbstractObject3D& object): AbstractFeature3D{object} {
setCachedTransformations(CachedTransformation::Absolute);
explicit CachingFeature(AbstractBasicObject3D<T>& object): AbstractBasicFeature3D<T>{object} {
this->setCachedTransformations(CachedTransformation::Absolute);
}
Matrix4 cleanedAbsoluteTransformation;
Math::Matrix4<T> cleanedAbsoluteTransformation;
void clean(const Matrix4& absoluteTransformation) override {
void clean(const Math::Matrix4<T>& absoluteTransformation) override {
cleanedAbsoluteTransformation = absoluteTransformation;
}
};
CachingObject* childOne = new CachingObject(&scene);
childOne->scale(Vector3(2.0f));
CachingObject<T>* childOne = new CachingObject<T>{&scene};
childOne->scale(Math::Vector3<T>(T(2.0)));
CachingObject* childTwo = new CachingObject(childOne);
childTwo->translate(Vector3::xAxis(1.0f));
CachingObject<T>* childTwo = new CachingObject<T>{childOne};
childTwo->translate(Math::Vector3<T>::xAxis(T(1.0)));
CachingFeature* childTwoFeature = new CachingFeature(*childTwo);
CachingObject* childThree = new CachingObject(childTwo);
childThree->rotate(Deg(90.0f), Vector3::yAxis());
CachingObject<T>* childThree = new CachingObject<T>{childTwo};
childThree->rotate(Math::Deg<T>{90.0}, Math::Vector3<T>::yAxis());
/* Clean the object and all its dirty parents (but not children) */
Scene3D::setClean({*childTwo});
Scene3D<T>::setClean({*childTwo});
CORRADE_VERIFY(!scene.isDirty());
CORRADE_VERIFY(!childOne->isDirty());
CORRADE_VERIFY(!childTwo->isDirty());
@ -486,31 +534,33 @@ void ObjectTest::setCleanListHierarchy() {
CORRADE_COMPARE(childTwoFeature->cleanedAbsoluteTransformation, childTwo->absoluteTransformationMatrix());
/* If the object itself is already clean, it shouldn't clean it again */
childOne->cleanedAbsoluteTransformation = Matrix4{Math::ZeroInit};
childOne->cleanedAbsoluteTransformation = Math::Matrix4<T>{Math::ZeroInit};
CORRADE_VERIFY(!childOne->isDirty());
Scene3D::setClean({*childOne});
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Matrix4{Math::ZeroInit});
Scene3D<T>::setClean({*childOne});
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Math::Matrix4<T>{Math::ZeroInit});
/* If any object in the hierarchy is already clean, it shouldn't clean it again */
CORRADE_VERIFY(!childOne->isDirty());
childTwo->setDirty();
Scene3D::setClean({*childTwo});
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Matrix4{Math::ZeroInit});
Scene3D<T>::setClean({*childTwo});
CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Math::Matrix4<T>{Math::ZeroInit});
}
void ObjectTest::setCleanListBulk() {
template<class T> void ObjectTest::setCleanListBulk() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
/* Verify it doesn't crash when passed empty list */
Object3D::setClean({});
Object3D<T>::setClean({});
Scene3D scene;
Object3D a(&scene);
Object3D b(&scene);
Scene3D<T> scene;
Object3D<T> a(&scene);
Object3D<T> b(&scene);
b.setClean();
Object3D c(&scene);
c.translate(Vector3::zAxis(3.0f));
CachingObject d(&c);
d.scale(Vector3(-2.0f));
Object3D e(&scene);
Object3D<T> c(&scene);
c.translate(Math::Vector3<T>::zAxis(T(3.0)));
CachingObject<T> d(&c);
d.scale(Math::Vector3<T>(T(-2.0)));
Object3D<T> e(&scene);
/* All objects should be cleaned */
CORRADE_VERIFY(a.isDirty());
@ -518,7 +568,7 @@ void ObjectTest::setCleanListBulk() {
CORRADE_VERIFY(c.isDirty());
CORRADE_VERIFY(d.isDirty());
CORRADE_VERIFY(e.isDirty());
Object3D::setClean({a, b, c, d, e});
Object3D<T>::setClean({a, b, c, d, e});
CORRADE_VERIFY(!a.isDirty());
CORRADE_VERIFY(!b.isDirty());
CORRADE_VERIFY(!c.isDirty());
@ -526,33 +576,37 @@ void ObjectTest::setCleanListBulk() {
CORRADE_VERIFY(!e.isDirty());
/* Verify that right transformation was passed */
CORRADE_COMPARE(d.cleanedAbsoluteTransformation, Matrix4::translation(Vector3::zAxis(3.0f))*Matrix4::scaling(Vector3(-2.0f)));
CORRADE_COMPARE(d.cleanedAbsoluteTransformation, Math::Matrix4<T>::translation(Math::Vector3<T>::zAxis(T(3.0)))*Math::Matrix4<T>::scaling(Math::Vector3<T>(T(-2.0))));
}
void ObjectTest::rangeBasedForChildren() {
Scene3D scene;
Object3D a(&scene);
Object3D b(&scene);
Object3D c(&scene);
template<class T> void ObjectTest::rangeBasedForChildren() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
std::vector<Object3D*> objects;
Scene3D<T> scene;
Object3D<T> a{&scene};
Object3D<T> b{&scene};
Object3D<T> c{&scene};
std::vector<Object3D<T>*> objects;
for(auto&& i: scene.children()) objects.push_back(&i);
CORRADE_COMPARE(objects, (std::vector<Object3D*>{&a, &b, &c}));
CORRADE_COMPARE(objects, (std::vector<Object3D<T>*>{&a, &b, &c}));
}
void ObjectTest::rangeBasedForFeatures() {
struct Feature: AbstractFeature3D {
explicit Feature(AbstractObject3D& object): AbstractFeature3D{object} {}
template<class T> void ObjectTest::rangeBasedForFeatures() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
struct Feature: AbstractBasicFeature3D<T> {
explicit Feature(AbstractBasicObject3D<T>& object): AbstractBasicFeature3D<T>{object} {}
};
Object3D object;
Feature a(object);
Feature b(object);
Feature c(object);
Object3D<T> object;
Feature a{object};
Feature b{object};
Feature c{object};
std::vector<AbstractFeature3D*> features;
std::vector<AbstractBasicFeature3D<T>*> features;
for(auto&& i: object.features()) features.push_back(&i);
CORRADE_COMPARE(features, (std::vector<AbstractFeature3D*>{&a, &b, &c}));
CORRADE_COMPARE(features, (std::vector<AbstractBasicFeature3D<T>*>{&a, &b, &c}));
}
}}}}

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

@ -28,202 +28,246 @@
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/Math/Complex.h"
#include "Magnum/SceneGraph/RigidMatrixTransformation2D.h"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/RigidMatrixTransformation2D.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<RigidMatrixTransformation2D> Object2D;
typedef Scene<RigidMatrixTransformation2D> Scene2D;
struct RigidMatrixTransformation2DTest: TestSuite::Tester {
explicit RigidMatrixTransformation2DTest();
void fromMatrix();
void fromMatrixInvalid();
void toMatrix();
void compose();
void inverted();
void setTransformation();
void setTransformationInvalid();
void resetTransformation();
void transform();
void transformInvalid();
void translate();
void rotate();
void reflect();
void normalizeRotation();
template<class T> void fromMatrix();
template<class T> void fromMatrixInvalid();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
template<class T> void setTransformation();
template<class T> void setTransformationInvalid();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void transformInvalid();
template<class T> void translate();
template<class T> void rotate();
template<class T> void reflect();
template<class T> void normalizeRotation();
};
RigidMatrixTransformation2DTest::RigidMatrixTransformation2DTest() {
addTests({&RigidMatrixTransformation2DTest::fromMatrix,
&RigidMatrixTransformation2DTest::fromMatrixInvalid,
&RigidMatrixTransformation2DTest::toMatrix,
&RigidMatrixTransformation2DTest::compose,
&RigidMatrixTransformation2DTest::inverted,
&RigidMatrixTransformation2DTest::setTransformation,
&RigidMatrixTransformation2DTest::setTransformationInvalid,
&RigidMatrixTransformation2DTest::resetTransformation,
&RigidMatrixTransformation2DTest::transform,
&RigidMatrixTransformation2DTest::transformInvalid,
&RigidMatrixTransformation2DTest::translate,
&RigidMatrixTransformation2DTest::rotate,
&RigidMatrixTransformation2DTest::reflect,
&RigidMatrixTransformation2DTest::normalizeRotation});
addTests<RigidMatrixTransformation2DTest>({
&RigidMatrixTransformation2DTest::fromMatrix<Float>,
&RigidMatrixTransformation2DTest::fromMatrix<Double>,
&RigidMatrixTransformation2DTest::fromMatrixInvalid<Float>,
&RigidMatrixTransformation2DTest::fromMatrixInvalid<Double>,
&RigidMatrixTransformation2DTest::toMatrix<Float>,
&RigidMatrixTransformation2DTest::toMatrix<Double>,
&RigidMatrixTransformation2DTest::compose<Float>,
&RigidMatrixTransformation2DTest::compose<Double>,
&RigidMatrixTransformation2DTest::inverted<Float>,
&RigidMatrixTransformation2DTest::inverted<Double>,
&RigidMatrixTransformation2DTest::setTransformation<Float>,
&RigidMatrixTransformation2DTest::setTransformation<Double>,
&RigidMatrixTransformation2DTest::setTransformationInvalid<Float>,
&RigidMatrixTransformation2DTest::setTransformationInvalid<Double>,
&RigidMatrixTransformation2DTest::resetTransformation<Float>,
&RigidMatrixTransformation2DTest::resetTransformation<Double>,
&RigidMatrixTransformation2DTest::transform<Float>,
&RigidMatrixTransformation2DTest::transform<Double>,
&RigidMatrixTransformation2DTest::transformInvalid<Float>,
&RigidMatrixTransformation2DTest::transformInvalid<Double>,
&RigidMatrixTransformation2DTest::translate<Float>,
&RigidMatrixTransformation2DTest::translate<Double>,
&RigidMatrixTransformation2DTest::rotate<Float>,
&RigidMatrixTransformation2DTest::rotate<Double>,
&RigidMatrixTransformation2DTest::reflect<Float>,
&RigidMatrixTransformation2DTest::reflect<Double>,
&RigidMatrixTransformation2DTest::normalizeRotation<Float>,
&RigidMatrixTransformation2DTest::normalizeRotation<Double>});
}
using namespace Math::Literals;
void RigidMatrixTransformation2DTest::fromMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation2D>::fromMatrix(m), m);
template<class T> using Object2D = Object<BasicRigidMatrixTransformation2D<T>>;
template<class T> using Scene2D = Scene<BasicRigidMatrixTransformation2D<T>>;
template<class T> void RigidMatrixTransformation2DTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation2D<T>>::fromMatrix(m), m);
}
void RigidMatrixTransformation2DTest::fromMatrixInvalid() {
template<class T> void RigidMatrixTransformation2DTest::fromMatrixInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream out;
Error redirectError{&out};
Implementation::Transformation<RigidMatrixTransformation2D>::fromMatrix(Matrix3::scaling(Vector2(4.0f)));
Implementation::Transformation<BasicRigidMatrixTransformation2D<T>>::fromMatrix(Math::Matrix3<T>::scaling(Math::Vector2<T>{T(4.0)}));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation2D: the matrix doesn't represent rigid transformation\n");
}
void RigidMatrixTransformation2DTest::toMatrix() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation2D>::toMatrix(m), m);
template<class T> void RigidMatrixTransformation2DTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation2D<T>>::toMatrix(m), m);
}
void RigidMatrixTransformation2DTest::compose() {
Matrix3 parent = Matrix3::rotation(Deg(17.0f));
Matrix3 child = Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation2D>::compose(parent, child), parent*child);
template<class T> void RigidMatrixTransformation2DTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> parent = Math::Matrix3<T>::rotation(Math::Deg<T>(T(17.0)));
Math::Matrix3<T> child = Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation2D<T>>::compose(parent, child), parent*child);
}
void RigidMatrixTransformation2DTest::inverted() {
Matrix3 m = Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation2D>::inverted(m)*m, Matrix3());
template<class T> void RigidMatrixTransformation2DTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation2D<T>>::inverted(m)*m, Math::Matrix3<T>{});
}
void RigidMatrixTransformation2DTest::setTransformation() {
Object2D o;
template<class T> void RigidMatrixTransformation2DTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
/* Dirty after setting transformation */
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
/* Scene cannot be transformed */
Scene2D s;
Scene2D<T> s;
s.setClean();
s.setTransformation(Matrix3::rotation(Deg(17.0f)));
s.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix3());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix3<T>());
}
void RigidMatrixTransformation2DTest::setTransformationInvalid() {
template<class T> void RigidMatrixTransformation2DTest::setTransformationInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Object2D o;
Object2D<T> o;
/* Can't transform with non-rigid transformation */
std::ostringstream out;
Error redirectError{&out};
o.setTransformation(Matrix3::scaling(Vector2(3.0f)));
o.setTransformation(Math::Matrix3<T>::scaling(Math::Vector2<T>{T(3.0)}));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation\n");
}
void RigidMatrixTransformation2DTest::resetTransformation() {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
CORRADE_VERIFY(o.transformationMatrix() != Matrix3());
template<class T> void RigidMatrixTransformation2DTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix3<T>());
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>());
}
void RigidMatrixTransformation2DTest::transform() {
template<class T> void RigidMatrixTransformation2DTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.transform(Matrix3::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.transform(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.transformLocal(Matrix3::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.transformLocal(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
}
}
void RigidMatrixTransformation2DTest::transformInvalid() {
template<class T> void RigidMatrixTransformation2DTest::transformInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
/* Can't transform with non-rigid transformation */
Object2D o;
Object2D<T> o;
std::ostringstream out;
Error redirectError{&out};
o.transform(Matrix3::scaling(Vector2(3.0f)));
o.transform(Math::Matrix3<T>::scaling(Math::Vector2<T>{T(3.0)}));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation\n");
}
void RigidMatrixTransformation2DTest::translate() {
template<class T> void RigidMatrixTransformation2DTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.translate({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translate({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.translateLocal({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translateLocal({T(1.0), T(-0.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
}
}
void RigidMatrixTransformation2DTest::rotate() {
template<class T> void RigidMatrixTransformation2DTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
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<T> o;
o.setTransformation(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}))
.rotate(Math::Complex<T>::rotation(Math::Deg<T>{T(7.0)}))
.rotate(Math::Deg<T>{T(10.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
} {
Object2D o;
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)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}))
.rotateLocal(Math::Complex<T>::rotation(Math::Deg<T>{T(7.0)}))
.rotateLocal(Math::Deg<T>{T(10.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
}
}
void RigidMatrixTransformation2DTest::reflect() {
template<class T> void RigidMatrixTransformation2DTest::reflect() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.reflect(Vector2(-1.0f/Constants::sqrt2()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2()))*Matrix3::rotation(Deg(17.0f)));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.reflect(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::reflection(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()})*Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.reflectLocal(Vector2(-1.0f/Constants::sqrt2()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2())));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.reflectLocal(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::reflection(Math::Vector2<T>{T(-1.0)/Math::Constants<T>::sqrt2()}));
}
}
void RigidMatrixTransformation2DTest::normalizeRotation() {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
template<class T> void RigidMatrixTransformation2DTest::normalizeRotation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.normalizeRotation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
}
}}}}

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

@ -28,219 +28,263 @@
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/Math/Quaternion.h"
#include "Magnum/SceneGraph/RigidMatrixTransformation3D.h"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/RigidMatrixTransformation3D.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<RigidMatrixTransformation3D> Object3D;
typedef Scene<RigidMatrixTransformation3D> Scene3D;
struct RigidMatrixTransformation3DTest: TestSuite::Tester {
explicit RigidMatrixTransformation3DTest();
void fromMatrix();
void fromMatrixInvalid();
void toMatrix();
void compose();
void inverted();
void setTransformation();
void setTransformationInvalid();
void resetTransformation();
void transform();
void transformInvalid();
void translate();
void rotate();
void reflect();
void normalizeRotation();
template<class T> void fromMatrix();
template<class T> void fromMatrixInvalid();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
template<class T> void setTransformation();
template<class T> void setTransformationInvalid();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void transformInvalid();
template<class T> void translate();
template<class T> void rotate();
template<class T> void reflect();
template<class T> void normalizeRotation();
};
RigidMatrixTransformation3DTest::RigidMatrixTransformation3DTest() {
addTests({&RigidMatrixTransformation3DTest::fromMatrix,
&RigidMatrixTransformation3DTest::fromMatrixInvalid,
&RigidMatrixTransformation3DTest::toMatrix,
&RigidMatrixTransformation3DTest::compose,
&RigidMatrixTransformation3DTest::inverted,
&RigidMatrixTransformation3DTest::setTransformation,
&RigidMatrixTransformation3DTest::setTransformationInvalid,
&RigidMatrixTransformation3DTest::resetTransformation,
&RigidMatrixTransformation3DTest::transform,
&RigidMatrixTransformation3DTest::transformInvalid,
&RigidMatrixTransformation3DTest::translate,
&RigidMatrixTransformation3DTest::rotate,
&RigidMatrixTransformation3DTest::reflect,
&RigidMatrixTransformation3DTest::normalizeRotation});
addTests<RigidMatrixTransformation3DTest>({
&RigidMatrixTransformation3DTest::fromMatrix<Float>,
&RigidMatrixTransformation3DTest::fromMatrix<Double>,
&RigidMatrixTransformation3DTest::fromMatrixInvalid<Float>,
&RigidMatrixTransformation3DTest::fromMatrixInvalid<Double>,
&RigidMatrixTransformation3DTest::toMatrix<Float>,
&RigidMatrixTransformation3DTest::toMatrix<Double>,
&RigidMatrixTransformation3DTest::compose<Float>,
&RigidMatrixTransformation3DTest::compose<Double>,
&RigidMatrixTransformation3DTest::inverted<Float>,
&RigidMatrixTransformation3DTest::inverted<Double>,
&RigidMatrixTransformation3DTest::setTransformation<Float>,
&RigidMatrixTransformation3DTest::setTransformation<Double>,
&RigidMatrixTransformation3DTest::setTransformationInvalid<Float>,
&RigidMatrixTransformation3DTest::setTransformationInvalid<Double>,
&RigidMatrixTransformation3DTest::resetTransformation<Float>,
&RigidMatrixTransformation3DTest::resetTransformation<Double>,
&RigidMatrixTransformation3DTest::transform<Float>,
&RigidMatrixTransformation3DTest::transform<Double>,
&RigidMatrixTransformation3DTest::transformInvalid<Float>,
&RigidMatrixTransformation3DTest::transformInvalid<Double>,
&RigidMatrixTransformation3DTest::translate<Float>,
&RigidMatrixTransformation3DTest::translate<Double>,
&RigidMatrixTransformation3DTest::rotate<Float>,
&RigidMatrixTransformation3DTest::rotate<Double>,
&RigidMatrixTransformation3DTest::reflect<Float>,
&RigidMatrixTransformation3DTest::reflect<Double>,
&RigidMatrixTransformation3DTest::normalizeRotation<Float>,
&RigidMatrixTransformation3DTest::normalizeRotation<Double>});
}
using namespace Math::Literals;
void RigidMatrixTransformation3DTest::fromMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation3D>::fromMatrix(m), m);
template<class T> using Object3D = Object<BasicRigidMatrixTransformation3D<T>>;
template<class T> using Scene3D = Scene<BasicRigidMatrixTransformation3D<T>>;
template<class T> void RigidMatrixTransformation3DTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation3D<T>>::fromMatrix(m), m);
}
void RigidMatrixTransformation3DTest::fromMatrixInvalid() {
template<class T> void RigidMatrixTransformation3DTest::fromMatrixInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream o;
Error redirectError{&o};
Implementation::Transformation<RigidMatrixTransformation3D>::fromMatrix(Matrix4::scaling(Vector3(4.0f)));
Implementation::Transformation<BasicRigidMatrixTransformation3D<T>>::fromMatrix(Math::Matrix4<T>::scaling(Math::Vector3<T>(T(4.0))));
CORRADE_COMPARE(o.str(), "SceneGraph::RigidMatrixTransformation3D: the matrix doesn't represent rigid transformation\n");
}
void RigidMatrixTransformation3DTest::toMatrix() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation3D>::toMatrix(m), m);
template<class T> void RigidMatrixTransformation3DTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation3D<T>>::toMatrix(Math::Matrix4<T>{m}), Math::Matrix4<T>{m});
}
void RigidMatrixTransformation3DTest::compose() {
Matrix4 parent = Matrix4::rotationX(Deg(17.0f));
Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation3D>::compose(parent, child), parent*child);
template<class T> void RigidMatrixTransformation3DTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> parent = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)});
Math::Matrix4<T> child = Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation3D<T>>::compose(parent, child), parent*child);
}
void RigidMatrixTransformation3DTest::inverted() {
Matrix4 m = Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<RigidMatrixTransformation3D>::inverted(m)*m, Matrix4());
template<class T> void RigidMatrixTransformation3DTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicRigidMatrixTransformation3D<T>>::inverted(m)*m, Math::Matrix4<T>{});
}
void RigidMatrixTransformation3DTest::setTransformation() {
Object3D o;
template<class T> void RigidMatrixTransformation3DTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
/* Dirty after setting transformation */
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
/* Scene cannot be transformed */
Scene3D s;
Scene3D<T> s;
s.setClean();
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(Matrix4::rotationX(Deg(17.0f)));
s.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix4());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix4<T>());
}
void RigidMatrixTransformation3DTest::setTransformationInvalid() {
template<class T> void RigidMatrixTransformation3DTest::setTransformationInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
Object3D o;
Object3D<T> o;
/* Can't transform with non-rigid transformation */
std::ostringstream out;
Error redirectError{&out};
o.setTransformation(Matrix4::scaling(Vector3(3.0f)));
o.setTransformation(Math::Matrix4<T>::scaling(Math::Vector3<T>(T(3.0))));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation\n");
}
void RigidMatrixTransformation3DTest::resetTransformation() {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
CORRADE_VERIFY(o.transformationMatrix() != Matrix4());
template<class T> void RigidMatrixTransformation3DTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix4<T>());
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>());
}
void RigidMatrixTransformation3DTest::transform() {
template<class T> void RigidMatrixTransformation3DTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.transform(Matrix4::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.transform(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.transformLocal(Matrix4::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.transformLocal(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
}
}
void RigidMatrixTransformation3DTest::transformInvalid() {
template<class T> void RigidMatrixTransformation3DTest::transformInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
/* Can't transform with non-rigid transformation */
Object3D o;
Object3D<T> o;
std::ostringstream out;
Error redirectError{&out};
o.transform(Matrix4::scaling(Vector3(3.0f)));
o.transform(Math::Matrix4<T>::scaling(Math::Vector3<T>(T(3.0))));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation\n");
}
void RigidMatrixTransformation3DTest::translate() {
template<class T> void RigidMatrixTransformation3DTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.translate({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.translate({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.translateLocal({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.translateLocal({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
}
}
void RigidMatrixTransformation3DTest::rotate() {
template<class T> void RigidMatrixTransformation3DTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
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()});
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}))
.rotateX(Math::Deg<T>{T(17.0)})
.rotateY(Math::Deg<T>{T(25.0)})
.rotateZ(Math::Deg<T>{T(-23.0)})
.rotate(Math::Quaternion<T>::rotation(Math::Deg<T>{T(36.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}))
.rotate(Math::Deg<T>{T(60.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))*
Matrix4::rotationZ(Deg(-23.0f))*
Matrix4::rotationY(Deg(25.0f))*
Matrix4::rotationX(Deg(17.0f))*
Matrix4::translation({1.0f, -0.3f, 2.3f}));
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
} {
Object3D o;
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()});
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}))
.rotateXLocal(Math::Deg<T>{T(17.0)})
.rotateYLocal(Math::Deg<T>{T(25.0)})
.rotateZLocal(Math::Deg<T>{T(-23.0)})
.rotateLocal(Math::Quaternion<T>::rotation(Math::Deg<T>{T(36.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}))
.rotateLocal(Math::Deg<T>{T(60.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(Deg(17.0f))*
Matrix4::rotationY(Deg(25.0f))*
Matrix4::rotationZ(Deg(-23.0f))*
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3())));
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}));
}
}
void RigidMatrixTransformation3DTest::reflect() {
template<class T> void RigidMatrixTransformation3DTest::reflect() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.reflect(Vector3(-1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3()))*Matrix4::rotationX(Deg(17.0f)));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.reflect(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::reflection(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3()))*Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.reflectLocal(Vector3(-1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3())));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.reflectLocal(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::reflection(Math::Vector3<T>(T(-1.0)/Math::Constants<T>::sqrt3())));
}
}
void RigidMatrixTransformation3DTest::normalizeRotation() {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
template<class T> void RigidMatrixTransformation3DTest::normalizeRotation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
o.normalizeRotation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
}
}}}}

42
src/Magnum/SceneGraph/Test/SceneTest.cpp

@ -25,7 +25,8 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/SceneGraph/MatrixTransformation3D.h"
#include "Magnum/SceneGraph/MatrixTransformation3D.hpp"
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
@ -33,32 +34,39 @@ namespace Magnum { namespace SceneGraph { namespace Test { namespace {
struct SceneTest: TestSuite::Tester {
explicit SceneTest();
void transformation();
void parent();
template<class T> void transformation();
template<class T> void parent();
};
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
SceneTest::SceneTest() {
addTests({&SceneTest::transformation,
&SceneTest::parent});
addTests<SceneTest>({
&SceneTest::transformation<Float>,
&SceneTest::transformation<Double>,
&SceneTest::parent<Float>,
&SceneTest::parent<Double>});
}
void SceneTest::transformation() {
Scene3D scene;
template<class T> using Object3D = SceneGraph::Object<SceneGraph::BasicMatrixTransformation3D<T>>;
template<class T> using Scene3D = SceneGraph::Scene<SceneGraph::BasicMatrixTransformation3D<T>>;
template<class T> void SceneTest::transformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D* scenePointer = &scene;
scenePointer->setTransformation(Matrix4::translation({1.0f, 1.0f, 1.0f}));
CORRADE_COMPARE(scene.transformation(), Matrix4());
Scene3D<T> scene;
Object3D<T>* scenePointer = &scene;
scenePointer->setTransformation(Math::Matrix4<T>::translation({T(1.0), T(1.0), T(1.0)}));
CORRADE_COMPARE(scene.transformation(), Math::Matrix4<T>{});
}
void SceneTest::parent() {
Scene3D scene;
template<class T> void SceneTest::parent() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Scene3D<T> scene;
/* Scene parent cannot be changed */
Object3D* scenePointer = &scene;
Object3D object;
Object3D<T>* scenePointer = &scene;
Object3D<T> object;
scenePointer->setParent(&object);
CORRADE_VERIFY(scene.parent() == nullptr);
CORRADE_VERIFY(scene.children().isEmpty());

319
src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation2DTest.cpp

@ -25,215 +25,250 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<TranslationRotationScalingTransformation2D> Object2D;
typedef Scene<TranslationRotationScalingTransformation2D> Scene2D;
struct TranslationRotationScalingTransformation2DTest: TestSuite::Tester {
explicit TranslationRotationScalingTransformation2DTest();
void fromMatrix();
void toMatrix();
void compose();
void inverted();
template<class T> void fromMatrix();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
void defaults();
void setTransformation();
void setTransformationRotateALot();
void resetTransformation();
template<class T> void defaults();
template<class T> void setTransformation();
template<class T> void setTransformationRotateALot();
template<class T> void resetTransformation();
void translate();
void rotate();
void scale();
template<class T> void translate();
template<class T> void rotate();
template<class T> void scale();
};
TranslationRotationScalingTransformation2DTest::TranslationRotationScalingTransformation2DTest() {
addTests({&TranslationRotationScalingTransformation2DTest::fromMatrix,
&TranslationRotationScalingTransformation2DTest::toMatrix,
&TranslationRotationScalingTransformation2DTest::compose,
&TranslationRotationScalingTransformation2DTest::inverted,
&TranslationRotationScalingTransformation2DTest::defaults,
&TranslationRotationScalingTransformation2DTest::setTransformation,
&TranslationRotationScalingTransformation2DTest::setTransformationRotateALot,
&TranslationRotationScalingTransformation2DTest::resetTransformation,
&TranslationRotationScalingTransformation2DTest::translate,
&TranslationRotationScalingTransformation2DTest::rotate,
&TranslationRotationScalingTransformation2DTest::scale});
addTests<TranslationRotationScalingTransformation2DTest>({
&TranslationRotationScalingTransformation2DTest::fromMatrix<Float>,
&TranslationRotationScalingTransformation2DTest::fromMatrix<Double>,
&TranslationRotationScalingTransformation2DTest::toMatrix<Float>,
&TranslationRotationScalingTransformation2DTest::toMatrix<Double>,
&TranslationRotationScalingTransformation2DTest::compose<Float>,
&TranslationRotationScalingTransformation2DTest::compose<Double>,
&TranslationRotationScalingTransformation2DTest::inverted<Float>,
&TranslationRotationScalingTransformation2DTest::inverted<Double>,
&TranslationRotationScalingTransformation2DTest::defaults<Float>,
&TranslationRotationScalingTransformation2DTest::defaults<Double>,
&TranslationRotationScalingTransformation2DTest::setTransformation<Float>,
&TranslationRotationScalingTransformation2DTest::setTransformation<Double>,
&TranslationRotationScalingTransformation2DTest::setTransformationRotateALot<Float>,
&TranslationRotationScalingTransformation2DTest::setTransformationRotateALot<Double>,
&TranslationRotationScalingTransformation2DTest::resetTransformation<Float>,
&TranslationRotationScalingTransformation2DTest::resetTransformation<Double>,
&TranslationRotationScalingTransformation2DTest::translate<Float>,
&TranslationRotationScalingTransformation2DTest::translate<Double>,
&TranslationRotationScalingTransformation2DTest::rotate<Float>,
&TranslationRotationScalingTransformation2DTest::rotate<Double>,
&TranslationRotationScalingTransformation2DTest::scale<Float>,
&TranslationRotationScalingTransformation2DTest::scale<Double>});
}
using namespace Math::Literals;
void TranslationRotationScalingTransformation2DTest::fromMatrix() {
Matrix3 m = Matrix3::rotation(17.0_degf)*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation2D>::fromMatrix(m), m);
template<class T> using Object2D = Object<BasicTranslationRotationScalingTransformation2D<T>>;
template<class T> using Scene2D = Scene<BasicTranslationRotationScalingTransformation2D<T>>;
template<class T> void TranslationRotationScalingTransformation2DTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation2D<T>>::fromMatrix(m), m);
}
void TranslationRotationScalingTransformation2DTest::toMatrix() {
Matrix3 m = Matrix3::rotation(17.0_degf)*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation2D>::toMatrix(m), m);
template<class T> void TranslationRotationScalingTransformation2DTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation2D<T>>::toMatrix(m), m);
}
void TranslationRotationScalingTransformation2DTest::compose() {
Matrix3 parent = Matrix3::rotation(17.0_degf);
Matrix3 child = Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation2D>::compose(parent, child), parent*child);
template<class T> void TranslationRotationScalingTransformation2DTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> parent = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)});
Math::Matrix3<T> child = Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation2D<T>>::compose(parent, child), parent*child);
}
void TranslationRotationScalingTransformation2DTest::inverted() {
Matrix3 m = Matrix3::rotation(17.0_degf)*Matrix3::translation({1.0f, -0.3f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation2D>::inverted(m)*m, Matrix3());
template<class T> void TranslationRotationScalingTransformation2DTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix3<T> m = Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*Math::Matrix3<T>::translation({T(1.0), T(-0.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation2D<T>>::inverted(m)*m, Math::Matrix3<T>{});
}
void TranslationRotationScalingTransformation2DTest::defaults() {
Object2D o;
CORRADE_COMPARE(o.translation(), Vector2{});
CORRADE_COMPARE(o.rotation(), Complex{});
CORRADE_COMPARE(o.scaling(), Vector2{1.0f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3{});
template<class T> void TranslationRotationScalingTransformation2DTest::defaults() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
CORRADE_COMPARE(o.translation(), Math::Vector2<T>{});
CORRADE_COMPARE(o.rotation(), Math::Complex<T>{});
CORRADE_COMPARE(o.scaling(), Math::Vector2<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>{});
}
void TranslationRotationScalingTransformation2DTest::setTransformation() {
template<class T> void TranslationRotationScalingTransformation2DTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
/* Dirty after setting transformation */
Object2D o;
Object2D<T> o;
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(
Matrix3::translation({7.0f, -1.0f})*
Matrix3::rotation(17.0_degf)*
Matrix3::scaling({1.5f, 0.5f}));
Math::Matrix3<T>::translation({T(7.0), T(-1.0)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*
Math::Matrix3<T>::scaling({T(1.5), T(0.5)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.translation(), (Vector2{7.0f, -1.0f}));
CORRADE_COMPARE(o.rotation(), Complex::rotation(17.0_degf));
CORRADE_COMPARE(o.scaling(), (Vector2{1.5f, 0.5f}));
CORRADE_COMPARE(o.translation(), (Math::Vector2<T>{T(7.0), T(-1.0)}));
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_COMPARE(o.scaling(), (Math::Vector2<T>{T(1.5), T(0.5)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::translation({7.0f, -1.0f})*
Matrix3::rotation(17.0_degf)*
Matrix3::scaling({1.5f, 0.5f}));
Math::Matrix3<T>::translation({T(7.0), T(-1.0)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*
Math::Matrix3<T>::scaling({T(1.5), T(0.5)}));
/* Scene cannot be transformed */
Scene2D s;
Scene2D<T> s;
s.setClean();
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(Matrix3::rotation(17.0_degf));
s.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix3());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix3<T>{});
}
void TranslationRotationScalingTransformation2DTest::setTransformationRotateALot() {
Object2D o;
template<class T> void TranslationRotationScalingTransformation2DTest::setTransformationRotateALot() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation(
Matrix3::translation({7.0f, -1.0f})*
Matrix3::rotation(225.0_degf)*
Matrix3::scaling({1.5f, 0.5f}));
CORRADE_COMPARE(o.translation(), (Vector2{7.0f, -1.0f}));
Math::Matrix3<T>::translation({T(7.0), T(-1.0)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(225.0)})*
Math::Matrix3<T>::scaling({T(1.5), T(0.5)}));
CORRADE_COMPARE(o.translation(), (Math::Vector2<T>{T(7.0), T(-1.0)}));
/* Rotation of more than 180° causes either the rotation matrix or scaling
to contain negative signs, verify we get a proper matrix back again */
CORRADE_COMPARE(o.rotation(), Complex::rotation(225.0_degf));
CORRADE_COMPARE(o.scaling(), (Vector2{1.5f, 0.5f}));
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(225.0)}));
CORRADE_COMPARE(o.scaling(), (Math::Vector2<T>{T(1.5), T(0.5)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::translation({7.0f, -1.0f})*
Matrix3::rotation(225.0_degf)*
Matrix3::scaling({1.5f, 0.5f}));
Math::Matrix3<T>::translation({T(7.0), T(-1.0)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(225.0)})*
Math::Matrix3<T>::scaling({T(1.5), T(0.5)}));
}
void TranslationRotationScalingTransformation2DTest::resetTransformation() {
Object2D o;
o.rotate(17.0_degf);
CORRADE_VERIFY(o.transformationMatrix() != Matrix3());
template<class T> void TranslationRotationScalingTransformation2DTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.rotate(Math::Deg<T>{T(17.0)});
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix3<T>{});
o.resetTransformation();
CORRADE_COMPARE(o.translation(), Vector2{});
CORRADE_COMPARE(o.rotation(), Complex{});
CORRADE_COMPARE(o.scaling(), Vector2{1.0f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3());
CORRADE_COMPARE(o.translation(), Math::Vector2<T>{});
CORRADE_COMPARE(o.rotation(), Math::Complex<T>{});
CORRADE_COMPARE(o.scaling(), Math::Vector2<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>{});
}
void TranslationRotationScalingTransformation2DTest::translate() {
template<class T> void TranslationRotationScalingTransformation2DTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(17.0_degf));
o.translate({1.0f, -0.3f})
.translate({1.0f, 0.1f});
CORRADE_COMPARE(o.translation(), (Vector2{2.0f, -0.2f}));
CORRADE_COMPARE(o.rotation(), Complex::rotation(17.0_degf));
CORRADE_COMPARE(o.scaling(), Vector2{1.0f});
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translate({T(1.0), T(-0.3)})
.translate({T(1.0), T(0.1)});
CORRADE_COMPARE(o.translation(), (Math::Vector2<T>{T(2.0), T(-0.2)}));
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_COMPARE(o.scaling(), Math::Vector2<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::translation({1.0f, 0.1f})*
Matrix3::translation({1.0f, -0.3f})*
Matrix3::rotation(17.0_degf));
Math::Matrix3<T>::translation({T(1.0), T(0.1)})*
Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(17.0_degf));
o.translateLocal({1.0f, -0.3f})
.translateLocal({1.0f, 0.1f});
CORRADE_COMPARE(o.translation(), (Vector2{2.0f, -0.2f}));
CORRADE_COMPARE(o.rotation(), Complex::rotation(17.0_degf));
CORRADE_COMPARE(o.scaling(), Vector2{1.0f});
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.translateLocal({T(1.0), T(-0.3)})
.translateLocal({T(1.0), T(0.1)});
CORRADE_COMPARE(o.translation(), (Math::Vector2<T>{T(2.0), T(-0.2)}));
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_COMPARE(o.scaling(), Math::Vector2<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::translation({1.0f, -0.3f})*
Matrix3::translation({1.0f, 0.1f})*
Matrix3::rotation(17.0_degf));
Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*
Math::Matrix3<T>::translation({T(1.0), T(0.1)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
}
}
void TranslationRotationScalingTransformation2DTest::rotate() {
template<class T> void TranslationRotationScalingTransformation2DTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::translation({1.0f, -0.3f}));
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));
CORRADE_COMPARE(o.scaling(), Vector2{1.0f});
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
o.rotate(Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}))
.rotate(Math::Deg<T>{T(-96.0)});
CORRADE_COMPARE(o.translation(), (Math::Vector2<T>{T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(-79.0)}));
CORRADE_COMPARE(o.scaling(), Math::Vector2<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::translation({1.0f, -0.3f})*
Matrix3::rotation(-96.0_degf)*
Matrix3::rotation(17.0_degf));
Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(-96.0)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
} {
Object2D o;
o.setTransformation(Matrix3::translation({1.0f, -0.3f}));
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));
CORRADE_COMPARE(o.scaling(), Vector2{1.0f});
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
o.rotateLocal(Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}))
.rotateLocal(Math::Deg<T>{T(-96.0)});
CORRADE_COMPARE(o.translation(), (Math::Vector2<T>{T(1.0), T(-0.3)}));
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(-79.0)}));
CORRADE_COMPARE(o.scaling(), Math::Vector2<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::translation({1.0f, -0.3f})*
Matrix3::rotation(17.0_degf)*
Matrix3::rotation(-96.0_degf));
Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*
Math::Matrix3<T>::rotation(Math::Deg<T>{T(-96.0)}));
}
}
void TranslationRotationScalingTransformation2DTest::scale() {
template<class T> void TranslationRotationScalingTransformation2DTest::scale() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object2D o;
o.setTransformation(Matrix3::rotation(17.0_degf));
o.scale({1.0f, -0.3f})
.scale({0.5f, 1.1f});
CORRADE_COMPARE(o.translation(), Vector2{});
CORRADE_COMPARE(o.rotation(), Complex::rotation(17.0_degf));
CORRADE_COMPARE(o.scaling(), (Vector2{0.5f, -0.33f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.scale({T(1.0), T(-0.3)})
.scale({T(0.5), T(1.1)});
CORRADE_COMPARE(o.translation(), Math::Vector2<T>{});
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_COMPARE(o.scaling(), (Math::Vector2<T>{T(0.5), T(-0.33)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::rotation(17.0_degf)*
Matrix3::scaling({0.5f, 1.1f})*
Matrix3::scaling({1.0f, -0.3f}));
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*
Math::Matrix3<T>::scaling({T(0.5), T(1.1)})*
Math::Matrix3<T>::scaling({T(1.0), T(-0.3)}));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(17.0_degf));
o.scaleLocal({1.0f, -0.3f})
.scaleLocal({0.5f, 1.1f});
CORRADE_COMPARE(o.translation(), Vector2{});
CORRADE_COMPARE(o.rotation(), Complex::rotation(17.0_degf));
CORRADE_COMPARE(o.scaling(), (Vector2{0.5f, -0.33f}));
Object2D<T> o;
o.setTransformation(Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)}));
o.scaleLocal({T(1.0), T(-0.3)})
.scaleLocal({T(0.5), T(1.1)});
CORRADE_COMPARE(o.translation(), Math::Vector2<T>{});
CORRADE_COMPARE(o.rotation(), Math::Complex<T>::rotation(Math::Deg<T>{T(17.0)}));
CORRADE_COMPARE(o.scaling(), (Math::Vector2<T>{T(0.5), T(-0.33)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix3::rotation(17.0_degf)*
Matrix3::scaling({1.0f, -0.3f})*
Matrix3::scaling({0.5f, 1.1f}));
Math::Matrix3<T>::rotation(Math::Deg<T>{T(17.0)})*
Math::Matrix3<T>::scaling({T(1.0), T(-0.3)})*
Math::Matrix3<T>::scaling({T(0.5), T(1.1)}));
}
}

347
src/Magnum/SceneGraph/Test/TranslationRotationScalingTransformation3DTest.cpp

@ -25,231 +25,266 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/SceneGraph/Object.hpp"
#include "Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h"
#include "Magnum/SceneGraph/Scene.h"
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<TranslationRotationScalingTransformation3D> Object3D;
typedef Scene<TranslationRotationScalingTransformation3D> Scene3D;
struct TranslationRotationScalingTransformation3DTest: TestSuite::Tester {
explicit TranslationRotationScalingTransformation3DTest();
void fromMatrix();
void toMatrix();
void compose();
void inverted();
template<class T> void fromMatrix();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
void defaults();
void setTransformation();
void setTransformationRotateALot();
void resetTransformation();
template<class T> void defaults();
template<class T> void setTransformation();
template<class T> void setTransformationRotateALot();
template<class T> void resetTransformation();
void translate();
void rotate();
void scale();
template<class T> void translate();
template<class T> void rotate();
template<class T> void scale();
};
TranslationRotationScalingTransformation3DTest::TranslationRotationScalingTransformation3DTest() {
addTests({&TranslationRotationScalingTransformation3DTest::fromMatrix,
&TranslationRotationScalingTransformation3DTest::toMatrix,
&TranslationRotationScalingTransformation3DTest::compose,
&TranslationRotationScalingTransformation3DTest::inverted,
&TranslationRotationScalingTransformation3DTest::defaults,
&TranslationRotationScalingTransformation3DTest::setTransformation,
&TranslationRotationScalingTransformation3DTest::setTransformationRotateALot,
&TranslationRotationScalingTransformation3DTest::resetTransformation,
&TranslationRotationScalingTransformation3DTest::translate,
&TranslationRotationScalingTransformation3DTest::rotate,
&TranslationRotationScalingTransformation3DTest::scale});
addTests<TranslationRotationScalingTransformation3DTest>({
&TranslationRotationScalingTransformation3DTest::fromMatrix<Float>,
&TranslationRotationScalingTransformation3DTest::fromMatrix<Double>,
&TranslationRotationScalingTransformation3DTest::toMatrix<Float>,
&TranslationRotationScalingTransformation3DTest::toMatrix<Double>,
&TranslationRotationScalingTransformation3DTest::compose<Float>,
&TranslationRotationScalingTransformation3DTest::compose<Double>,
&TranslationRotationScalingTransformation3DTest::inverted<Float>,
&TranslationRotationScalingTransformation3DTest::inverted<Double>,
&TranslationRotationScalingTransformation3DTest::defaults<Float>,
&TranslationRotationScalingTransformation3DTest::defaults<Double>,
&TranslationRotationScalingTransformation3DTest::setTransformation<Float>,
&TranslationRotationScalingTransformation3DTest::setTransformation<Double>,
&TranslationRotationScalingTransformation3DTest::setTransformationRotateALot<Float>,
&TranslationRotationScalingTransformation3DTest::setTransformationRotateALot<Double>,
&TranslationRotationScalingTransformation3DTest::resetTransformation<Float>,
&TranslationRotationScalingTransformation3DTest::resetTransformation<Double>,
&TranslationRotationScalingTransformation3DTest::translate<Float>,
&TranslationRotationScalingTransformation3DTest::translate<Double>,
&TranslationRotationScalingTransformation3DTest::rotate<Float>,
&TranslationRotationScalingTransformation3DTest::rotate<Double>,
&TranslationRotationScalingTransformation3DTest::scale<Float>,
&TranslationRotationScalingTransformation3DTest::scale<Double>});
}
using namespace Math::Literals;
void TranslationRotationScalingTransformation3DTest::fromMatrix() {
Matrix4 m = Matrix4::rotationX(17.0_degf)*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation3D>::fromMatrix(m), m);
template<class T> using Object3D = Object<BasicTranslationRotationScalingTransformation3D<T>>;
template<class T> using Scene3D = Scene<BasicTranslationRotationScalingTransformation3D<T>>;
template<class T> void TranslationRotationScalingTransformation3DTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::scaling({T(2.0), T(1.4), T(-2.1)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation3D<T>>::fromMatrix(m), m);
}
void TranslationRotationScalingTransformation3DTest::toMatrix() {
Matrix4 m = Matrix4::rotationX(17.0_degf)*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation3D>::toMatrix(m), m);
template<class T> void TranslationRotationScalingTransformation3DTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::scaling({T(2.0), T(1.4), T(-2.1)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation3D<T>>::toMatrix(m), m);
}
void TranslationRotationScalingTransformation3DTest::compose() {
Matrix4 parent = Matrix4::rotationX(17.0_degf);
Matrix4 child = Matrix4::translation({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation3D>::compose(parent, child), parent*child);
template<class T> void TranslationRotationScalingTransformation3DTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> parent = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)});
Math::Matrix4<T> child = Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation3D<T>>::compose(parent, child), parent*child);
}
void TranslationRotationScalingTransformation3DTest::inverted() {
Matrix4 m = Matrix4::rotationX(17.0_degf)*Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::scaling({2.0f, 1.4f, -2.1f});
CORRADE_COMPARE(Implementation::Transformation<TranslationRotationScalingTransformation3D>::inverted(m)*m, Matrix4());
template<class T> void TranslationRotationScalingTransformation3DTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Math::Matrix4<T> m = Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*Math::Matrix4<T>::scaling({T(2.0), T(1.4), T(-2.1)});
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationRotationScalingTransformation3D<T>>::inverted(Math::Matrix4<T>{m})*Math::Matrix4<T>{m}, Math::Matrix4<T>{});
}
void TranslationRotationScalingTransformation3DTest::defaults() {
Object3D o;
CORRADE_COMPARE(o.translation(), Vector3{});
CORRADE_COMPARE(o.rotation(), Quaternion{});
CORRADE_COMPARE(o.scaling(), Vector3{1.0f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4{});
template<class T> void TranslationRotationScalingTransformation3DTest::defaults() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
CORRADE_COMPARE(o.translation(), Math::Vector3<T>{});
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>{});
CORRADE_COMPARE(o.scaling(), Math::Vector3<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>{});
}
void TranslationRotationScalingTransformation3DTest::setTransformation() {
template<class T> void TranslationRotationScalingTransformation3DTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
/* Dirty after setting transformation */
Object3D o;
Object3D<T> o;
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(
Matrix4::translation({7.0f, -1.0f, 2.2f})*
Matrix4::rotationX(17.0_degf)*
Matrix4::scaling({1.5f, 0.5f, 3.0f}));
Math::Matrix4<T>::translation({T(7.0), T(-1.0), T(2.2)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::scaling({T(1.5), T(0.5), T(3.0)}));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.translation(), (Vector3{7.0f, -1.0f, 2.2f}));
CORRADE_COMPARE(o.rotation(), Quaternion::rotation(17.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), (Vector3{1.5f, 0.5f, 3.0f}));
CORRADE_COMPARE(o.translation(), (Math::Vector3<T>{T(7.0), T(-1.0), T(2.2)}));
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), (Math::Vector3<T>{T(1.5), T(0.5), T(3.0)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({7.0f, -1.0f, 2.2f})*
Matrix4::rotationX(17.0_degf)*
Matrix4::scaling({1.5f, 0.5f, 3.0f}));
Math::Matrix4<T>::translation({T(7.0), T(-1.0), T(2.2)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::scaling({T(1.5), T(0.5), T(3.0)}));
/* Scene cannot be transformed */
Scene3D s;
Scene3D<T> s;
s.setClean();
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(Matrix4::rotationX(17.0_degf));
s.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{17.0}));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix4());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix4<T>{});
}
void TranslationRotationScalingTransformation3DTest::setTransformationRotateALot() {
Object3D o;
template<class T> void TranslationRotationScalingTransformation3DTest::setTransformationRotateALot() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.setTransformation(
Matrix4::translation({7.0f, -1.0f, 2.2f})*
Matrix4::rotationX(225.0_degf)*
Matrix4::scaling({1.5f, 0.5f, 3.0f}));
CORRADE_COMPARE(o.translation(), (Vector3{7.0f, -1.0f, 2.2f}));
Math::Matrix4<T>::translation({T(7.0), T(-1.0), T(2.2)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(225.0)})*
Math::Matrix4<T>::scaling({T(1.5), T(0.5), T(3.0)}));
CORRADE_COMPARE(o.translation(), (Math::Vector3<T>{T(7.0), T(-1.0), T(2.2)}));
/* Rotation of more than 180° causes either the rotation matrix or scaling
to contain negative signs, verify we get a proper matrix back again */
CORRADE_COMPARE(o.rotation(), Quaternion::rotation(225.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), (Vector3{1.5f, 0.5f, 3.0f}));
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>::rotation(Math::Deg<T>{T(225.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), (Math::Vector3<T>{T(1.5), T(0.5), T(3.0)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({7.0f, -1.0f, 2.2f})*
Matrix4::rotationX(225.0_degf)*
Matrix4::scaling({1.5f, 0.5f, 3.0f}));
Math::Matrix4<T>::translation({T(7.0), T(-1.0), T(2.2)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(225.0)})*
Math::Matrix4<T>::scaling({T(1.5), T(0.5), T(3.0)}));
}
void TranslationRotationScalingTransformation3DTest::resetTransformation() {
Object3D o;
o.rotateX(17.0_degf);
CORRADE_VERIFY(o.transformationMatrix() != Matrix4());
template<class T> void TranslationRotationScalingTransformation3DTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object3D<T> o;
o.rotateX(Math::Deg<T>{17.0});
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix4<T>{});
o.resetTransformation();
CORRADE_COMPARE(o.translation(), Vector3{});
CORRADE_COMPARE(o.rotation(), Quaternion{});
CORRADE_COMPARE(o.scaling(), Vector3{1.0f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4());
CORRADE_COMPARE(o.translation(), Math::Vector3<T>{});
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>{});
CORRADE_COMPARE(o.scaling(), Math::Vector3<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix4<T>());
}
void TranslationRotationScalingTransformation3DTest::translate() {
template<class T> void TranslationRotationScalingTransformation3DTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(17.0_degf));
o.translate({1.0f, -0.3f, 2.3f})
.translate({1.0f, 0.1f, 0.2f});
CORRADE_COMPARE(o.translation(), (Vector3{2.0f, -0.2f, 2.5f}));
CORRADE_COMPARE(o.rotation(), Quaternion::rotation(17.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), Vector3{1.0f});
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{17.0}));
o.translate({T(1.0), T(-0.3), T(2.3)})
.translate({T(1.0), T(0.1), T(0.2)});
CORRADE_COMPARE(o.translation(), (Math::Vector3<T>{T(2.0), T(-0.2), T(2.5)}));
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), Math::Vector3<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, 0.1f, 0.2f})*
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(17.0_degf));
Math::Matrix4<T>::translation({T(1.0), T(0.1), T(0.2)})*
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(17.0_degf));
o.translateLocal({1.0f, -0.3f, 2.3f})
.translateLocal({1.0f, 0.1f, 0.2f});
CORRADE_COMPARE(o.translation(), (Vector3{2.0f, -0.2f, 2.5f}));
CORRADE_COMPARE(o.rotation(), Quaternion::rotation(17.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), Vector3{1.0f});
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{17.0}));
o.translateLocal({T(1.0), T(-0.3), T(2.3)})
.translateLocal({T(1.0), T(0.1), T(0.2)});
CORRADE_COMPARE(o.translation(), (Math::Vector3<T>{T(2.0), T(-0.2), T(2.5)}));
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), Math::Vector3<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::translation({1.0f, 0.1f, 0.2f})*
Matrix4::rotationX(17.0_degf));
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::translation({T(1.0), T(0.1), T(0.2)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
}
}
void TranslationRotationScalingTransformation3DTest::rotate() {
template<class T> void TranslationRotationScalingTransformation3DTest::rotate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(17.0_degf)
.rotateY(25.0_degf)
.rotateZ(-23.0_degf)
.rotate(96.0_degf, Vector3{1.0f/Constants::sqrt3()});
CORRADE_COMPARE(o.translation(), (Vector3{1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
o.rotateX(Math::Deg<T>{T(17.0)})
.rotateY(Math::Deg<T>{T(25.0)})
.rotateZ(Math::Deg<T>{T(-23.0)})
.rotate(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.translation(), (Math::Vector3<T>{T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.rotation(),
Quaternion::rotation(96.0_degf, Vector3{1.0f/Constants::sqrt3()})*
Quaternion::rotation(-23.0_degf, Vector3::zAxis())*
Quaternion::rotation(25.0_degf, Vector3::yAxis())*
Quaternion::rotation(17.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), Vector3{1.0f});
Math::Quaternion<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()})*
Math::Quaternion<T>::rotation(Math::Deg<T>{T(-23.0)}, Math::Vector3<T>::zAxis())*
Math::Quaternion<T>::rotation(Math::Deg<T>{T(25.0)}, Math::Vector3<T>::yAxis())*
Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), Math::Vector3<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotation(96.0_degf, Vector3{1.0f/Constants::sqrt3()})*
Matrix4::rotationZ(-23.0_degf)*
Matrix4::rotationY(25.0_degf)*
Matrix4::rotationX(17.0_degf));
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)},Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)}));
} {
Object3D o;
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateXLocal(17.0_degf)
.rotateYLocal(25.0_degf)
.rotateZLocal(-23.0_degf)
.rotateLocal(96.0_degf, Vector3{1.0f/Constants::sqrt3()});
CORRADE_COMPARE(o.translation(), (Vector3{1.0f, -0.3f, 2.3f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)}));
o.rotateXLocal(Math::Deg<T>{T(17.0)})
.rotateYLocal(Math::Deg<T>{T(25.0)})
.rotateZLocal(Math::Deg<T>{T(-23.0)})
.rotateLocal(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()});
CORRADE_COMPARE(o.translation(), (Math::Vector3<T>{T(1.0), T(-0.3), T(2.3)}));
CORRADE_COMPARE(o.rotation(),
Quaternion::rotation(17.0_degf, Vector3::xAxis())*
Quaternion::rotation(25.0_degf, Vector3::yAxis())*
Quaternion::rotation(-23.0_degf, Vector3::zAxis())*
Quaternion::rotation(96.0_degf, Vector3(1.0f/Constants::sqrt3())));
CORRADE_COMPARE(o.scaling(), Vector3{1.0f});
Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis())*
Math::Quaternion<T>::rotation(Math::Deg<T>{T(25.0)}, Math::Vector3<T>::yAxis())*
Math::Quaternion<T>::rotation(Math::Deg<T>{T(-23.0)}, Math::Vector3<T>::zAxis())*
Math::Quaternion<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>(T(1.0)/Math::Constants<T>::sqrt3())));
CORRADE_COMPARE(o.scaling(), Math::Vector3<T>{T(1.0)});
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(17.0_degf)*
Matrix4::rotationY(25.0_degf)*
Matrix4::rotationZ(-23.0_degf)*
Matrix4::rotation(96.0_degf, Vector3{1.0f/Constants::sqrt3()}));
Math::Matrix4<T>::translation({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::rotationY(Math::Deg<T>{T(25.0)})*
Math::Matrix4<T>::rotationZ(Math::Deg<T>{T(-23.0)})*
Math::Matrix4<T>::rotation(Math::Deg<T>{T(96.0)}, Math::Vector3<T>{T(1.0)/Math::Constants<T>::sqrt3()}));
}
}
void TranslationRotationScalingTransformation3DTest::scale() {
template<class T> void TranslationRotationScalingTransformation3DTest::scale() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
{
Object3D o;
o.setTransformation(Matrix4::rotationX(17.0_degf));
o.scale({1.0f, -0.3f, 2.3f})
.scale({0.5f, 1.1f, 2.0f});
CORRADE_COMPARE(o.translation(), Vector3{});
CORRADE_COMPARE(o.rotation(), Quaternion::rotation(17.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), (Vector3{0.5f, -0.33f, 4.6f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{17.0}));
o.scale({T(1.0), T(-0.3), T(2.3)})
.scale({T(0.5), T(1.1), T(2.0)});
CORRADE_COMPARE(o.translation(), Math::Vector3<T>{});
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), (Math::Vector3<T>{T(0.5), T(-0.33), T(4.6)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotationX(17.0_degf)*
Matrix4::scaling({0.5f, 1.1f, 2.0f})*
Matrix4::scaling({1.0f, -0.3f, 2.3f}));
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::scaling({T(0.5), T(1.1), T(2.0)})*
Math::Matrix4<T>::scaling({T(1.0), T(-0.3), T(2.3)}));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(17.0_degf));
o.scaleLocal({1.0f, -0.3f, 2.3f})
.scaleLocal({0.5f, 1.1f, 2.0f});
CORRADE_COMPARE(o.translation(), Vector3{});
CORRADE_COMPARE(o.rotation(), Quaternion::rotation(17.0_degf, Vector3::xAxis()));
CORRADE_COMPARE(o.scaling(), (Vector3{0.5f, -0.33f, 4.6f}));
Object3D<T> o;
o.setTransformation(Math::Matrix4<T>::rotationX(Math::Deg<T>{17.0}));
o.scaleLocal({T(1.0), T(-0.3), T(2.3)})
.scaleLocal({T(0.5), T(1.1), T(2.0)});
CORRADE_COMPARE(o.translation(), Math::Vector3<T>{});
CORRADE_COMPARE(o.rotation(), Math::Quaternion<T>::rotation(Math::Deg<T>{T(17.0)}, Math::Vector3<T>::xAxis()));
CORRADE_COMPARE(o.scaling(), (Math::Vector3<T>{T(0.5), T(-0.33), T(4.6)}));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotationX(17.0_degf)*
Matrix4::scaling({1.0f, -0.3f, 2.3f})*
Matrix4::scaling({0.5f, 1.1f, 2.0f}));
Math::Matrix4<T>::rotationX(Math::Deg<T>{T(17.0)})*
Math::Matrix4<T>::scaling({T(1.0), T(-0.3), T(2.3)})*
Math::Matrix4<T>::scaling({T(0.5), T(1.1), T(2.0)}));
}
}

157
src/Magnum/SceneGraph/Test/TranslationTransformationTest.cpp

@ -33,114 +33,145 @@
namespace Magnum { namespace SceneGraph { namespace Test { namespace {
typedef Object<TranslationTransformation2D> Object2D;
typedef Scene<TranslationTransformation2D> Scene2D;
struct TranslationTransformationTest: TestSuite::Tester {
explicit TranslationTransformationTest();
void fromMatrix();
void fromMatrixInvalid();
void toMatrix();
void compose();
void inverted();
template<class T> void fromMatrix();
template<class T> void fromMatrixInvalid();
template<class T> void toMatrix();
template<class T> void compose();
template<class T> void inverted();
void setTransformation();
void resetTransformation();
void transform();
void translate();
template<class T> void setTransformation();
template<class T> void resetTransformation();
template<class T> void transform();
template<class T> void translate();
void integral();
template<class T> void integral();
};
TranslationTransformationTest::TranslationTransformationTest() {
addTests({&TranslationTransformationTest::fromMatrix,
&TranslationTransformationTest::fromMatrixInvalid,
&TranslationTransformationTest::toMatrix,
&TranslationTransformationTest::compose,
&TranslationTransformationTest::inverted,
&TranslationTransformationTest::setTransformation,
&TranslationTransformationTest::resetTransformation,
&TranslationTransformationTest::transform,
&TranslationTransformationTest::translate,
&TranslationTransformationTest::integral});
addTests<TranslationTransformationTest>({
&TranslationTransformationTest::fromMatrix<Float>,
&TranslationTransformationTest::fromMatrix<Double>,
&TranslationTransformationTest::fromMatrixInvalid<Float>,
&TranslationTransformationTest::fromMatrixInvalid<Double>,
&TranslationTransformationTest::toMatrix<Float>,
&TranslationTransformationTest::toMatrix<Double>,
&TranslationTransformationTest::compose<Float>,
&TranslationTransformationTest::compose<Double>,
&TranslationTransformationTest::inverted<Float>,
&TranslationTransformationTest::inverted<Double>,
&TranslationTransformationTest::setTransformation<Float>,
&TranslationTransformationTest::setTransformation<Double>,
&TranslationTransformationTest::resetTransformation<Float>,
&TranslationTransformationTest::resetTransformation<Double>,
&TranslationTransformationTest::transform<Float>,
&TranslationTransformationTest::transform<Double>,
&TranslationTransformationTest::translate<Float>,
&TranslationTransformationTest::translate<Double>,
&TranslationTransformationTest::integral<Float>,
&TranslationTransformationTest::integral<Double>});
}
void TranslationTransformationTest::fromMatrix() {
const Vector2 v(1.0f, -0.3f);
CORRADE_COMPARE(Implementation::Transformation<TranslationTransformation2D>::fromMatrix(Matrix3::translation(v)), v);
template<class T> using Object2D = Object<BasicTranslationTransformation2D<T>>;
template<class T> using Scene2D = Scene<BasicTranslationTransformation2D<T>>;
template<class T> void TranslationTransformationTest::fromMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const Math::Vector2<T> v{T(1.0), T(-0.3)};
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationTransformation2D<T>>::fromMatrix(Math::Matrix3<T>::translation(v)), v);
}
void TranslationTransformationTest::fromMatrixInvalid() {
template<class T> void TranslationTransformationTest::fromMatrixInvalid() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
std::ostringstream o;
Error redirectError{&o};
Implementation::Transformation<TranslationTransformation2D>::fromMatrix(Matrix3::scaling(Vector2(4.0f)));
Implementation::Transformation<BasicTranslationTransformation2D<T>>::fromMatrix(Math::Matrix3<T>::scaling(Math::Vector2<T>{T(4.0)}));
CORRADE_COMPARE(o.str(), "SceneGraph::TranslationTransformation: the matrix doesn't represent pure translation\n");
}
void TranslationTransformationTest::toMatrix() {
const Vector2 v(1.0f, -0.3f);
CORRADE_COMPARE(Implementation::Transformation<TranslationTransformation2D>::toMatrix(v), Matrix3::translation(v));
template<class T> void TranslationTransformationTest::toMatrix() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const Math::Vector2<T> v{T(1.0), T(-0.3)};
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationTransformation2D<T>>::toMatrix(v), Math::Matrix3<T>::translation(v));
}
void TranslationTransformationTest::compose() {
const Vector2 parent(-0.5f, 2.0f);
const Vector2 child(1.0f, -0.3f);
CORRADE_COMPARE(Implementation::Transformation<TranslationTransformation2D>::compose(parent, child), Vector2(0.5f, 1.7f));
template<class T> void TranslationTransformationTest::compose() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const Math::Vector2<T> parent{T(-0.5), T(2.0)};
const Math::Vector2<T> child{T(1.0), T(-0.3)};
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationTransformation2D<T>>::compose(parent, child), (Math::Vector2<T>{T(0.5), T(1.7)}));
}
void TranslationTransformationTest::inverted() {
const Vector2 v(1.0f, -0.3f);
CORRADE_COMPARE(Implementation::Transformation<TranslationTransformation2D>::inverted(v), Vector2(-1.0f, 0.3f));
template<class T> void TranslationTransformationTest::inverted() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
const Math::Vector2<T> v{T(1.0), T(-0.3)};
CORRADE_COMPARE(Implementation::Transformation<BasicTranslationTransformation2D<T>>::inverted(v), (Math::Vector2<T>{T(-1.0), T(0.3)}));
}
void TranslationTransformationTest::setTransformation() {
Object2D o;
template<class T> void TranslationTransformationTest::setTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
/* Dirty after setting transformation */
o.setClean();
CORRADE_VERIFY(!o.isDirty());
o.setTransformation({1.0f, -0.3f});
o.setTransformation({T(1.0), T(-0.3)});
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)}));
/* Scene cannot be transformed */
Scene2D s;
Scene2D<T> s;
s.setClean();
s.setTransformation({1.0f, -0.3f});
s.setTransformation({T(1.0), T(-0.3)});
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix3());
CORRADE_COMPARE(s.transformationMatrix(), Math::Matrix3<T>{});
}
void TranslationTransformationTest::resetTransformation() {
Object2D o;
o.setTransformation({1.0f, -0.3f});
CORRADE_VERIFY(o.transformationMatrix() != Matrix3());
template<class T> void TranslationTransformationTest::resetTransformation() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation({T(1.0), T(-0.3)});
CORRADE_VERIFY(o.transformationMatrix() != Math::Matrix3<T>{});
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3());
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>{});
}
void TranslationTransformationTest::transform() {
Object2D o;
o.setTransformation({1.0f, -0.3f})
.transform({-0.5f, 2.0f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({0.5f, 1.7f}));
template<class T> void TranslationTransformationTest::transform() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation({T(1.0), T(-0.3)})
.transform({T(-0.5), T(2.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(0.5), T(1.7)}));
}
void TranslationTransformationTest::translate() {
Object2D o;
o.setTransformation({1.0f, -0.3f})
.translate({-0.5f, 2.0f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::translation({-0.5f, 2.0f}));
template<class T> void TranslationTransformationTest::translate() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
Object2D<T> o;
o.setTransformation({T(1.0), T(-0.3)})
.translate({T(-0.5), T(2.0)});
CORRADE_COMPARE(o.transformationMatrix(), Math::Matrix3<T>::translation({T(1.0), T(-0.3)})*Math::Matrix3<T>::translation({T(-0.5), T(2.0)}));
}
void TranslationTransformationTest::integral() {
template<class T> void TranslationTransformationTest::integral() {
setTestCaseTemplateName(Math::TypeTraits<T>::name());
typedef Object<BasicTranslationTransformation2D<Float, Short>> Object2Di;
Object2Di o;

Loading…
Cancel
Save