From cef2a19b078d25472e1af1b8d9b1f53214d93cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 16 Sep 2012 00:56:43 +0200 Subject: [PATCH] Moved template list of SceneGraph objects into traits class. Beside better readability it is now more future proof, as objects with double types etc. and new templated types can be added more easily. --- src/SceneGraph/Camera.cpp | 28 +++++++------- src/SceneGraph/Camera.h | 32 ++++++++-------- src/SceneGraph/Object.cpp | 16 ++++---- src/SceneGraph/Object.h | 79 +++++++++++++++++++++++++++++---------- src/SceneGraph/Scene.h | 20 +++++----- 5 files changed, 108 insertions(+), 67 deletions(-) diff --git a/src/SceneGraph/Camera.cpp b/src/SceneGraph/Camera.cpp index b73cb61d2..5e5693261 100644 --- a/src/SceneGraph/Camera.cpp +++ b/src/SceneGraph/Camera.cpp @@ -45,40 +45,40 @@ template Matrix4 aspectRatioFix(AspectRatioPolicy, const Vector2&, cons } #endif -template Camera::Camera(ObjectType* parent): ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {} +template Camera::Camera(typename Object::ObjectType* parent): Object::ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {} -template CameraType* Camera::setAspectRatioPolicy(AspectRatioPolicy policy) { +template typename Object::CameraType* Camera::setAspectRatioPolicy(AspectRatioPolicy policy) { _aspectRatioPolicy = policy; fixAspectRatio(); - return static_cast(this); + return static_cast::CameraType*>(this); } -template void Camera::setViewport(const Math::Vector2& size) { +template void Camera::setViewport(const Math::Vector2& size) { _viewport = size; fixAspectRatio(); } -template void Camera::clean(const MatrixType& absoluteTransformation) { - ObjectType::clean(absoluteTransformation); +template void Camera::clean(const typename Object::MatrixType& absoluteTransformation) { + Object::ObjectType::clean(absoluteTransformation); _cameraMatrix = absoluteTransformation.inverted(); } -template void Camera::draw() { - SceneType* s = this->scene(); +template void Camera::draw() { + typename Object::SceneType* s = this->scene(); CORRADE_ASSERT(s, "Camera: cannot draw without camera attached to scene", ); /* Recursively draw child objects */ drawChildren(s, cameraMatrix()); } -template void Camera::drawChildren(ObjectType* object, const MatrixType& transformationMatrix) { - for(ObjectType* i = object->firstChild(); i; i = i->nextSibling()) { +template void Camera::drawChildren(typename Object::ObjectType* object, const typename Object::MatrixType& transformationMatrix) { + for(typename Object::ObjectType* i = object->firstChild(); i; i = i->nextSibling()) { /* Transformation matrix for the object */ - MatrixType matrix = transformationMatrix*i->transformation(); + typename Object::MatrixType matrix = transformationMatrix*i->transformation(); /* Draw the object and its children */ - i->draw(matrix, static_cast(this)); + i->draw(matrix, static_cast::CameraType*>(this)); drawChildren(i, matrix); } } @@ -128,7 +128,7 @@ Camera3D* Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { } /* Explicitly instantiate the templates */ -template class Camera; -template class Camera; +template class Camera<2>; +template class Camera<3>; }} diff --git a/src/SceneGraph/Camera.h b/src/SceneGraph/Camera.h index a335beb77..d4541ed1e 100644 --- a/src/SceneGraph/Camera.h +++ b/src/SceneGraph/Camera.h @@ -49,7 +49,7 @@ namespace Implementation { /** @brief %Camera object */ -template class SCENEGRAPH_EXPORT Camera: public ObjectType { +template class SCENEGRAPH_EXPORT Camera: public Object::ObjectType { public: /** * @brief Aspect ratio policy @@ -67,7 +67,7 @@ template::ObjectType* parent = nullptr); /** @brief Aspect ratio policy */ inline AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; } @@ -76,7 +76,7 @@ template::CameraType* setAspectRatioPolicy(AspectRatioPolicy policy); /** * @brief Camera matrix @@ -84,7 +84,7 @@ template::MatrixType cameraMatrix() { this->setClean(); return _cameraMatrix; } @@ -96,7 +96,7 @@ template::MatrixType projectionMatrix() const { return _projectionMatrix; } /** * @brief Size of (near) XY plane in current projection @@ -127,41 +127,41 @@ template::ObjectType::draw; /* Don't hide Object's draw() */ protected: /** * Recalculates camera matrix. */ - void clean(const MatrixType& absoluteTransformation); + void clean(const typename Object::MatrixType& absoluteTransformation); /** * @brief Draw object children * * Recursively draws all children of the object. */ - void drawChildren(ObjectType* object, const MatrixType& transformationMatrix); + void drawChildren(typename Object::ObjectType* object, const typename Object::MatrixType& transformationMatrix); #ifndef DOXYGEN_GENERATING_OUTPUT inline void fixAspectRatio() { - _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix; + _projectionMatrix = Implementation::aspectRatioFix::MatrixType>(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix; } - MatrixType rawProjectionMatrix; + typename Object::MatrixType rawProjectionMatrix; AspectRatioPolicy _aspectRatioPolicy; #endif private: - MatrixType _projectionMatrix; - MatrixType _cameraMatrix; + typename Object::MatrixType _projectionMatrix; + typename Object::MatrixType _cameraMatrix; Math::Vector2 _viewport; }; #ifndef DOXYGEN_GENERATING_OUTPUT /* These templates are instantiated in source file */ -extern template class SCENEGRAPH_EXPORT Camera; -extern template class SCENEGRAPH_EXPORT Camera; +extern template class SCENEGRAPH_EXPORT Camera<2>; +extern template class SCENEGRAPH_EXPORT Camera<3>; namespace Implementation { template<> class Camera<2> { @@ -180,7 +180,7 @@ namespace Implementation { #endif /** @brief %Camera for two-dimensional scenes */ -class SCENEGRAPH_EXPORT Camera2D: public Camera { +class SCENEGRAPH_EXPORT Camera2D: public Camera<2> { public: /** * @brief Constructor @@ -203,7 +203,7 @@ class SCENEGRAPH_EXPORT Camera2D: public Camera { +class SCENEGRAPH_EXPORT Camera3D: public Camera<3> { public: /** * @brief Constructor diff --git a/src/SceneGraph/Object.cpp b/src/SceneGraph/Object.cpp index f3de86b1c..5b437a14e 100644 --- a/src/SceneGraph/Object.cpp +++ b/src/SceneGraph/Object.cpp @@ -25,7 +25,7 @@ using namespace Magnum::Math; namespace Magnum { namespace SceneGraph { -template ObjectType* Object::setParent(ObjectType* parent) { +template typename Object::ObjectType* Object::setParent(ObjectType* parent) { /* Skip if nothing to do or this is scene */ if(this->parent() == parent || isScene()) return static_cast(this); @@ -49,7 +49,7 @@ template(this); } -template MatrixType Object::absoluteTransformation(CameraType* camera) { +template typename Object::MatrixType Object::absoluteTransformation(CameraType* camera) { /* Shortcut for absolute transformation of camera relative to itself */ if(camera == this) return MatrixType(); @@ -77,7 +77,7 @@ template SceneType* Object::scene() { +template typename Object::SceneType* Object::scene() { /* Goes up the family tree until it finds object which is parent of itself (that's the scene) */ ObjectType* p = parent(); @@ -89,7 +89,7 @@ template ObjectType* Object::setTransformation(const MatrixType& transformation) { +template typename Object::ObjectType* Object::setTransformation(const MatrixType& transformation) { /* Setting transformation is forbidden for the scene */ /** @todo Assert for this? */ if(isScene()) return static_cast(this); @@ -99,7 +99,7 @@ template(this); } -template void Object::setDirty() { +template void Object::setDirty() { /* The object (and all its children) are already dirty, nothing to do */ if(dirty) return; @@ -110,7 +110,7 @@ templatesetDirty(); } -template void Object::setClean() { +template void Object::setClean() { /* The object (and all its parents) are already clean, nothing to do */ if(!dirty) return; @@ -141,7 +141,7 @@ template; -template class Object; +template class Object<2>; +template class Object<3>; }} diff --git a/src/SceneGraph/Object.h b/src/SceneGraph/Object.h index 33afb906a..4890ee622 100644 --- a/src/SceneGraph/Object.h +++ b/src/SceneGraph/Object.h @@ -28,6 +28,38 @@ namespace Magnum { namespace SceneGraph { +class Camera2D; +class Camera3D; +class Object2D; +class Object3D; +template class Scene; +typedef Scene<2> Scene2D; +typedef Scene<3> Scene3D; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct ObjectDimensionTraits {}; + + template<> struct ObjectDimensionTraits<2> { + static const size_t Dimensions = 2; + typedef Vector2 VectorType; + typedef Matrix3 MatrixType; + typedef Object2D ObjectType; + typedef Camera2D CameraType; + typedef Scene2D SceneType; + }; + + template<> struct ObjectDimensionTraits<3> { + static const size_t Dimensions = 3; + typedef Vector3 VectorType; + typedef Matrix4 MatrixType; + typedef Object3D ObjectType; + typedef Camera3D CameraType; + typedef Scene3D SceneType; + }; +} +#endif + /** @todo User-specified Object implementation: - for front-to-back sorting, LoD changes etc. @@ -44,15 +76,32 @@ namespace Magnum { namespace SceneGraph { * @todo Transform transformation when changing parent, so the object stays in * place. */ -template class SCENEGRAPH_EXPORT Object: public Corrade::Containers::LinkedList, public Corrade::Containers::LinkedListItem { +template class SCENEGRAPH_EXPORT Object: public Corrade::Containers::LinkedList::ObjectType>, public Corrade::Containers::LinkedListItem::ObjectType, typename Implementation::ObjectDimensionTraits::ObjectType> { #ifndef DOXYGEN_GENERATING_OUTPUT - Object(const Object& other) = delete; - Object(Object&& other) = delete; - Object& operator=(const Object& other) = delete; - Object& operator=(Object&& other) = delete; + Object(const Object& other) = delete; + Object(Object&& other) = delete; + Object& operator=(const Object& other) = delete; + Object& operator=(Object&& other) = delete; #endif public: + static const size_t Dimensions = dimensions; /**< @brief %Object dimension count */ + + /** @brief %Vector type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::VectorType VectorType; + + /** @brief %Matrix type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::MatrixType MatrixType; + + /** @brief %Object type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::ObjectType ObjectType; + + /** @brief %Camera type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::CameraType CameraType; + + /** @brief %Scene type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::SceneType SceneType; + /** * @brief Constructor * @param parent Parent object @@ -261,25 +310,17 @@ template inline void Object::draw(const MatrixType&, CameraType*) {} -template inline void Object::clean(const MatrixType&) { dirty = false; } - -class Camera2D; -class Camera3D; -class Object2D; -class Object3D; -template class Scene; -typedef Scene Scene2D; -typedef Scene Scene3D; +template inline void Object::draw(const MatrixType&, CameraType*) {} +template inline void Object::clean(const MatrixType&) { dirty = false; } #ifndef DOXYGEN_GENERATING_OUTPUT /* These templates are instantiated in source file */ -extern template class SCENEGRAPH_EXPORT Object; -extern template class SCENEGRAPH_EXPORT Object; +extern template class SCENEGRAPH_EXPORT Object<2>; +extern template class SCENEGRAPH_EXPORT Object<3>; #endif /** @brief Two-dimensional object */ -class SCENEGRAPH_EXPORT Object2D: public Object { +class SCENEGRAPH_EXPORT Object2D: public Object<2> { public: /** @copydoc Object::Object */ inline Object2D(Object2D* parent = nullptr): Object(parent) {} @@ -330,7 +371,7 @@ class SCENEGRAPH_EXPORT Object2D: public Object { +class SCENEGRAPH_EXPORT Object3D: public Object<3> { public: /** @copydoc Object::Object */ inline Object3D(Object3D* parent = nullptr): Object(parent) {} diff --git a/src/SceneGraph/Scene.h b/src/SceneGraph/Scene.h index 2fd2e6fe9..9874f40c4 100644 --- a/src/SceneGraph/Scene.h +++ b/src/SceneGraph/Scene.h @@ -24,30 +24,30 @@ namespace Magnum { namespace SceneGraph { /** @brief %Scene */ -template class SCENEGRAPH_EXPORT Scene: public ObjectType { +template class SCENEGRAPH_EXPORT Scene: public Object::ObjectType { public: /** @copydoc Object::isScene() */ inline bool isScene() const { return true; } /** @todo Some deleted functions belong only to Scene2D, some only to Scene3D - what to do? */ #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; + void setParent(typename Object::ObjectType* parent) = delete; + void setTransformation(const typename Object::MatrixType& transformation) = delete; + void multiplyTransformation(const typename Object::MatrixType& transformation, typename Object::Transformation type = Object::Transformation::Global) = delete; + void translate(const typename Object::VectorType& vec, typename Object::Transformation type = Object::Transformation::Global) = delete; + void scale(const typename Object::VectorType& vec, typename Object::Transformation type = Object::Transformation::Global) = delete; + void rotate(GLfloat angle, const typename Object::VectorType& vec, typename Object::Transformation type = Object::Transformation::Global) = delete; #endif private: - inline void draw(const MatrixType&, CameraType*) {} + inline void draw(const typename Object::MatrixType&, typename Object::CameraType*) {} }; /** @brief Two-dimensional scene */ -typedef Scene Scene2D; +typedef Scene<2> Scene2D; /** @brief Three-dimensional scene */ -typedef Scene Scene3D; +typedef Scene<3> Scene3D; }}