diff --git a/src/SceneGraph/AbstractObject.h b/src/SceneGraph/AbstractObject.h index 7c58ae068..662a56c07 100644 --- a/src/SceneGraph/AbstractObject.h +++ b/src/SceneGraph/AbstractObject.h @@ -79,6 +79,19 @@ template class AbstractObject 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 */ /** @@ -89,6 +102,48 @@ template class AbstractObject virtual typename DimensionTraits::MatrixType absoluteTransformationMatrix() 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 @ref scenegraph-caching, setDirty(), isDirty() + */ + virtual void setClean() = 0; + + /*@}*/ }; /** diff --git a/src/SceneGraph/Object.h b/src/SceneGraph/Object.h index 73676b6f0..587f2f07d 100644 --- a/src/SceneGraph/Object.h +++ b/src/SceneGraph/Object.h @@ -188,49 +188,14 @@ template class Object: public AbstractObject* sceneObject() override; + const Object* sceneObject() const override; + typedef Implementation::ObjectFlag Flag; typedef Implementation::ObjectFlags Flags; Flags flags; diff --git a/src/SceneGraph/Object.hpp b/src/SceneGraph/Object.hpp index dc54f42ca..092cc9c70 100644 --- a/src/SceneGraph/Object.hpp +++ b/src/SceneGraph/Object.hpp @@ -28,15 +28,23 @@ namespace Magnum { namespace SceneGraph { template Scene* Object::scene() { + return static_cast*>(sceneObject()); +} + +template const Scene* Object::scene() const { + return static_cast*>(sceneObject()); +} + +template Object* Object::sceneObject() { Object* p(this); while(p && !p->isScene()) p = p->parent(); - return static_cast*>(p); + return p; } -template const Scene* Object::scene() const { +template const Object* Object::sceneObject() const { const Object* p(this); while(p && !p->isScene()) p = p->parent(); - return static_cast*>(p); + return p; } template Object* Object::setParent(Object* parent) {