#ifndef Magnum_SceneGraph_Object_h #define Magnum_SceneGraph_Object_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::Object */ #include #include "AbstractFeature.h" #include "AbstractObject.h" #include "magnumSceneGraphVisibility.h" namespace Magnum { namespace SceneGraph { template class Scene; #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { enum class ObjectFlag: std::uint8_t { Dirty = 1 << 0 }; typedef Corrade::Containers::EnumSet ObjectFlags; CORRADE_ENUMSET_OPERATORS(ObjectFlags) } #endif /** @brief %Object Base of scene graph. Contains specific transformation implementation, takes care of parent/children relationships and contains features. See @ref scenegraph for introduction. @section Object-explicit-specializations Explicit template specializations The following specialization are explicitly compiled into SceneGraph library. For other specializations you have to use Object.hpp implementation file to avoid linker errors. See @ref compilation-speedup-hpp for more information. - @ref MatrixTransformation2D "Object>" - @ref MatrixTransformation3D "Object>" @see Scene, AbstractFeature, AbstractTransformation */ template class Object: public AbstractObject, public Transformation #ifndef DOXYGEN_GENERATING_OUTPUT , private Corrade::Containers::LinkedList>, private Corrade::Containers::LinkedListItem, Object> #endif { friend class Corrade::Containers::LinkedList>; friend class Corrade::Containers::LinkedListItem, 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 public: /** * @brief Constructor * @param parent Parent object */ inline Object(Object* parent = nullptr): flags(Flag::Dirty) { setParent(parent); } /** * @brief Destructor * * Removes itself from parent's children list and destroys all own * children. */ inline virtual ~Object() {} /** * @{ @name Scene hierarchy * * See @ref scenegraph-hierarchy for more information. */ /** @brief Whether this object is scene */ virtual inline bool isScene() const { return false; } /** * @brief %Scene * @return %Scene or `nullptr`, if the object is not part of any scene. */ Scene* scene(); /** @overload */ const Scene* scene() const; /** @brief Parent object or `nullptr`, if this is root object */ inline Object* parent() { return Corrade::Containers::LinkedListItem, Object>::list(); } /** @overload */ inline const Object* parent() const { return Corrade::Containers::LinkedListItem, Object>::list(); } /** @brief Previous sibling object or `nullptr`, if this is first object */ inline Object* previousSibling() { return Corrade::Containers::LinkedListItem, Object>::previous(); } /** @overload */ inline const Object* previousSibling() const { return Corrade::Containers::LinkedListItem, Object>::previous(); } /** @brief Next sibling object or `nullptr`, if this is last object */ inline Object* nextSibling() { return Corrade::Containers::LinkedListItem, Object>::next(); } /** @overload */ inline const Object* nextSibling() const { return Corrade::Containers::LinkedListItem, Object>::next(); } /** @brief Whether this object has children */ inline bool hasChildren() const { return !Corrade::Containers::LinkedList>::isEmpty(); } /** @brief First child object or `nullptr`, if this object has no children */ inline Object* firstChild() { return Corrade::Containers::LinkedList>::first(); } /** @overload */ inline const Object* firstChild() const { return Corrade::Containers::LinkedList>::first(); } /** @brief Last child object or `nullptr`, if this object has no children */ inline Object* lastChild() { return Corrade::Containers::LinkedList>::last(); } /** @overload */ inline const Object* lastChild() const { return Corrade::Containers::LinkedList>::last(); } /** * @brief Set parent object * @return Pointer to self (for method chaining) */ Object* setParent(Object* parent); /*@}*/ /** @{ @name Object transformation */ inline typename DimensionTraits::MatrixType absoluteTransformationMatrix() const override { return Transformation::toMatrix(absoluteTransformation()); } /** * @brief Transformation relative to root object * * @see absoluteTransformationMatrix() */ typename Transformation::DataType absoluteTransformation() const; /*@}*/ inline bool isDirty() const override { return !!(flags & Flag::Dirty); } void setDirty() override; void setClean() override; private: Object* sceneObject() override; const Object* sceneObject() const override; typedef Implementation::ObjectFlag Flag; typedef Implementation::ObjectFlags Flags; Flags flags; }; }} #endif