#ifndef Magnum_SceneGraph_AbstractObject_h #define Magnum_SceneGraph_AbstractObject_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. */ /** @file * @brief Class Magnum::SceneGraph::AbstractObject, alias Magnum::SceneGraph::AbstractObject2D, Magnum::SceneGraph::AbstractObject3D */ #include #include #include "DimensionTraits.h" #include "SceneGraph.h" #include "SceneGraph/magnumSceneGraphVisibility.h" namespace Magnum { namespace SceneGraph { /** @brief Base for objects Provides minimal interface for features, not depending on object transformation implementation. This class is not directly instantiatable, use Object subclass instead. See also @ref scenegraph for more information. Uses Corrade::Containers::LinkedList for storing features. Traversing through the list is done like in the following code. It is also possible to go in reverse order using lastFeature() and AbstractFeature::previousFeature(). @code for(AbstractFeature* feature = o->firstFeature(); feature; feature = feature->nextFeature()) { // ... } @endcode @see AbstractObject2D, AbstractObject3D */ #ifndef DOXYGEN_GENERATING_OUTPUT template class MAGNUM_SCENEGRAPH_EXPORT AbstractObject: private Corrade::Containers::LinkedList> #else template class AbstractObject #endif { friend class Corrade::Containers::LinkedList>; friend class Corrade::Containers::LinkedListItem, AbstractObject>; friend AbstractFeature::AbstractFeature(AbstractObject*); public: /** @brief Feature object type */ typedef AbstractFeature FeatureType; explicit AbstractObject(); virtual ~AbstractObject(); /** @brief Whether this object has features */ inline bool hasFeatures() const { return !Corrade::Containers::LinkedList>::isEmpty(); } /** @brief First object feature or `nullptr`, if this object has no features */ inline FeatureType* firstFeature() { return Corrade::Containers::LinkedList>::first(); } /** @overload */ inline const FeatureType* firstFeature() const { return Corrade::Containers::LinkedList>::first(); } /** @brief Last object feature or `nullptr`, if this object has no features */ inline FeatureType* lastFeature() { return Corrade::Containers::LinkedList>::last(); } /** @overload */ inline const FeatureType* lastFeature() const { return Corrade::Containers::LinkedList>::last(); } /** * @brief %Scene object * @return Root object which is also scene or `nullptr`, if the object * is not part of any scene. * * @todo Rename to scene() when I fully understand and fix covariant * return issues. */ virtual AbstractObject* sceneObject() = 0; /** @overload */ virtual const AbstractObject* sceneObject() const = 0; /** @{ @name Object transformation */ /** * @brief Transformation matrix * * @see Object::transformation() */ virtual typename DimensionTraits::MatrixType transformationMatrix() const = 0; /** * @brief Transformation matrix relative to root object * * @see Object::absoluteTransformation() */ virtual typename DimensionTraits::MatrixType absoluteTransformationMatrix() const = 0; /** * @brief Transformation matrices of given set of objects relative to this object * * All transformations are premultiplied with @p initialTransformationMatrix, * if specified. * @warning This function cannot check if all objects are of the same * Object type, use typesafe Object::transformations() when * possible. */ virtual std::vector::MatrixType> transformationMatrices(const std::vector*>& objects, const typename DimensionTraits::MatrixType& initialTransformationMatrix = typename DimensionTraits::MatrixType()) const = 0; /*@}*/ /** * @{ @name Transformation caching * * See @ref scenegraph-caching for more information. */ /** * @brief Whether absolute transformation is dirty * * Returns `true` if transformation of the object or any parent has * changed since last call to setClean(), `false` otherwise. * * All objects are dirty by default. * * @see @ref scenegraph-caching */ virtual bool isDirty() const = 0; /** * @brief Set object absolute transformation as dirty * * Calls AbstractFeature::markDirty() on all object features and * recursively calls setDirty() on every child object which is not * already dirty. If the object is already marked as dirty, the * function does nothing. * @see @ref scenegraph-caching, setClean(), isDirty() */ virtual void setDirty() = 0; /** * @brief Clean object absolute transformation * * Calls AbstractFeature::clean() and/or AbstractFeature::cleanInverted() * on all object features which have caching enabled and recursively * calls setClean() on every parent which is not already clean. If the * object is already clean, the function does nothing. * * See also setClean(const std::vector& objects), which cleans given * set of objects more efficiently than when calling setClean() on * each object individually. * @see @ref scenegraph-caching, setDirty(), isDirty() */ virtual void setClean() = 0; /** * @brief Clean absolute transformations of given set of objects * * Only dirty objects in the list are cleaned. * @warning This function cannot check if all objects are of the same * Object type, use typesafe Object::setClean(const std::vector& objects) when * possible. */ virtual void setClean(const std::vector*>& objects) const = 0; /*@}*/ }; #ifndef CORRADE_GCC46_COMPATIBILITY /** @brief Base for two-dimensional objects Convenience alternative to %AbstractObject<2, T>. See AbstractObject for more information. @note Not available on GCC < 4.7. Use %AbstractObject<2, T> instead. @see AbstractObject3D */ #ifdef DOXYGEN_GENERATING_OUTPUT template #else template #endif using AbstractObject2D = AbstractObject<2, T>; /** @brief Base for three-dimensional objects Convenience alternative to %AbstractObject<3, T>. See AbstractObject for more information. @note Not available on GCC < 4.7. Use %AbstractObject<3, T> instead. @see AbstractObject2D */ #ifdef DOXYGEN_GENERATING_OUTPUT template #else template #endif using AbstractObject3D = AbstractObject<3, T>; #endif }} #endif