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; }}