diff --git a/src/Object.cpp b/src/Object.cpp index ee29a91ff..85f312894 100644 --- a/src/Object.cpp +++ b/src/Object.cpp @@ -50,19 +50,21 @@ Object* Object::setParent(Object* parent) { } Matrix4 Object::absoluteTransformation(Camera* camera) { - Matrix4 t = _transformation; - /* Shortcut for absolute transformation of camera relative to itself */ if(camera == this) return Matrix4(); + Matrix4 t = _transformation; + Object* p = parent(); while(p != nullptr) { t = p->transformation()*t; /* We got to the scene, multiply with camera matrix */ if(p->parent() == p) { - if(camera && camera->scene() == scene()) + if(camera) { + CORRADE_ASSERT(camera->scene() == scene(), "Object::absoluteTransformation(): the camera is not part of the same scene as object!", t) t = camera->cameraMatrix()*t; + } break; } @@ -70,6 +72,8 @@ Matrix4 Object::absoluteTransformation(Camera* camera) { p = p->parent(); } + CORRADE_ASSERT(p != nullptr || camera == nullptr, "Object::absoluteTransformation(): the object is not part of camera scene!", t) + return t; } diff --git a/src/Object.h b/src/Object.h index f6c0bab0b..4fceb7f2b 100644 --- a/src/Object.h +++ b/src/Object.h @@ -103,10 +103,9 @@ class MAGNUM_EXPORT Object { /** * @brief Absolute transformation * - * If both this object and the camera is part of the same scene, - * returns absolute transformation matrix (relative to the camera). - * Otherwise returns transformation matrix relative to root object - * (in most cases scene of this object). + * Returns absolute transformation matrix relative to the camera or + * root object, if no camera is specified. If the camera is specified, + * it should be part of the same scene as object. * * Note that the absolute transformation is computed from all parent * objects every time it is asked, unless this function is diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 16c0cbcdf..639eb4c61 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -1,4 +1,4 @@ -corrade_add_test(ObjectTest ObjectTest.h ObjectTest.cpp Magnum) +corrade_add_test(ObjectTest ObjectTest.h ObjectTest.cpp MagnumTestLib) corrade_add_test(CameraTest CameraTest.h CameraTest.cpp Magnum) corrade_add_test(LightTest LightTest.h LightTest.cpp MagnumTestLib) corrade_add_test(SceneTest SceneTest.h SceneTest.cpp Magnum) diff --git a/src/Test/ObjectTest.cpp b/src/Test/ObjectTest.cpp index 44598aa33..979923f5b 100644 --- a/src/Test/ObjectTest.cpp +++ b/src/Test/ObjectTest.cpp @@ -15,9 +15,14 @@ #include "ObjectTest.h" #include "Scene.h" +#include "Camera.h" +#include #include +using namespace std; +using namespace Corrade::Utility; + QTEST_APPLESS_MAIN(Magnum::Test::ObjectTest) namespace Magnum { namespace Test { @@ -70,6 +75,45 @@ void ObjectTest::transformation() { QVERIFY(o2.transformation() == o.transformation()); } +void ObjectTest::absoluteTransformationWrongCamera() { + stringstream ss; + Error::setOutput(&ss); + + Scene s; + Object o(&s); + o.translate(Vector3::yAxis()); + Camera c; + QVERIFY(o.absoluteTransformation(&c) == Matrix4::translation(Vector3::yAxis())); + QVERIFY(ss.str() == "Object::absoluteTransformation(): the camera is not part of the same scene as object!\n"); + + ss.str(""); + Object o2; + o2.translate(Vector3::xAxis()); + QVERIFY(o2.absoluteTransformation(&c) == Matrix4::translation(Vector3::xAxis())); + QVERIFY(ss.str() == "Object::absoluteTransformation(): the object is not part of camera scene!\n"); +} + +void ObjectTest::absoluteTransformation() { + Scene s; + Camera c(&s); + c.translate(Vector3::zAxis(2.0f)); + QVERIFY(s.absoluteTransformation() == Matrix4()); + QVERIFY(c.absoluteTransformation(&c) == Matrix4()); + + Object o(&s); + o.scale(Vector3(2.0f)); + Object o2(&o); + o.rotate(deg(90.0f), Vector3::yAxis()); + QVERIFY((o2.absoluteTransformation() == + Matrix4::scaling(Vector3(2.0f))*Matrix4::rotation(deg(90.0f), Vector3::yAxis()))); + QVERIFY((o2.absoluteTransformation(&c) == + (Matrix4::translation(Vector3::zAxis(2.0f)).inverted())*Matrix4::scaling(Vector3(2.0f))*Matrix4::rotation(deg(90.0f), Vector3::yAxis()))); + + Object o3; + o3.translate({1.0f, 2.0f, 3.0f}); + QVERIFY(o3.absoluteTransformation() == Matrix4::translation({1.0f, 2.0f, 3.0f})); +} + void ObjectTest::scene() { Scene scene; diff --git a/src/Test/ObjectTest.h b/src/Test/ObjectTest.h index b316684da..ef7a629e8 100644 --- a/src/Test/ObjectTest.h +++ b/src/Test/ObjectTest.h @@ -27,6 +27,8 @@ class ObjectTest: public QObject { private slots: void parenting(); void transformation(); + void absoluteTransformationWrongCamera(); + void absoluteTransformation(); void scene(); void dirty(); };