Browse Source

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.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
cef2a19b07
  1. 28
      src/SceneGraph/Camera.cpp
  2. 32
      src/SceneGraph/Camera.h
  3. 16
      src/SceneGraph/Object.cpp
  4. 79
      src/SceneGraph/Object.h
  5. 20
      src/SceneGraph/Scene.h

28
src/SceneGraph/Camera.cpp

@ -45,40 +45,40 @@ template Matrix4 aspectRatioFix<Matrix4>(AspectRatioPolicy, const Vector2&, cons
}
#endif
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::Camera(ObjectType* parent): ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {}
template<size_t dimensions> Camera<dimensions>::Camera(typename Object<dimensions>::ObjectType* parent): Object<dimensions>::ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> CameraType* Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setAspectRatioPolicy(AspectRatioPolicy policy) {
template<size_t dimensions> typename Object<dimensions>::CameraType* Camera<dimensions>::setAspectRatioPolicy(AspectRatioPolicy policy) {
_aspectRatioPolicy = policy;
fixAspectRatio();
return static_cast<CameraType*>(this);
return static_cast<typename Object<dimensions>::CameraType*>(this);
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setViewport(const Math::Vector2<GLsizei>& size) {
template<size_t dimensions> void Camera<dimensions>::setViewport(const Math::Vector2<GLsizei>& size) {
_viewport = size;
fixAspectRatio();
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::clean(const MatrixType& absoluteTransformation) {
ObjectType::clean(absoluteTransformation);
template<size_t dimensions> void Camera<dimensions>::clean(const typename Object<dimensions>::MatrixType& absoluteTransformation) {
Object<dimensions>::ObjectType::clean(absoluteTransformation);
_cameraMatrix = absoluteTransformation.inverted();
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::draw() {
SceneType* s = this->scene();
template<size_t dimensions> void Camera<dimensions>::draw() {
typename Object<dimensions>::SceneType* s = this->scene();
CORRADE_ASSERT(s, "Camera: cannot draw without camera attached to scene", );
/* Recursively draw child objects */
drawChildren(s, cameraMatrix());
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Camera<MatrixType, VectorType, ObjectType, SceneType, CameraType>::drawChildren(ObjectType* object, const MatrixType& transformationMatrix) {
for(ObjectType* i = object->firstChild(); i; i = i->nextSibling()) {
template<size_t dimensions> void Camera<dimensions>::drawChildren(typename Object<dimensions>::ObjectType* object, const typename Object<dimensions>::MatrixType& transformationMatrix) {
for(typename Object<dimensions>::ObjectType* i = object->firstChild(); i; i = i->nextSibling()) {
/* Transformation matrix for the object */
MatrixType matrix = transformationMatrix*i->transformation();
typename Object<dimensions>::MatrixType matrix = transformationMatrix*i->transformation();
/* Draw the object and its children */
i->draw(matrix, static_cast<CameraType*>(this));
i->draw(matrix, static_cast<typename Object<dimensions>::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<Matrix3, Vector2, Object2D, Scene2D, Camera2D>;
template class Camera<Matrix4, Vector3, Object3D, Scene3D, Camera3D>;
template class Camera<2>;
template class Camera<3>;
}}

32
src/SceneGraph/Camera.h

@ -49,7 +49,7 @@ namespace Implementation {
/**
@brief %Camera object
*/
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> class SCENEGRAPH_EXPORT Camera: public ObjectType {
template<size_t dimensions> class SCENEGRAPH_EXPORT Camera: public Object<dimensions>::ObjectType {
public:
/**
* @brief Aspect ratio policy
@ -67,7 +67,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
#endif
/** @copydoc Object::Object */
Camera(ObjectType* parent = nullptr);
Camera(typename Object<dimensions>::ObjectType* parent = nullptr);
/** @brief Aspect ratio policy */
inline AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; }
@ -76,7 +76,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
* @brief Set aspect ratio policy
* @return Pointer to self (for method chaining)
*/
CameraType* setAspectRatioPolicy(AspectRatioPolicy policy);
typename Object<dimensions>::CameraType* setAspectRatioPolicy(AspectRatioPolicy policy);
/**
* @brief Camera matrix
@ -84,7 +84,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
* Camera matrix describes world position relative to the camera and is
* applied as first.
*/
inline MatrixType cameraMatrix() {
inline typename Object<dimensions>::MatrixType cameraMatrix() {
this->setClean();
return _cameraMatrix;
}
@ -96,7 +96,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
* as last.
* @see projectionSize()
*/
inline MatrixType projectionMatrix() const { return _projectionMatrix; }
inline typename Object<dimensions>::MatrixType projectionMatrix() const { return _projectionMatrix; }
/**
* @brief Size of (near) XY plane in current projection
@ -127,41 +127,41 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
*/
virtual void draw();
using ObjectType::draw; /* Don't hide Object's draw() */
using Object<dimensions>::ObjectType::draw; /* Don't hide Object's draw() */
protected:
/**
* Recalculates camera matrix.
*/
void clean(const MatrixType& absoluteTransformation);
void clean(const typename Object<dimensions>::MatrixType& absoluteTransformation);
/**
* @brief Draw object children
*
* Recursively draws all children of the object.
*/
void drawChildren(ObjectType* object, const MatrixType& transformationMatrix);
void drawChildren(typename Object<dimensions>::ObjectType* object, const typename Object<dimensions>::MatrixType& transformationMatrix);
#ifndef DOXYGEN_GENERATING_OUTPUT
inline void fixAspectRatio() {
_projectionMatrix = Implementation::aspectRatioFix<MatrixType>(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix;
_projectionMatrix = Implementation::aspectRatioFix<typename Object<dimensions>::MatrixType>(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix;
}
MatrixType rawProjectionMatrix;
typename Object<dimensions>::MatrixType rawProjectionMatrix;
AspectRatioPolicy _aspectRatioPolicy;
#endif
private:
MatrixType _projectionMatrix;
MatrixType _cameraMatrix;
typename Object<dimensions>::MatrixType _projectionMatrix;
typename Object<dimensions>::MatrixType _cameraMatrix;
Math::Vector2<GLsizei> _viewport;
};
#ifndef DOXYGEN_GENERATING_OUTPUT
/* These templates are instantiated in source file */
extern template class SCENEGRAPH_EXPORT Camera<Matrix3, Vector2, Object2D, Scene2D, Camera2D>;
extern template class SCENEGRAPH_EXPORT Camera<Matrix4, Vector3, Object3D, Scene3D, Camera3D>;
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<Matrix3, Vector2, Object2D, Scene2D, Camera2D> {
class SCENEGRAPH_EXPORT Camera2D: public Camera<2> {
public:
/**
* @brief Constructor
@ -203,7 +203,7 @@ class SCENEGRAPH_EXPORT Camera2D: public Camera<Matrix3, Vector2, Object2D, Scen
};
/** @brief %Camera for three-dimensional scenes */
class SCENEGRAPH_EXPORT Camera3D: public Camera<Matrix4, Vector3, Object3D, Scene3D, Camera3D> {
class SCENEGRAPH_EXPORT Camera3D: public Camera<3> {
public:
/**
* @brief Constructor

16
src/SceneGraph/Object.cpp

@ -25,7 +25,7 @@ using namespace Magnum::Math;
namespace Magnum { namespace SceneGraph {
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> ObjectType* Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setParent(ObjectType* parent) {
template<size_t dimensions> typename Object<dimensions>::ObjectType* Object<dimensions>::setParent(ObjectType* parent) {
/* Skip if nothing to do or this is scene */
if(this->parent() == parent || isScene()) return static_cast<ObjectType*>(this);
@ -49,7 +49,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
return static_cast<ObjectType*>(this);
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> MatrixType Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::absoluteTransformation(CameraType* camera) {
template<size_t dimensions> typename Object<dimensions>::MatrixType Object<dimensions>::absoluteTransformation(CameraType* camera) {
/* Shortcut for absolute transformation of camera relative to itself */
if(camera == this) return MatrixType();
@ -77,7 +77,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
return t;
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> SceneType* Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::scene() {
template<size_t dimensions> typename Object<dimensions>::SceneType* Object<dimensions>::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<class MatrixType, class VectorType, class ObjectType, class SceneType,
return nullptr;
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> ObjectType* Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setTransformation(const MatrixType& transformation) {
template<size_t dimensions> typename Object<dimensions>::ObjectType* Object<dimensions>::setTransformation(const MatrixType& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
if(isScene()) return static_cast<ObjectType*>(this);
@ -99,7 +99,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
return static_cast<ObjectType*>(this);
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setDirty() {
template<size_t dimensions> void Object<dimensions>::setDirty() {
/* The object (and all its children) are already dirty, nothing to do */
if(dirty) return;
@ -110,7 +110,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
i->setDirty();
}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> void Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::setClean() {
template<size_t dimensions> void Object<dimensions>::setClean() {
/* The object (and all its parents) are already clean, nothing to do */
if(!dirty) return;
@ -141,7 +141,7 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
}
/* Explicitly instantiate the templates */
template class Object<Matrix3, Vector2, Object2D, Scene2D, Camera2D>;
template class Object<Matrix4, Vector3, Object3D, Scene3D, Camera3D>;
template class Object<2>;
template class Object<3>;
}}

79
src/SceneGraph/Object.h

@ -28,6 +28,38 @@
namespace Magnum { namespace SceneGraph {
class Camera2D;
class Camera3D;
class Object2D;
class Object3D;
template<size_t dimensions> class Scene;
typedef Scene<2> Scene2D;
typedef Scene<3> Scene3D;
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<size_t dimensions> 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 MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> class SCENEGRAPH_EXPORT Object: public Corrade::Containers::LinkedList<ObjectType>, public Corrade::Containers::LinkedListItem<ObjectType, ObjectType> {
template<size_t dimensions> class SCENEGRAPH_EXPORT Object: public Corrade::Containers::LinkedList<typename Implementation::ObjectDimensionTraits<dimensions>::ObjectType>, public Corrade::Containers::LinkedListItem<typename Implementation::ObjectDimensionTraits<dimensions>::ObjectType, typename Implementation::ObjectDimensionTraits<dimensions>::ObjectType> {
#ifndef DOXYGEN_GENERATING_OUTPUT
Object(const Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>& other) = delete;
Object(Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>&& other) = delete;
Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>& operator=(const Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>& other) = delete;
Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>& operator=(Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>&& other) = delete;
Object(const Object<dimensions>& other) = delete;
Object(Object<dimensions>&& other) = delete;
Object<dimensions>& operator=(const Object<dimensions>& other) = delete;
Object<dimensions>& operator=(Object<dimensions>&& 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<Dimensions>::VectorType VectorType;
/** @brief %Matrix type for given dimension count */
typedef typename Implementation::ObjectDimensionTraits<Dimensions>::MatrixType MatrixType;
/** @brief %Object type for given dimension count */
typedef typename Implementation::ObjectDimensionTraits<Dimensions>::ObjectType ObjectType;
/** @brief %Camera type for given dimension count */
typedef typename Implementation::ObjectDimensionTraits<Dimensions>::CameraType CameraType;
/** @brief %Scene type for given dimension count */
typedef typename Implementation::ObjectDimensionTraits<Dimensions>::SceneType SceneType;
/**
* @brief Constructor
* @param parent Parent object
@ -261,25 +310,17 @@ template<class MatrixType, class VectorType, class ObjectType, class SceneType,
};
/* Implementations for inline functions with unused parameters */
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> inline void Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::draw(const MatrixType&, CameraType*) {}
template<class MatrixType, class VectorType, class ObjectType, class SceneType, class CameraType> inline void Object<MatrixType, VectorType, ObjectType, SceneType, CameraType>::clean(const MatrixType&) { dirty = false; }
class Camera2D;
class Camera3D;
class Object2D;
class Object3D;
template<class MatrixType, class VectorType, class ObjectType, class CameraType> class Scene;
typedef Scene<Matrix3, Vector2, Object2D, Camera2D> Scene2D;
typedef Scene<Matrix4, Vector3, Object3D, Camera3D> Scene3D;
template<size_t dimensions> inline void Object<dimensions>::draw(const MatrixType&, CameraType*) {}
template<size_t dimensions> inline void Object<dimensions>::clean(const MatrixType&) { dirty = false; }
#ifndef DOXYGEN_GENERATING_OUTPUT
/* These templates are instantiated in source file */
extern template class SCENEGRAPH_EXPORT Object<Matrix3, Vector2, Object2D, Scene2D, Camera2D>;
extern template class SCENEGRAPH_EXPORT Object<Matrix4, Vector3, Object3D, Scene3D, Camera3D>;
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<Matrix3, Vector2, Object2D, Scene2D, Camera2D> {
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<Matrix3, Vector2, Object2D, Scen
};
/** @brief Three-dimensional object */
class SCENEGRAPH_EXPORT Object3D: public Object<Matrix4, Vector3, Object3D, Scene3D, Camera3D> {
class SCENEGRAPH_EXPORT Object3D: public Object<3> {
public:
/** @copydoc Object::Object */
inline Object3D(Object3D* parent = nullptr): Object(parent) {}

20
src/SceneGraph/Scene.h

@ -24,30 +24,30 @@
namespace Magnum { namespace SceneGraph {
/** @brief %Scene */
template<class MatrixType, class VectorType, class ObjectType, class CameraType> class SCENEGRAPH_EXPORT Scene: public ObjectType {
template<size_t dimensions> class SCENEGRAPH_EXPORT Scene: public Object<dimensions>::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<dimensions>::ObjectType* parent) = delete;
void setTransformation(const typename Object<dimensions>::MatrixType& transformation) = delete;
void multiplyTransformation(const typename Object<dimensions>::MatrixType& transformation, typename Object<dimensions>::Transformation type = Object<dimensions>::Transformation::Global) = delete;
void translate(const typename Object<dimensions>::VectorType& vec, typename Object<dimensions>::Transformation type = Object<dimensions>::Transformation::Global) = delete;
void scale(const typename Object<dimensions>::VectorType& vec, typename Object<dimensions>::Transformation type = Object<dimensions>::Transformation::Global) = delete;
void rotate(GLfloat angle, const typename Object<dimensions>::VectorType& vec, typename Object<dimensions>::Transformation type = Object<dimensions>::Transformation::Global) = delete;
#endif
private:
inline void draw(const MatrixType&, CameraType*) {}
inline void draw(const typename Object<dimensions>::MatrixType&, typename Object<dimensions>::CameraType*) {}
};
/** @brief Two-dimensional scene */
typedef Scene<Matrix3, Vector2, Object2D, Camera2D> Scene2D;
typedef Scene<2> Scene2D;
/** @brief Three-dimensional scene */
typedef Scene<Matrix4, Vector3, Object3D, Camera3D> Scene3D;
typedef Scene<3> Scene3D;
}}

Loading…
Cancel
Save