From 810c06509a48493f4bd3579484b069f6bb7b684b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 15 Aug 2012 18:57:12 +0200 Subject: [PATCH] SceneGraph: modifications to allow 2D implementation in future. --- src/SceneGraph/Camera.cpp | 129 +++++++++++++++------------- src/SceneGraph/Camera.h | 133 +++++++++++++++++++---------- src/SceneGraph/Light.h | 4 +- src/SceneGraph/Object.cpp | 54 ++++++------ src/SceneGraph/Object.h | 127 +++++++++++++++------------ src/SceneGraph/Scene.h | 23 +++-- src/SceneGraph/Test/CameraTest.cpp | 4 +- src/SceneGraph/Test/ObjectTest.cpp | 44 +++++----- src/SceneGraph/Test/ObjectTest.h | 6 +- src/SceneGraph/Test/SceneTest.cpp | 10 +-- 10 files changed, 303 insertions(+), 231 deletions(-) diff --git a/src/SceneGraph/Camera.cpp b/src/SceneGraph/Camera.cpp index d05ff63f1..ad3b794fe 100644 --- a/src/SceneGraph/Camera.cpp +++ b/src/SceneGraph/Camera.cpp @@ -21,9 +21,72 @@ using namespace std; namespace Magnum { namespace SceneGraph { -Camera::Camera(Object* parent): Object(parent), _aspectRatioPolicy(AspectRatioPolicy::Extend) {} +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { -void Camera::setOrthographic(GLfloat size, GLfloat near, GLfloat far) { +Matrix4 Camera<3>::fixAspectRatio(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& viewport) { + /* Don't divide by zero */ + if(viewport.x() == 0 || viewport.y() == 0) + return Matrix4(); + + /* Extend on larger side = scale larger side down */ + if(aspectRatioPolicy == AspectRatioPolicy::Extend) + return ((viewport.x() > viewport.y()) ? + Matrix4::scaling({GLfloat(viewport.y())/viewport.x(), 1, 1}) : + Matrix4::scaling({1, GLfloat(viewport.x())/viewport.y(), 1}) + ); + + /* Clip on smaller side = scale smaller side up */ + if(aspectRatioPolicy == AspectRatioPolicy::Clip) + return ((viewport.x() > viewport.y()) ? + Matrix4::scaling({1, GLfloat(viewport.x())/viewport.y(), 1}) : + Matrix4::scaling({GLfloat(viewport.y())/viewport.x(), 1, 1}) + ); + + /* Don't preserve anything */ + return Matrix4(); +} + +} +#endif + +template Camera::Camera(ObjectType* parent): ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::Extend) {} + +template void Camera::setViewport(const Math::Vector2& size) { + Framebuffer::setViewport({0, 0}, size); + + _viewport = size; + fixAspectRatio(); +} + +template void Camera::clean(const MatrixType& absoluteTransformation) { + ObjectType::clean(absoluteTransformation); + + _cameraMatrix = absoluteTransformation.inverted(); +} + +template void Camera::draw() { + SceneType* s = this->scene(); + CORRADE_ASSERT(s, "Camera: cannot draw without camera attached to scene", ); + + Framebuffer::clear(); + + /* Recursively draw child objects */ + drawChildren(s, cameraMatrix()); +} + +template void Camera::drawChildren(ObjectType* object, const MatrixType& transformationMatrix) { + for(typename set::const_iterator it = object->children().begin(); it != object->children().end(); ++it) { + /* Transformation matrix for the object */ + MatrixType matrix = transformationMatrix*(*it)->transformation(); + + /* Draw the object and its children */ + (*it)->draw(matrix, static_cast(this)); + drawChildren(*it, matrix); + } +} + +void Camera3D::setOrthographic(GLfloat size, GLfloat near, GLfloat far) { _near = near; _far = far; @@ -38,7 +101,7 @@ void Camera::setOrthographic(GLfloat size, GLfloat near, GLfloat far) { fixAspectRatio(); } -void Camera::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { +void Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { _near = near; _far = far; @@ -63,63 +126,7 @@ void Camera::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { fixAspectRatio(); } -void Camera::setViewport(const Math::Vector2& size) { - Framebuffer::setViewport({0, 0}, size); - - _viewport = size; - fixAspectRatio(); -} - -void Camera::clean(const Matrix4& absoluteTransformation) { - Object::clean(absoluteTransformation); - - _cameraMatrix = absoluteTransformation.inverted(); -} - -void Camera::fixAspectRatio() { - /* Don't divide by zero */ - if(_viewport.x() == 0 || _viewport.y() == 0) { - _projectionMatrix = rawProjectionMatrix; - return; - } - - /* Extend on larger side = scale larger side down */ - if(_aspectRatioPolicy == AspectRatioPolicy::Extend) { - _projectionMatrix = ((_viewport.x() > _viewport.y()) ? - Matrix4::scaling({GLfloat(_viewport.y())/_viewport.x(), 1, 1}) : - Matrix4::scaling({1, GLfloat(_viewport.x())/_viewport.y(), 1}) - )*rawProjectionMatrix; - - /* Clip on smaller side = scale smaller side up */ - } else if(_aspectRatioPolicy == AspectRatioPolicy::Clip) { - _projectionMatrix = ((_viewport.x() > _viewport.y()) ? - Matrix4::scaling({1, GLfloat(_viewport.x())/_viewport.y(), 1}) : - Matrix4::scaling({GLfloat(_viewport.y())/_viewport.x(), 1, 1}) - )*rawProjectionMatrix; - - /* Don't preserve anything */ - } else _projectionMatrix = rawProjectionMatrix; -} - -void Camera::draw() { - Scene* s = scene(); - CORRADE_ASSERT(s, "Camera: cannot draw without camera attached to scene", ); - - Framebuffer::clear(); - - /* Recursively draw child objects */ - drawChildren(s, cameraMatrix()); -} - -void Camera::drawChildren(Object* object, const Matrix4& transformationMatrix) { - for(set::const_iterator it = object->children().begin(); it != object->children().end(); ++it) { - /* Transformation matrix for the object */ - Matrix4 matrix = transformationMatrix*(*it)->transformation(); - - /* Draw the object and its children */ - (*it)->draw(matrix, this); - drawChildren(*it, matrix); - } -} +/* Explicitly instantiate the templates */ +template class Camera; }} diff --git a/src/SceneGraph/Camera.h b/src/SceneGraph/Camera.h index 308a0d99a..d1a8674f8 100644 --- a/src/SceneGraph/Camera.h +++ b/src/SceneGraph/Camera.h @@ -28,31 +28,38 @@ namespace Magnum { namespace SceneGraph { +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + enum class AspectRatioPolicy { + NotPreserved, Extend, Clip + }; + + template class Camera {}; +} +#endif + /** @brief %Camera object */ -class SCENEGRAPH_EXPORT Camera: public Object { +template class SCENEGRAPH_EXPORT Camera: public ObjectType { public: /** * @brief Aspect ratio policy * * @see aspectRatioPolicy(), setAspectRatioPolicy() */ + #ifndef DOXYGEN_GENERATING_OUTPUT + typedef Implementation::AspectRatioPolicy AspectRatioPolicy; + #else enum class AspectRatioPolicy { NotPreserved, /**< Don't preserve aspect ratio */ Extend, /**< Extend on larger side of view */ Clip /**< Clip on smaller side of view */ }; + #endif - /** - * @brief Constructor - * @param parent Parent object - * - * Sets orthographic projection to the default OpenGL cube (range - * @f$ [-1; 1] @f$ in all directions). - * @see setOrthographic(), setPerspective() - */ - Camera(Object* parent = nullptr); + /** @copydoc Object::Object */ + Camera(ObjectType* parent = nullptr); /** @brief Aspect ratio policy */ inline AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; } @@ -60,39 +67,14 @@ class SCENEGRAPH_EXPORT Camera: public Object { /** @brief Set aspect ratio policy */ void setAspectRatioPolicy(AspectRatioPolicy policy) { _aspectRatioPolicy = policy; } - /** - * @brief Set orthographic projection - * @param size Size of (square) view - * @param near Near clipping plane - * @param far Far clipping plane - * - * The volume of given size will be scaled down to range - * @f$ [-1; 1] @f$ on all directions. - */ - void setOrthographic(GLfloat size, GLfloat near, GLfloat far); - - /** - * @brief Set perspective projection - * @param fov Field of view angle - * @param near Near clipping plane - * @param far Far clipping plane - */ - void setPerspective(GLfloat fov, GLfloat near, GLfloat far); - - /** @brief Near clipping plane */ - inline GLfloat near() const { return _near; } - - /** @brief Far clipping plane */ - inline GLfloat far() const { return _far; } - /** * @brief Camera matrix * * Camera matrix describes world position relative to the camera and is * applied as first. */ - inline Matrix4 cameraMatrix() { - setClean(); + inline MatrixType cameraMatrix() { + this->setClean(); return _cameraMatrix; } @@ -102,7 +84,7 @@ class SCENEGRAPH_EXPORT Camera: public Object { * Projection matrix handles e.g. perspective distortion and is applied * as last. */ - inline Matrix4 projectionMatrix() const { return _projectionMatrix; } + inline MatrixType projectionMatrix() const { return _projectionMatrix; } /** @brief Viewport size */ inline Math::Vector2 viewport() const { return _viewport; } @@ -124,31 +106,88 @@ class SCENEGRAPH_EXPORT Camera: public Object { */ virtual void draw(); - using Object::draw; /* Don't hide Object's draw() */ + using ObjectType::draw; /* Don't hide Object's draw() */ protected: /** * Recalculates camera matrix. */ - void clean(const Matrix4& absoluteTransformation); + void clean(const MatrixType& absoluteTransformation); /** * @brief Draw object children * * Recursively draws all children of the object. */ - void drawChildren(Object* object, const Matrix4& transformationMatrix); + void drawChildren(ObjectType* object, const MatrixType& transformationMatrix); + + #ifndef DOXYGEN_GENERATING_OUTPUT + inline void fixAspectRatio() { + _projectionMatrix = Implementation::Camera::fixAspectRatio(_aspectRatioPolicy, _viewport)*rawProjectionMatrix; + } + + MatrixType rawProjectionMatrix; + AspectRatioPolicy _aspectRatioPolicy; + #endif private: - Matrix4 rawProjectionMatrix; - Matrix4 _projectionMatrix; - Matrix4 _cameraMatrix; - GLfloat _near, _far; + MatrixType _projectionMatrix; + MatrixType _cameraMatrix; Math::Vector2 _viewport; - AspectRatioPolicy _aspectRatioPolicy; +}; + +#ifndef DOXYGEN_GENERATING_OUTPUT +/* These templates are instantiated in source file */ +extern template class SCENEGRAPH_EXPORT Camera; + +namespace Implementation { + template<> class Camera<3> { + public: + static Matrix4 fixAspectRatio(AspectRatioPolicy aspectRatioPolicy, const Math::Vector2& viewport); + }; +} +#endif + +/** @brief %Camera for three-dimensional scenes */ +class SCENEGRAPH_EXPORT Camera3D: public Camera { + public: + /** + * @brief Constructor + * @param parent Parent object + * + * Sets orthographic projection to the default OpenGL cube (range @f$ [-1; 1] @f$ in all directions). + * @see setOrthographic(), setPerspective() + */ + inline Camera3D(Object3D* parent = nullptr): Camera(parent), _near(0.0), _far(0.0) {} + + /** + * @brief Set orthographic projection + * @param size Size of (square) view + * @param near Near clipping plane + * @param far Far clipping plane + * + * The volume of given size will be scaled down to range @f$ [-1; 1] @f$ + * on all directions. + */ + void setOrthographic(GLfloat size, GLfloat near, GLfloat far); + + /** + * @brief Set perspective projection + * @param fov Field of view angle + * @param near Near clipping plane + * @param far Far clipping plane + */ + void setPerspective(GLfloat fov, GLfloat near, GLfloat far); - SCENEGRAPH_LOCAL void fixAspectRatio(); + /** @brief Near clipping plane */ + inline GLfloat near() const { return _near; } + + /** @brief Far clipping plane */ + inline GLfloat far() const { return _far; } + + private: + GLfloat _near, _far; }; }} diff --git a/src/SceneGraph/Light.h b/src/SceneGraph/Light.h index 57ae9e083..3e604f584 100644 --- a/src/SceneGraph/Light.h +++ b/src/SceneGraph/Light.h @@ -28,13 +28,13 @@ namespace Magnum { namespace SceneGraph { * * Provides cached light position. */ -class SCENEGRAPH_EXPORT Light: public Object { +class SCENEGRAPH_EXPORT Light: public Object3D { public: /** * @brief Constructor * @param parent Parent object */ - inline Light(Object* parent = nullptr): Object(parent) {} + inline Light(Object3D* parent = nullptr): Object3D(parent) {} /** * @brief Light position relative to root object (scene) diff --git a/src/SceneGraph/Object.cpp b/src/SceneGraph/Object.cpp index 5ee2d06a6..386cf86e9 100644 --- a/src/SceneGraph/Object.cpp +++ b/src/SceneGraph/Object.cpp @@ -21,44 +21,45 @@ #include "Camera.h" using namespace std; +using namespace Magnum::Math; namespace Magnum { namespace SceneGraph { -Object* Object::setParent(Object* parent) { +template ObjectType* Object::setParent(ObjectType* parent) { /* Skip if nothing to do or this is scene */ - if(_parent == parent || _parent == this) return this; + if(_parent == parent || _parent == this) return static_cast(this); /* Add the object to children list of new parent */ if(parent != nullptr) { /* Only Fry can be his own grandfather */ - Object* p = parent; + ObjectType* p = parent; while(p != nullptr && p->parent() != p) { - if(p == this) return this; + if(p == this) return static_cast(this); p = p->parent(); } - parent->_children.insert(this); + parent->_children.insert(static_cast(this)); } /* Remove the object from old parent children list */ if(_parent != nullptr) - _parent->_children.erase(this); + _parent->_children.erase(static_cast(this)); /* Set new parent */ _parent = parent; setDirty(); - return this; + return static_cast(this); } -Matrix4 Object::absoluteTransformation(Camera* camera) { +template MatrixType Object::absoluteTransformation(CameraType* camera) { /* Shortcut for absolute transformation of camera relative to itself */ - if(camera == this) return Matrix4(); + if(camera == this) return MatrixType(); - Matrix4 t = _transformation; + MatrixType t = _transformation; - Object* p = parent(); + ObjectType* p = parent(); while(p != nullptr) { t = p->transformation()*t; @@ -80,7 +81,7 @@ Matrix4 Object::absoluteTransformation(Camera* camera) { return t; } -Object::~Object() { +template Object::~Object() { /* Remove the object from parent's children */ setParent(nullptr); @@ -89,44 +90,44 @@ Object::~Object() { delete *_children.begin(); } -Scene* Object::scene() { +template SceneType* Object::scene() { /* Goes up the family tree until it finds object which is parent of itself (that's the scene) */ - Object* p = parent(); + ObjectType* p = parent(); while(p != nullptr) { - if(p->parent() == p) return static_cast(p); + if(p->parent() == p) return static_cast(p); p = p->parent(); } return nullptr; } -Object* Object::setTransformation(const Matrix4& transformation) { - if(_parent == this) return this; +template ObjectType* Object::setTransformation(const MatrixType& transformation) { + if(_parent == this) return static_cast(this); _transformation = transformation; setDirty(); - return this; + return static_cast(this); } -void Object::setDirty() { +template void Object::setDirty() { /* The object (and all its children) are already dirty, nothing to do */ if(dirty) return; dirty = true; /* Make all children dirty */ - for(set::iterator it = _children.begin(); it != _children.end(); ++it) + for(typename set::iterator it = _children.begin(); it != _children.end(); ++it) (*it)->setDirty(); } -void Object::setClean() { +template void Object::setClean() { /* The object (and all its parents) are already clean, nothing to do */ if(!dirty) return; /* Collect all parents */ - stack objects; - Object* p = this; + stack objects; + ObjectType* p = static_cast(this); for(;;) { objects.push(p); @@ -138,9 +139,9 @@ void Object::setClean() { } /* Call setClean(const Matrix4&) for every parent and also this object */ - Object* o = objects.top(); + ObjectType* o = objects.top(); objects.pop(); - Matrix4 absoluteTransformation = o->absoluteTransformation(); + MatrixType absoluteTransformation = o->absoluteTransformation(); o->clean(absoluteTransformation); while(!objects.empty()) { o = objects.top(); @@ -150,4 +151,7 @@ void Object::setClean() { } } +/* Explicitly instantiate the templates */ +template class Object; + }} diff --git a/src/SceneGraph/Object.h b/src/SceneGraph/Object.h index 5ddb2c2f3..b86f48d20 100644 --- a/src/SceneGraph/Object.h +++ b/src/SceneGraph/Object.h @@ -27,8 +27,7 @@ namespace Magnum { namespace SceneGraph { -class Scene; -class Camera; +template class Scene; /** @todo User-specified Object implementation: @@ -46,13 +45,15 @@ class Camera; * @todo Transform transformation when changing parent, so the object stays in * place. */ -class SCENEGRAPH_EXPORT Object { - Object(const Object& other) = delete; - Object(Object&& other) = delete; - Object& operator=(const Object& other) = delete; - Object& operator=(Object&& other) = delete; +template class SCENEGRAPH_EXPORT Object { + #ifndef DOXYGEN_GENERATING_OUTPUT + Object(const Object& other) = delete; + Object(Object&& other) = delete; + Object& operator=(const Object& other) = delete; + Object& operator=(Object&& other) = delete; + #endif - friend class Scene; + friend class Scene; public: /** @@ -61,7 +62,7 @@ class SCENEGRAPH_EXPORT Object { * * Sets all transformations to their default values. */ - inline Object(Object* parent = nullptr): _parent(nullptr), dirty(true) { + inline Object(ObjectType* parent = nullptr): _parent(nullptr), dirty(true) { setParent(parent); } @@ -79,16 +80,16 @@ class SCENEGRAPH_EXPORT Object { * @brief %Scene * @return If the object is not assigned to any scene, returns nullptr. */ - Scene* scene(); + SceneType* scene(); /** @brief Parent object */ - inline Object* parent() { return _parent; } + inline ObjectType* parent() { return _parent; } /** @brief Child objects */ - inline const std::set& children() { return _children; } + inline const std::set& children() { return _children; } /** @brief Set parent object */ - Object* setParent(Object* parent); + ObjectType* setParent(ObjectType* parent); /*@}*/ @@ -108,7 +109,7 @@ class SCENEGRAPH_EXPORT Object { }; /** @brief Transformation */ - inline Matrix4 transformation() const { + inline MatrixType transformation() const { return _transformation; } @@ -123,50 +124,20 @@ class SCENEGRAPH_EXPORT Object { * objects every time it is asked, unless this function is * reimplemented in a different way. */ - virtual Matrix4 absoluteTransformation(Camera* camera = nullptr); + virtual MatrixType absoluteTransformation(CameraType* camera = nullptr); /** @brief Set transformation */ - Object* setTransformation(const Matrix4& transformation); + ObjectType* setTransformation(const MatrixType& transformation); /** * @brief Multiply transformation * @param transformation Transformation * @param type Transformation type */ - inline Object* multiplyTransformation(const Matrix4& transformation, Transformation type = Transformation::Global) { + inline ObjectType* multiplyTransformation(const MatrixType& transformation, Transformation type = Transformation::Global) { setTransformation(type == Transformation::Global ? transformation*_transformation : _transformation*transformation); - return this; - } - - /** - * @brief Translate object - * - * Same as calling multiplyTransformation() with Matrix4::translation(). - */ - inline Object* translate(Vector3 vec, Transformation type = Transformation::Global) { - multiplyTransformation(Matrix4::translation(vec), type); - return this; - } - - /** - * @brief Scale object - * - * Same as calling multiplyTransformation() with Matrix4::scaling(). - */ - inline Object* scale(Vector3 vec, Transformation type = Transformation::Global) { - multiplyTransformation(Matrix4::scaling(vec), type); - return this; - } - - /** - * @brief Rotate object - * - * Same as calling multiplyTransformation() with Matrix4::rotation(). - */ - inline Object* rotate(GLfloat angle, Vector3 vec, Transformation type = Transformation::Global) { - multiplyTransformation(Matrix4::rotation(angle, vec), type); - return this; + return static_cast(this); } /*@}*/ @@ -180,7 +151,7 @@ class SCENEGRAPH_EXPORT Object { * * Default implementation does nothing. */ - virtual void draw(const Matrix4& transformationMatrix, Camera* camera); + virtual void draw(const MatrixType& transformationMatrix, CameraType* camera); /** @{ @name Caching helpers * @@ -255,20 +226,66 @@ class SCENEGRAPH_EXPORT Object { * } * @endcode */ - virtual void clean(const Matrix4& absoluteTransformation); + virtual void clean(const MatrixType& absoluteTransformation); /*@}*/ private: - Object* _parent; - std::set _children; - Matrix4 _transformation; + ObjectType* _parent; + std::set _children; + MatrixType _transformation; bool dirty; }; /* Implementations for inline functions with unused parameters */ -inline void Object::draw(const Matrix4&, Camera*) {} -inline void Object::clean(const Matrix4&) { dirty = false; } +template inline void Object::draw(const MatrixType&, CameraType*) {} +template inline void Object::clean(const MatrixType&) { dirty = false; } + +class Camera3D; +class Object3D; +typedef Scene Scene3D; + +#ifndef DOXYGEN_GENERATING_OUTPUT +/* These templates are instantiated in source file */ +extern template class SCENEGRAPH_EXPORT Object; +#endif + +/** @brief Three-dimensional object */ +class SCENEGRAPH_EXPORT Object3D: public Object { + public: + /** @copydoc Object::Object */ + inline Object3D(Object3D* parent = nullptr): Object(parent) {} + + /** + * @brief Translate object + * + * Same as calling multiplyTransformation() with Matrix4::translation(). + */ + inline Object3D* translate(const Vector3& vec, Transformation type = Transformation::Global) { + multiplyTransformation(Matrix4::translation(vec), type); + return this; + } + + /** + * @brief Scale object + * + * Same as calling multiplyTransformation() with Matrix4::scaling(). + */ + inline Object3D* scale(const Vector3& vec, Transformation type = Transformation::Global) { + multiplyTransformation(Matrix4::scaling(vec), type); + return this; + } + + /** + * @brief Rotate object + * + * Same as calling multiplyTransformation() with Matrix4::rotation(). + */ + inline Object3D* rotate(GLfloat angle, const Vector3& vec, Transformation type = Transformation::Global) { + multiplyTransformation(Matrix4::rotation(angle, vec), type); + return this; + } +}; }} diff --git a/src/SceneGraph/Scene.h b/src/SceneGraph/Scene.h index 63cedc905..35b36e501 100644 --- a/src/SceneGraph/Scene.h +++ b/src/SceneGraph/Scene.h @@ -24,22 +24,27 @@ namespace Magnum { namespace SceneGraph { /** @brief %Scene */ -class SCENEGRAPH_EXPORT Scene: public Object { +template class SCENEGRAPH_EXPORT Scene: public ObjectType { public: /** @brief Constructor */ - inline Scene() { _parent = this; } + inline Scene() { this->_parent = this; } - void setParent(Object* parent) = delete; - void setTransformation(const Matrix4& transformation) = delete; - void multiplyTransformation(const Matrix4& transformation, Transformation type = Transformation::Global) = delete; - void translate(Vector3 vec, Transformation type = Transformation::Global) = delete; - void scale(Vector3 vec, Transformation type = Transformation::Global) = delete; - void rotate(GLfloat angle, Vector3 vec, Transformation type = Transformation::Global) = delete; + #ifndef DOXYGEN_GENERATING_OUTPUT + void setParent(ObjectType* parent) = delete; + void setTransformation(const MatrixType& transformation) = delete; + void multiplyTransformation(const MatrixType& transformation, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; + void translate(const VectorType& vec, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; + void scale(const VectorType& vec, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; + void rotate(GLfloat angle, const VectorType& vec, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; + #endif private: - inline void draw(const Magnum::Matrix4&, Camera*) {} + inline void draw(const MatrixType&, CameraType*) {} }; +/** @brief Three-dimensional scene */ +typedef Scene Scene3D; + }} #endif diff --git a/src/SceneGraph/Test/CameraTest.cpp b/src/SceneGraph/Test/CameraTest.cpp index 508705b43..53e4cbe42 100644 --- a/src/SceneGraph/Test/CameraTest.cpp +++ b/src/SceneGraph/Test/CameraTest.cpp @@ -27,7 +27,7 @@ CameraTest::CameraTest() { } void CameraTest::orthographic() { - Camera camera; + Camera3D camera; camera.setOrthographic(5, 1, 9); Matrix4 a(0.4f, 0.0f, 0.0f, 0.0f, @@ -39,7 +39,7 @@ void CameraTest::orthographic() { } void CameraTest::perspective() { - Camera camera; + Camera3D camera; camera.setPerspective(deg(27.0f), 32.0f, 100); Matrix4 a(4.1652994f, 0.0f, 0.0f, 0.0f, diff --git a/src/SceneGraph/Test/ObjectTest.cpp b/src/SceneGraph/Test/ObjectTest.cpp index 5a4f22a6e..06248e097 100644 --- a/src/SceneGraph/Test/ObjectTest.cpp +++ b/src/SceneGraph/Test/ObjectTest.cpp @@ -35,10 +35,10 @@ ObjectTest::ObjectTest() { } void ObjectTest::parenting() { - Object root; + Object3D root; - Object* childOne = new Object(&root); - Object* childTwo = new Object(&root); + Object3D* childOne = new Object3D(&root); + Object3D* childTwo = new Object3D(&root); CORRADE_VERIFY(childOne->parent() == &root); CORRADE_COMPARE(root.children().size(), 2); @@ -62,8 +62,8 @@ void ObjectTest::parenting() { } void ObjectTest::transformation() { - Object o; - Object o2; + Object3D o; + Object3D o2; o.setTransformation(Matrix4::translation(Vector3::xAxis(1.0f))); o2.translate(Vector3::xAxis(1.0f)); @@ -74,8 +74,8 @@ void ObjectTest::transformation() { Matrix4::translation(Vector3::xAxis(1.0f))); CORRADE_COMPARE(o2.transformation(), o.transformation()); - o.multiplyTransformation(Matrix4::scaling(Vector3(2.0f)), Object::Transformation::Local); - o2.scale(Vector3(2.0f), Object::Transformation::Local); + o.multiplyTransformation(Matrix4::scaling(Vector3(2.0f)), Object3D::Transformation::Local); + o2.scale(Vector3(2.0f), Object3D::Transformation::Local); CORRADE_COMPARE(o.transformation(), Matrix4::rotation(deg(35.0f), Vector3::zAxis())* Matrix4::translation(Vector3::xAxis(1.0f))* Matrix4::scaling(Vector3(2.0f))); @@ -86,56 +86,56 @@ void ObjectTest::absoluteTransformationWrongCamera() { stringstream ss; Error::setOutput(&ss); - Scene s; - Object o(&s); + Scene3D s; + Object3D o(&s); o.translate(Vector3::yAxis()); - Camera c; + Camera3D c; CORRADE_COMPARE(o.absoluteTransformation(&c), Matrix4::translation(Vector3::yAxis())); CORRADE_COMPARE(ss.str(), "Object::absoluteTransformation(): the camera is not part of the same scene as object!\n"); ss.str(""); - Object o2; + Object3D o2; o2.translate(Vector3::xAxis()); CORRADE_COMPARE(o2.absoluteTransformation(&c), Matrix4::translation(Vector3::xAxis())); CORRADE_COMPARE(ss.str(), "Object::absoluteTransformation(): the object is not part of camera scene!\n"); } void ObjectTest::absoluteTransformation() { - Scene s; - Camera c(&s); + Scene3D s; + Camera3D c(&s); c.translate(Vector3::zAxis(2.0f)); CORRADE_COMPARE(s.absoluteTransformation(), Matrix4()); CORRADE_COMPARE(c.absoluteTransformation(&c), Matrix4()); - Object o(&s); + Object3D o(&s); o.scale(Vector3(2.0f)); - Object o2(&o); + Object3D o2(&o); o.rotate(deg(90.0f), Vector3::yAxis()); CORRADE_COMPARE(o2.absoluteTransformation(), Matrix4::scaling(Vector3(2.0f))*Matrix4::rotation(deg(90.0f), Vector3::yAxis())); CORRADE_COMPARE(o2.absoluteTransformation(&c), (Matrix4::translation(Vector3::zAxis(2.0f)).inverted())*Matrix4::scaling(Vector3(2.0f))*Matrix4::rotation(deg(90.0f), Vector3::yAxis())); - Object o3; + Object3D o3; o3.translate({1.0f, 2.0f, 3.0f}); CORRADE_COMPARE(o3.absoluteTransformation(), Matrix4::translation({1.0f, 2.0f, 3.0f})); } void ObjectTest::scene() { - Scene scene; + Scene3D scene; - Object* childOne = new Object(&scene); - Object* childTwo = new Object(childOne); + Object3D* childOne = new Object3D(&scene); + Object3D* childTwo = new Object3D(childOne); - Object orphan; - Object* childOfOrphan = new Object(&orphan); + Object3D orphan; + Object3D* childOfOrphan = new Object3D(&orphan); CORRADE_VERIFY(childTwo->scene() == &scene); CORRADE_VERIFY(childOfOrphan->scene() == nullptr); } void ObjectTest::dirty() { - Scene scene; + Scene3D scene; CleaningObject* childOne = new CleaningObject(&scene); childOne->scale(Vector3(2.0f)); diff --git a/src/SceneGraph/Test/ObjectTest.h b/src/SceneGraph/Test/ObjectTest.h index 8505bd59e..01149310f 100644 --- a/src/SceneGraph/Test/ObjectTest.h +++ b/src/SceneGraph/Test/ObjectTest.h @@ -33,12 +33,12 @@ class ObjectTest: public Corrade::TestSuite::Tester { void dirty(); private: - class CleaningObject: public Object { + class CleaningObject: public Object3D { public: - CleaningObject(Object* parent = nullptr): Object(parent) {} + CleaningObject(Object3D* parent = nullptr): Object3D(parent) {} inline void clean(const Matrix4& absoluteTransformation) { - Object::clean(absoluteTransformation); + Object3D::clean(absoluteTransformation); cleanedAbsoluteTransformation = absoluteTransformation; } diff --git a/src/SceneGraph/Test/SceneTest.cpp b/src/SceneGraph/Test/SceneTest.cpp index 132c09e0b..e2df35aa1 100644 --- a/src/SceneGraph/Test/SceneTest.cpp +++ b/src/SceneGraph/Test/SceneTest.cpp @@ -27,21 +27,21 @@ SceneTest::SceneTest() { } void SceneTest::transformation() { - Scene scene; + Scene3D scene; - Object* scenePointer = &scene; + Object3D* scenePointer = &scene; scenePointer->setTransformation(Matrix4::translation({1.0f, 1.0f, 1.0f})); CORRADE_COMPARE(scene.transformation(), Matrix4()); } void SceneTest::parent() { - Scene scene; + Scene3D scene; CORRADE_VERIFY(scene.parent() == &scene); /* Scene parent cannot be changed */ - Object* scenePointer = &scene; - Object object; + Object3D* scenePointer = &scene; + Object3D object; scenePointer->setParent(&object); CORRADE_VERIFY(scene.parent() == &scene); CORRADE_VERIFY(scene.children().empty());