diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d9b35b542..bd69d4388 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,15 @@ install(TARGETS Magnum DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) if(BUILD_TESTS) enable_testing() + + # Library with graceful assert for testing + add_library(MagnumTestLib SHARED ${Magnum_SRCS}) + if(WIN32) + set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DMAGNUM_EXPORTING) + endif() + set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) + target_link_libraries(MagnumTestLib ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY} ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) + include_directories(${QT_INCLUDE_DIR}) add_subdirectory(Test) endif() diff --git a/src/Light.cpp b/src/Light.cpp index 3ce026f86..9ba5eeecf 100644 --- a/src/Light.cpp +++ b/src/Light.cpp @@ -14,12 +14,25 @@ */ #include "Light.h" +#include "Camera.h" namespace Magnum { +Vector3 Light::position(Camera* camera) { + CORRADE_ASSERT(scene() && camera->scene() == scene(), "Light: camera and light aren't in the same scene!", Vector3()) + + if(camera != _camera) { + _camera = camera; + setDirty(); + } + + setClean(); + return _position; +} + void Light::setClean() { if(!isDirty()) return; - _position = absoluteTransformation()[3]; + _position = (absoluteTransformation()*_camera->cameraMatrix())[3].xyz(); Object::setClean(); } diff --git a/src/Light.h b/src/Light.h index 080c1681f..f04e70385 100644 --- a/src/Light.h +++ b/src/Light.h @@ -34,15 +34,15 @@ class Light: public Object { * @brief Constructor * @param parent Parent object */ - inline Light(Object* parent = nullptr): Object(parent) {} + inline Light(Object* parent = nullptr): Object(parent), _camera(nullptr) {} /** - * @brief Light position relative to root object (scene) + * @brief Light position relative to given camera + * + * The position is cached until the camera is changed to another or + * the light dirty bit is set. */ - inline Vector4 position() { - setClean(); - return _position; - } + Vector3 position(Camera* camera); /** * Recomputes light position. @@ -50,7 +50,8 @@ class Light: public Object { void setClean(); private: - Vector4 _position; + Camera* _camera; + Vector3 _position; }; } diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index ae92a6cb9..16c0cbcdf 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -1,3 +1,4 @@ corrade_add_test(ObjectTest ObjectTest.h ObjectTest.cpp Magnum) 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/LightTest.cpp b/src/Test/LightTest.cpp new file mode 100644 index 000000000..6c506908e --- /dev/null +++ b/src/Test/LightTest.cpp @@ -0,0 +1,63 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "LightTest.h" + +#include +#include + +#include "Camera.h" +#include "Light.h" +#include "Scene.h" + +QTEST_APPLESS_MAIN(Magnum::Test::LightTest) + +using namespace std; +using namespace Corrade::Utility; + +namespace Magnum { namespace Test { + +void LightTest::positionWrongCamera() { + stringstream ss; + Error::setOutput(&ss); + + Camera c; + Light l; + QVERIFY(l.position(&c) == Vector3()); + QVERIFY(ss.str() == "Light: camera and light aren't in the same scene!\n"); +} + +void LightTest::position() { + Scene s; + + Object lightParent(&s); + lightParent.translate(Vector3::zAxis(3)); + Light light(&lightParent); + + Object cameraParent(&s); + cameraParent.rotate(deg(90.0f), Vector3::xAxis()); + Camera camera(&cameraParent); + + QVERIFY(light.position(&camera) == (Matrix4::translation(Vector3::zAxis(3))* + Matrix4::rotation(deg(90.0f), Vector3::xAxis()).inversed())[3].xyz()); + + /* Set another camera */ + Camera another(&cameraParent); + another.scale(Vector3(3.0f)); + QVERIFY(light.position(&another) == (Matrix4::translation(Vector3::zAxis(3))* + (Matrix4::scaling(Vector3(3.0f))*Matrix4::rotation(deg(90.0f), Vector3::xAxis())).inversed())[3].xyz()); +} + +}} diff --git a/src/Test/LightTest.h b/src/Test/LightTest.h new file mode 100644 index 000000000..601834df7 --- /dev/null +++ b/src/Test/LightTest.h @@ -0,0 +1,32 @@ +#ifndef Magnum_Test_LightTest_h +#define Magnum_Test_LightTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace Test { + +class LightTest: public QObject { + Q_OBJECT + + private slots: + void positionWrongCamera(); + void position(); +}; + +}} + +#endif