/*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+ Copyright (C) 2001-2006, William Joseph.
+ All Rights Reserved.
-This file is part of GtkRadiant.
+ This file is part of GtkRadiant.
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ GtkRadiant is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-GtkRadiant 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 General Public License for more details.
+ GtkRadiant 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 General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ You should have received a copy of the GNU General Public License
+ along with GtkRadiant; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
-#if !defined (INCLUDED_SCENELIB_H)
+#if !defined ( INCLUDED_SCENELIB_H )
#define INCLUDED_SCENELIB_H
+#include "globaldefs.h"
#include "iscenegraph.h"
#include "iselection.h"
class ComponentSelectionTestable
{
public:
- STRING_CONSTANT(Name, "ComponentSelectionTestable");
+STRING_CONSTANT( Name, "ComponentSelectionTestable" );
- virtual bool isSelectedComponents() const = 0;
- virtual void setSelectedComponents(bool select, SelectionSystem::EComponentMode mode) = 0;
- virtual void testSelectComponents(Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode) = 0;
+virtual bool isSelectedComponents() const = 0;
+virtual void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ) = 0;
+virtual void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ) = 0;
};
class ComponentEditable
{
public:
- STRING_CONSTANT(Name, "ComponentEditable");
+STRING_CONSTANT( Name, "ComponentEditable" );
- virtual const AABB& getSelectedComponentsBounds() const = 0;
+virtual const AABB& getSelectedComponentsBounds() const = 0;
};
class ComponentSnappable
{
public:
- STRING_CONSTANT(Name, "ComponentSnappable");
+STRING_CONSTANT( Name, "ComponentSnappable" );
- virtual void snapComponents(float snap) = 0;
+virtual void snapComponents( float snap ) = 0;
};
class Bounded
{
public:
- STRING_CONSTANT(Name, "Bounded");
+STRING_CONSTANT( Name, "Bounded" );
- virtual const AABB& localAABB() const = 0;
+virtual const AABB& localAABB() const = 0;
};
class BrushDoom3
{
public:
- STRING_CONSTANT(Name, "BrushDoom3");
+STRING_CONSTANT( Name, "BrushDoom3" );
- virtual void setDoom3GroupOrigin(const Vector3& origin) = 0;
+virtual void setDoom3GroupOrigin( const Vector3& origin ) = 0;
};
template<typename Type>
class NodeType : public StaticTypeSystemInitialiser
{
- TypeId m_typeId;
+TypeId m_typeId;
public:
- typedef typename Type::Name Name;
- NodeType() : m_typeId(NODETYPEID_NONE)
- {
- StaticTypeSystemInitialiser::instance().addInitialiser(InitialiseCaller(*this));
- }
- void initialise()
- {
- m_typeId = GlobalSceneGraph().getNodeTypeId(Name());
- }
- typedef MemberCaller<NodeType<Type>, &NodeType<Type>::initialise> InitialiseCaller;
- TypeId getTypeId()
- {
-#if defined(_DEBUG)
- ASSERT_MESSAGE(m_typeId != NODETYPEID_NONE, "node-type " << makeQuoted(Name()) << " used before being initialised");
+typedef typename Type::Name Name;
+NodeType() : m_typeId( NODETYPEID_NONE ){
+ StaticTypeSystemInitialiser::instance().addInitialiser( InitialiseCaller( *this ) );
+}
+void initialise(){
+ m_typeId = GlobalSceneGraph().getNodeTypeId( Name() );
+}
+typedef MemberCaller<NodeType<Type>, void(), &NodeType<Type>::initialise> InitialiseCaller;
+TypeId getTypeId(){
+#if GDEF_DEBUG
+ ASSERT_MESSAGE( m_typeId != NODETYPEID_NONE, "node-type " << makeQuoted( Name() ) << " used before being initialised" );
#endif
- return m_typeId;
- }
+ return m_typeId;
+}
};
template<typename Type>
class StaticNodeType
{
public:
- enum unnamed0 { SIZE = NODETYPEID_MAX };
- static TypeId getTypeId()
- {
- return Static< NodeType<Type> >::instance().getTypeId();
- }
+enum unnamed0 { SIZE = NODETYPEID_MAX };
+static TypeId getTypeId(){
+ return Static< NodeType<Type> >::instance().getTypeId();
+}
};
template<typename Type, typename Base>
class NodeStaticCast :
- public CastInstaller<
- StaticNodeType<Base>,
- StaticCast<Type, Base>
- >
+ public CastInstaller<
+ StaticNodeType<Base>,
+ StaticCast<Type, Base>
+ >
{
};
template<typename Type, typename Contained>
class NodeContainedCast :
- public CastInstaller<
- StaticNodeType<Contained>,
- ContainedCast<Type, Contained>
- >
+ public CastInstaller<
+ StaticNodeType<Contained>,
+ ContainedCast<Type, Contained>
+ >
{
};
template<typename Type>
class NodeIdentityCast :
- public CastInstaller<
- StaticNodeType<Type>,
- IdentityCast<Type>
- >
+ public CastInstaller<
+ StaticNodeType<Type>,
+ IdentityCast<Type>
+ >
{
};
namespace scene
{
- class Node
- {
- public:
- enum unnamed0 { eVisible = 0 };
- enum unnamed1 { eHidden = 1 << 0 };
- enum unnamed2 { eFiltered = 1 << 1 };
- enum unnamed3 { eExcluded = 1 << 2 };
-
- class Symbiot
- {
- public:
- virtual void release() = 0;
- };
-
- private:
- unsigned int m_state;
- std::size_t m_refcount;
- Symbiot* m_symbiot;
- void* m_node;
- NodeTypeCastTable& m_casts;
-
- public:
- bool m_isRoot;
-
- bool isRoot()
- {
- return m_isRoot;
- }
-
- Node(Symbiot* symbiot, void* node, NodeTypeCastTable& casts) :
- m_state(eVisible),
- m_refcount(0),
- m_symbiot(symbiot),
- m_node(node),
- m_casts(casts),
- m_isRoot(false)
- {
- }
- ~Node()
- {
- }
-
- void IncRef()
- {
- ASSERT_MESSAGE(m_refcount < (1 << 24), "Node::decref: uninitialised refcount");
- ++m_refcount;
- }
- void DecRef()
- {
- ASSERT_MESSAGE(m_refcount < (1 << 24), "Node::decref: uninitialised refcount");
- if(--m_refcount == 0)
- {
- m_symbiot->release();
- }
- }
- std::size_t getReferenceCount() const
- {
- return m_refcount;
- }
-
- void* cast(TypeId typeId) const
- {
- return m_casts.cast(typeId, m_node);
- }
-
- void enable(unsigned int state)
- {
- m_state |= state;
- }
- void disable(unsigned int state)
- {
- m_state &= ~state;
- }
- bool visible()
- {
- return m_state == eVisible;
- }
- bool excluded()
- {
- return (m_state & eExcluded) != 0;
- }
- };
-
- class NullNode : public Node::Symbiot
- {
- NodeTypeCastTable m_casts;
- Node m_node;
- public:
- NullNode() : m_node(this, 0, m_casts)
- {
- }
- void release()
- {
- delete this;
- }
- scene::Node& node()
- {
- return m_node;
- }
- };
-}
+class Node
+{
+public:
+enum unnamed0 { eVisible = 0 };
+enum unnamed1 { eHidden = 1 << 0 };
+enum unnamed2 { eFiltered = 1 << 1 };
+enum unnamed3 { eExcluded = 1 << 2 };
-template<typename Type>
-class NodeTypeCast
+class Symbiot
{
public:
- static Type* cast(scene::Node& node)
- {
- return static_cast<Type*>(node.cast(StaticNodeType<Type>::getTypeId()));
- }
- static const Type* cast(const scene::Node& node)
- {
- return static_cast<const Type*>(node.cast(StaticNodeType<Type>::getTypeId()));
- }
+virtual void release() = 0;
+virtual ~Symbiot(){
+}
};
+private:
+unsigned int m_state;
+std::size_t m_refcount;
+Symbiot* m_symbiot;
+void* m_node;
+NodeTypeCastTable& m_casts;
-inline scene::Instantiable* Node_getInstantiable(scene::Node& node)
-{
- return NodeTypeCast<scene::Instantiable>::cast(node);
+public:
+bool m_isRoot;
+
+bool isRoot(){
+ return m_isRoot;
}
-inline scene::Traversable* Node_getTraversable(scene::Node& node)
-{
- return NodeTypeCast<scene::Traversable>::cast(node);
+Node( Symbiot* symbiot, void* node, NodeTypeCastTable& casts ) :
+ m_state( eVisible ),
+ m_refcount( 0 ),
+ m_symbiot( symbiot ),
+ m_node( node ),
+ m_casts( casts ),
+ m_isRoot( false ){
+}
+~Node(){
}
-inline void Node_traverseSubgraph(scene::Node& node, const scene::Traversable::Walker& walker)
-{
- if(walker.pre(node))
- {
- scene::Traversable* traversable = Node_getTraversable(node);
- if(traversable != 0)
- {
- traversable->traverse(walker);
- }
- }
- walker.post(node);
-}
-
-inline TransformNode* Node_getTransformNode(scene::Node& node)
-{
- return NodeTypeCast<TransformNode>::cast(node);
+void IncRef(){
+ ASSERT_MESSAGE( m_refcount < ( 1 << 24 ), "Node::decref: uninitialised refcount" );
+ ++m_refcount;
+}
+void DecRef(){
+ ASSERT_MESSAGE( m_refcount < ( 1 << 24 ), "Node::decref: uninitialised refcount" );
+ if ( --m_refcount == 0 ) {
+ m_symbiot->release();
+ }
+}
+std::size_t getReferenceCount() const {
+ return m_refcount;
}
-inline bool operator<(scene::Node& node, scene::Node& other)
-{
- return &node < &other;
+void* cast( TypeId typeId ) const {
+ return m_casts.cast( typeId, m_node );
}
-inline bool operator==(scene::Node& node, scene::Node& other)
-{
- return &node == &other;
+
+void enable( unsigned int state ){
+ m_state |= state;
}
-inline bool operator!=(scene::Node& node, scene::Node& other)
-{
- return !::operator==(node, other);
+void disable( unsigned int state ){
+ m_state &= ~state;
+}
+bool visible(){
+ return m_state == eVisible;
+}
+bool excluded(){
+ return ( m_state & eExcluded ) != 0;
+}
+bool operator<( const scene::Node& other ){
+ return this < &other;
+}
+bool operator==( const scene::Node& other ){
+ return this == &other;
+}
+bool operator!=( const scene::Node& other ){
+ return this != &other;
}
+};
-inline scene::Node& NewNullNode()
+class NullNode : public Node::Symbiot
{
- return (new scene::NullNode)->node();
+NodeTypeCastTable m_casts;
+Node m_node;
+public:
+NullNode() : m_node( this, 0, m_casts ){
+}
+void release(){
+ delete this;
+}
+scene::Node& node(){
+ return m_node;
+}
+};
}
-inline void Path_deleteTop(const scene::Path& path)
+template<typename Type>
+class NodeTypeCast
{
- Node_getTraversable(path.parent())->erase(path.top());
+public:
+static Type* cast( scene::Node& node ){
+ return static_cast<Type*>( node.cast( StaticNodeType<Type>::getTypeId() ) );
+}
+static const Type* cast( const scene::Node& node ){
+ return static_cast<const Type*>( node.cast( StaticNodeType<Type>::getTypeId() ) );
+}
+};
+
+
+inline scene::Instantiable* Node_getInstantiable( scene::Node& node ){
+ return NodeTypeCast<scene::Instantiable>::cast( node );
+}
+
+inline scene::Traversable* Node_getTraversable( scene::Node& node ){
+ return NodeTypeCast<scene::Traversable>::cast( node );
+}
+
+inline void Node_traverseSubgraph( scene::Node& node, const scene::Traversable::Walker& walker ){
+ if ( walker.pre( node ) ) {
+ scene::Traversable* traversable = Node_getTraversable( node );
+ if ( traversable != 0 ) {
+ traversable->traverse( walker );
+ }
+ }
+ walker.post( node );
+}
+
+inline TransformNode* Node_getTransformNode( scene::Node& node ){
+ return NodeTypeCast<TransformNode>::cast( node );
+}
+
+
+inline scene::Node& NewNullNode(){
+ return ( new scene::NullNode )->node();
+}
+
+inline void Path_deleteTop( const scene::Path& path ){
+ Node_getTraversable( path.parent() )->erase( path.top() );
}
class delete_all : public scene::Traversable::Walker
{
- scene::Node& m_parent;
+scene::Node& m_parent;
public:
- delete_all(scene::Node& parent) : m_parent(parent)
- {
- }
- bool pre(scene::Node& node) const
- {
- return false;
- }
- void post(scene::Node& node) const
- {
- Node_getTraversable(m_parent)->erase(node);
- }
+delete_all( scene::Node& parent ) : m_parent( parent ){
+}
+bool pre( scene::Node& node ) const {
+ return false;
+}
+void post( scene::Node& node ) const {
+ Node_getTraversable( m_parent )->erase( node );
+}
};
-inline void DeleteSubgraph(scene::Node& subgraph)
-{
- Node_getTraversable(subgraph)->traverse(delete_all(subgraph));
+inline void DeleteSubgraph( scene::Node& subgraph ){
+ Node_getTraversable( subgraph )->traverse( delete_all( subgraph ) );
}
class EntityUndefined
{
public:
- STRING_CONSTANT(Name, "Entity");
+STRING_CONSTANT( Name, "Entity" );
};
-inline bool Node_isEntity(scene::Node& node)
+inline bool Node_isEntity( scene::Node& node ){
+ return NodeTypeCast<EntityUndefined>::cast( node ) != 0;
+}
+
+template<typename Functor>
+class EntityWalker : public scene::Graph::Walker
{
- return NodeTypeCast<EntityUndefined>::cast(node) != 0;
+const Functor& functor;
+public:
+EntityWalker( const Functor& functor ) : functor( functor ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ if ( Node_isEntity( path.top() ) ) {
+ functor( instance );
+ return false;
+ }
+ return true;
+}
+};
+
+template<typename Functor>
+inline const Functor& Scene_forEachEntity( const Functor& functor ){
+ GlobalSceneGraph().traverse( EntityWalker<Functor>( functor ) );
+ return functor;
}
class BrushUndefined
{
public:
- STRING_CONSTANT(Name, "Brush");
+STRING_CONSTANT( Name, "Brush" );
};
-inline bool Node_isBrush(scene::Node& node)
-{
- return NodeTypeCast<BrushUndefined>::cast(node) != 0;
+inline bool Node_isBrush( scene::Node& node ){
+ return NodeTypeCast<BrushUndefined>::cast( node ) != 0;
}
class PatchUndefined
{
public:
- STRING_CONSTANT(Name, "Patch");
+STRING_CONSTANT( Name, "Patch" );
};
-inline bool Node_isPatch(scene::Node& node)
-{
- return NodeTypeCast<PatchUndefined>::cast(node) != 0;
+inline bool Node_isPatch( scene::Node& node ){
+ return NodeTypeCast<PatchUndefined>::cast( node ) != 0;
}
-inline bool Node_isPrimitive(scene::Node& node)
-{
+inline bool Node_isPrimitive( scene::Node& node ){
#if 1
- return Node_isBrush(node) || Node_isPatch(node);
+ return Node_isBrush( node ) || Node_isPatch( node );
#else
- return !node.isRoot();
+ return !node.isRoot();
#endif
}
class ParentBrushes : public scene::Traversable::Walker
{
- scene::Node& m_parent;
+scene::Node& m_parent;
public:
- ParentBrushes(scene::Node& parent)
- : m_parent(parent)
- {
- }
- bool pre(scene::Node& node) const
- {
- return false;
- }
- void post(scene::Node& node) const
- {
- if(Node_isPrimitive(node))
- {
- Node_getTraversable(m_parent)->insert(node);
- }
- }
+ParentBrushes( scene::Node& parent )
+ : m_parent( parent ){
+}
+bool pre( scene::Node& node ) const {
+ return false;
+}
+void post( scene::Node& node ) const {
+ if ( Node_isPrimitive( node ) ) {
+ Node_getTraversable( m_parent )->insert( node );
+ }
+}
};
-inline void parentBrushes(scene::Node& subgraph, scene::Node& parent)
-{
- Node_getTraversable(subgraph)->traverse(ParentBrushes(parent));
+inline void parentBrushes( scene::Node& subgraph, scene::Node& parent ){
+ Node_getTraversable( subgraph )->traverse( ParentBrushes( parent ) );
}
class HasBrushes : public scene::Traversable::Walker
{
- bool& m_hasBrushes;
+bool& m_hasBrushes;
public:
- HasBrushes(bool& hasBrushes)
- : m_hasBrushes(hasBrushes)
- {
- m_hasBrushes = true;
- }
- bool pre(scene::Node& node) const
- {
- if(!Node_isPrimitive(node))
- {
- m_hasBrushes = false;
- }
- return false;
- }
+HasBrushes( bool& hasBrushes )
+ : m_hasBrushes( hasBrushes ){
+ m_hasBrushes = true;
+}
+bool pre( scene::Node& node ) const {
+ if ( !Node_isPrimitive( node ) ) {
+ m_hasBrushes = false;
+ }
+ return false;
+}
};
-inline bool node_is_group(scene::Node& node)
-{
- scene::Traversable* traversable = Node_getTraversable(node);
- if(traversable != 0)
- {
- bool hasBrushes = false;
- traversable->traverse(HasBrushes(hasBrushes));
- return hasBrushes;
- }
- return false;
+inline bool node_is_group( scene::Node& node ){
+ scene::Traversable* traversable = Node_getTraversable( node );
+ if ( traversable != 0 ) {
+ bool hasBrushes = false;
+ traversable->traverse( HasBrushes( hasBrushes ) );
+ return hasBrushes;
+ }
+ return false;
}
typedef TypeCastTable<INSTANCETYPEID_MAX> InstanceTypeCastTable;
template<typename Type>
class InstanceType : public StaticTypeSystemInitialiser
{
- TypeId m_typeId;
+TypeId m_typeId;
public:
- typedef typename Type::Name Name;
- InstanceType() : m_typeId(INSTANCETYPEID_NONE)
- {
- StaticTypeSystemInitialiser::instance().addInitialiser(InitialiseCaller(*this));
- }
- void initialise()
- {
- m_typeId = GlobalSceneGraph().getInstanceTypeId(Name());
- }
- typedef MemberCaller<InstanceType<Type>, &InstanceType<Type>::initialise> InitialiseCaller;
- TypeId getTypeId()
- {
-#if defined(_DEBUG)
- ASSERT_MESSAGE(m_typeId != INSTANCETYPEID_NONE, "instance-type " << makeQuoted(Name()) << " used before being initialised");
+typedef typename Type::Name Name;
+InstanceType() : m_typeId( INSTANCETYPEID_NONE ){
+ StaticTypeSystemInitialiser::instance().addInitialiser( InitialiseCaller( *this ) );
+}
+void initialise(){
+ m_typeId = GlobalSceneGraph().getInstanceTypeId( Name() );
+}
+typedef MemberCaller<InstanceType<Type>, void(), &InstanceType<Type>::initialise> InitialiseCaller;
+TypeId getTypeId(){
+#if GDEF_DEBUG
+ ASSERT_MESSAGE( m_typeId != INSTANCETYPEID_NONE, "instance-type " << makeQuoted( Name() ) << " used before being initialised" );
#endif
- return m_typeId;
- }
+ return m_typeId;
+}
};
template<typename Type>
class StaticInstanceType
{
public:
- enum unnamed0 { SIZE = INSTANCETYPEID_MAX };
- static TypeId getTypeId()
- {
- return Static< InstanceType<Type> >::instance().getTypeId();
- }
+enum unnamed0 { SIZE = INSTANCETYPEID_MAX };
+static TypeId getTypeId(){
+ return Static< InstanceType<Type> >::instance().getTypeId();
+}
};
template<typename Type, typename Base>
class InstanceStaticCast :
- public CastInstaller<
- StaticInstanceType<Base>,
- StaticCast<Type, Base>
- >
+ public CastInstaller<
+ StaticInstanceType<Base>,
+ StaticCast<Type, Base>
+ >
{
};
template<typename Type, typename Contained>
class InstanceContainedCast :
- public CastInstaller<
- StaticInstanceType<Contained>,
- ContainedCast<Type, Contained>
- >
+ public CastInstaller<
+ StaticInstanceType<Contained>,
+ ContainedCast<Type, Contained>
+ >
{
};
template<typename Type>
class InstanceIdentityCast :
- public CastInstaller<
- StaticInstanceType<Type>,
- IdentityCast<Type>
- >
+ public CastInstaller<
+ StaticInstanceType<Type>,
+ IdentityCast<Type>
+ >
{
};
-inline Selectable* Instance_getSelectable(scene::Instance& instance);
-inline const Selectable* Instance_getSelectable(const scene::Instance& instance);
+inline Selectable* Instance_getSelectable( scene::Instance& instance );
+inline const Selectable* Instance_getSelectable( const scene::Instance& instance );
-inline Bounded* Instance_getBounded(scene::Instance& instance);
-inline const Bounded* Instance_getBounded(const scene::Instance& instance);
+inline Bounded* Instance_getBounded( scene::Instance& instance );
+inline const Bounded* Instance_getBounded( const scene::Instance& instance );
namespace scene
{
- class Instance
- {
- class AABBAccumulateWalker : public scene::Graph::Walker
- {
- AABB& m_aabb;
- mutable std::size_t m_depth;
- public:
- AABBAccumulateWalker(AABB& aabb) : m_aabb(aabb), m_depth(0)
- {
- }
- bool pre(const scene::Path& path, scene::Instance& instance) const
- {
- if(m_depth == 1)
- {
- aabb_extend_by_aabb_safe(m_aabb, instance.worldAABB());
- }
- return ++m_depth != 2;
- }
- void post(const scene::Path& path, scene::Instance& instance) const
- {
- --m_depth;
- }
- };
-
-
- class TransformChangedWalker : public scene::Graph::Walker
- {
- public:
- bool pre(const scene::Path& path, scene::Instance& instance) const
- {
- instance.transformChangedLocal();
- return true;
- }
- };
-
- class ParentSelectedChangedWalker : public scene::Graph::Walker
- {
- public:
- bool pre(const scene::Path& path, scene::Instance& instance) const
- {
- instance.parentSelectedChanged();
- return true;
- }
- };
-
- class ChildSelectedWalker : public scene::Graph::Walker
- {
- bool& m_childSelected;
- mutable std::size_t m_depth;
- public:
- ChildSelectedWalker(bool& childSelected) : m_childSelected(childSelected), m_depth(0)
- {
- m_childSelected = false;
- }
- bool pre(const scene::Path& path, scene::Instance& instance) const
- {
- if(m_depth == 1 && !m_childSelected)
- {
- m_childSelected = instance.isSelected() || instance.childSelected();
- }
- return ++m_depth != 2;
- }
- void post(const scene::Path& path, scene::Instance& instance) const
- {
- --m_depth;
- }
- };
-
- Path m_path;
- Instance* m_parent;
- void* m_instance;
- InstanceTypeCastTable& m_casts;
-
- mutable Matrix4 m_local2world;
- mutable AABB m_bounds;
- mutable AABB m_childBounds;
- mutable bool m_transformChanged;
- mutable bool m_transformMutex;
- mutable bool m_boundsChanged;
- mutable bool m_boundsMutex;
- mutable bool m_childBoundsChanged;
- mutable bool m_childBoundsMutex;
- mutable bool m_isSelected;
- mutable bool m_isSelectedChanged;
- mutable bool m_childSelected;
- mutable bool m_childSelectedChanged;
- mutable bool m_parentSelected;
- mutable bool m_parentSelectedChanged;
- Callback m_childSelectedChangedCallback;
- Callback m_transformChangedCallback;
-
-
- void evaluateTransform() const
- {
- if(m_transformChanged)
- {
- ASSERT_MESSAGE(!m_transformMutex, "re-entering transform evaluation");
- m_transformMutex = true;
-
- m_local2world = (m_parent != 0) ? m_parent->localToWorld() : g_matrix4_identity;
- TransformNode* transformNode = Node_getTransformNode(m_path.top());
- if(transformNode != 0)
- {
- matrix4_multiply_by_matrix4(m_local2world, transformNode->localToParent());
- }
-
- m_transformMutex = false;
- m_transformChanged = false;
- }
- }
- void evaluateChildBounds() const
- {
- if(m_childBoundsChanged)
- {
- ASSERT_MESSAGE(!m_childBoundsMutex, "re-entering bounds evaluation");
- m_childBoundsMutex = true;
-
- m_childBounds = AABB();
-
- GlobalSceneGraph().traverse_subgraph(AABBAccumulateWalker(m_childBounds), m_path);
-
- m_childBoundsMutex = false;
- m_childBoundsChanged = false;
- }
- }
- void evaluateBounds() const
- {
- if(m_boundsChanged)
- {
- ASSERT_MESSAGE(!m_boundsMutex, "re-entering bounds evaluation");
- m_boundsMutex = true;
-
- m_bounds = childBounds();
-
- const Bounded* bounded = Instance_getBounded(*this);
- if(bounded != 0)
- {
- aabb_extend_by_aabb_safe(
- m_bounds,
- aabb_for_oriented_aabb_safe(bounded->localAABB(), localToWorld())
- );
- }
-
- m_boundsMutex = false;
- m_boundsChanged = false;
- }
- }
-
- Instance(const scene::Instance& other);
- Instance& operator=(const scene::Instance& other);
- public:
-
- Instance(const scene::Path& path, Instance* parent, void* instance, InstanceTypeCastTable& casts) :
- m_path(path),
- m_parent(parent),
- m_instance(instance),
- m_casts(casts),
- m_local2world(g_matrix4_identity),
- m_transformChanged(true),
- m_transformMutex(false),
- m_boundsChanged(true),
- m_boundsMutex(false),
- m_childBoundsChanged(true),
- m_childBoundsMutex(false),
- m_isSelectedChanged(true),
- m_childSelectedChanged(true),
- m_parentSelectedChanged(true)
- {
- ASSERT_MESSAGE((parent == 0) == (path.size() == 1), "instance has invalid parent");
- }
- virtual ~Instance()
- {
- }
-
- const scene::Path& path() const
- {
- return m_path;
- }
-
- void* cast(TypeId typeId) const
- {
- return m_casts.cast(typeId, m_instance);
- }
-
- const Matrix4& localToWorld() const
- {
- evaluateTransform();
- return m_local2world;
- }
- void transformChangedLocal()
- {
- ASSERT_NOTNULL(m_parent);
- m_transformChanged = true;
- m_boundsChanged = true;
- m_childBoundsChanged = true;
- m_transformChangedCallback();
- }
- void transformChanged()
- {
- GlobalSceneGraph().traverse_subgraph(TransformChangedWalker(), m_path);
- boundsChanged();
- }
- void setTransformChangedCallback(const Callback& callback)
- {
- m_transformChangedCallback = callback;
- }
-
-
- const AABB& worldAABB() const
- {
- evaluateBounds();
- return m_bounds;
- }
- const AABB& childBounds() const
- {
- evaluateChildBounds();
- return m_childBounds;
- }
- void boundsChanged()
- {
- m_boundsChanged = true;
- m_childBoundsChanged = true;
- if(m_parent != 0)
- {
- m_parent->boundsChanged();
- }
- GlobalSceneGraph().boundsChanged();
- }
-
- void childSelectedChanged()
- {
- m_childSelectedChanged = true;
- m_childSelectedChangedCallback();
- if(m_parent != 0)
- {
- m_parent->childSelectedChanged();
- }
- }
- bool childSelected() const
- {
- if(m_childSelectedChanged)
- {
- m_childSelectedChanged = false;
- GlobalSceneGraph().traverse_subgraph(ChildSelectedWalker(m_childSelected), m_path);
- }
- return m_childSelected;
- }
-
- void setChildSelectedChangedCallback(const Callback& callback)
- {
- m_childSelectedChangedCallback = callback;
- }
- void selectedChanged()
- {
- m_isSelectedChanged = true;
- if(m_parent != 0)
- {
- m_parent->childSelectedChanged();
- }
- GlobalSceneGraph().traverse_subgraph(ParentSelectedChangedWalker(), m_path);
- }
- bool isSelected() const
- {
- if(m_isSelectedChanged)
- {
- m_isSelectedChanged = false;
- const Selectable* selectable = Instance_getSelectable(*this);
- m_isSelected = selectable != 0 && selectable->isSelected();
- }
- return m_isSelected;
- }
-
- void parentSelectedChanged()
- {
- m_parentSelectedChanged = true;
- }
- bool parentSelected() const
- {
- if(m_parentSelectedChanged)
- {
- m_parentSelectedChanged = false;
- m_parentSelected = m_parent != 0 && (m_parent->isSelected() || m_parent->parentSelected());
- }
- return m_parentSelected;
- }
- };
+class Instance
+{
+class AABBAccumulateWalker : public scene::Graph::Walker
+{
+AABB& m_aabb;
+mutable std::size_t m_depth;
+public:
+AABBAccumulateWalker( AABB& aabb ) : m_aabb( aabb ), m_depth( 0 ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ if ( m_depth == 1 ) {
+ aabb_extend_by_aabb_safe( m_aabb, instance.worldAABB() );
+ }
+ return ++m_depth != 2;
+}
+void post( const scene::Path& path, scene::Instance& instance ) const {
+ --m_depth;
+}
+};
+
+
+class TransformChangedWalker : public scene::Graph::Walker
+{
+public:
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ instance.transformChangedLocal();
+ return true;
+}
+};
+
+class ParentSelectedChangedWalker : public scene::Graph::Walker
+{
+public:
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ instance.parentSelectedChanged();
+ return true;
+}
+};
+
+class ChildSelectedWalker : public scene::Graph::Walker
+{
+bool& m_childSelected;
+mutable std::size_t m_depth;
+public:
+ChildSelectedWalker( bool& childSelected ) : m_childSelected( childSelected ), m_depth( 0 ){
+ m_childSelected = false;
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ if ( m_depth == 1 && !m_childSelected ) {
+ m_childSelected = instance.isSelected() || instance.childSelected();
+ }
+ return ++m_depth != 2;
+}
+void post( const scene::Path& path, scene::Instance& instance ) const {
+ --m_depth;
+}
+};
+
+Path m_path;
+Instance* m_parent;
+void* m_instance;
+InstanceTypeCastTable& m_casts;
+
+mutable Matrix4 m_local2world;
+mutable AABB m_bounds;
+mutable AABB m_childBounds;
+mutable bool m_transformChanged;
+mutable bool m_transformMutex;
+mutable bool m_boundsChanged;
+mutable bool m_boundsMutex;
+mutable bool m_childBoundsChanged;
+mutable bool m_childBoundsMutex;
+mutable bool m_isSelected;
+mutable bool m_isSelectedChanged;
+mutable bool m_childSelected;
+mutable bool m_childSelectedChanged;
+mutable bool m_parentSelected;
+mutable bool m_parentSelectedChanged;
+Callback<void()> m_childSelectedChangedCallback;
+Callback<void()> m_transformChangedCallback;
+
+
+void evaluateTransform() const {
+ if ( m_transformChanged ) {
+ ASSERT_MESSAGE( !m_transformMutex, "re-entering transform evaluation" );
+ m_transformMutex = true;
+
+ m_local2world = ( m_parent != 0 ) ? m_parent->localToWorld() : g_matrix4_identity;
+ TransformNode* transformNode = Node_getTransformNode( m_path.top() );
+ if ( transformNode != 0 ) {
+ matrix4_multiply_by_matrix4( m_local2world, transformNode->localToParent() );
+ }
+
+ m_transformMutex = false;
+ m_transformChanged = false;
+ }
+}
+void evaluateChildBounds() const {
+ if ( m_childBoundsChanged ) {
+ ASSERT_MESSAGE( !m_childBoundsMutex, "re-entering bounds evaluation" );
+ m_childBoundsMutex = true;
+
+ m_childBounds = AABB();
+
+ GlobalSceneGraph().traverse_subgraph( AABBAccumulateWalker( m_childBounds ), m_path );
+
+ m_childBoundsMutex = false;
+ m_childBoundsChanged = false;
+ }
+}
+void evaluateBounds() const {
+ if ( m_boundsChanged ) {
+ ASSERT_MESSAGE( !m_boundsMutex, "re-entering bounds evaluation" );
+ m_boundsMutex = true;
+
+ m_bounds = childBounds();
+
+ const Bounded* bounded = Instance_getBounded( *this );
+ if ( bounded != 0 ) {
+ aabb_extend_by_aabb_safe(
+ m_bounds,
+ aabb_for_oriented_aabb_safe( bounded->localAABB(), localToWorld() )
+ );
+ }
+
+ m_boundsMutex = false;
+ m_boundsChanged = false;
+ }
+}
+
+Instance( const scene::Instance& other );
+Instance& operator=( const scene::Instance& other );
+public:
+
+Instance( const scene::Path& path, Instance* parent, void* instance, InstanceTypeCastTable& casts ) :
+ m_path( path ),
+ m_parent( parent ),
+ m_instance( instance ),
+ m_casts( casts ),
+ m_local2world( g_matrix4_identity ),
+ m_transformChanged( true ),
+ m_transformMutex( false ),
+ m_boundsChanged( true ),
+ m_boundsMutex( false ),
+ m_childBoundsChanged( true ),
+ m_childBoundsMutex( false ),
+ m_isSelectedChanged( true ),
+ m_childSelectedChanged( true ),
+ m_parentSelectedChanged( true ){
+ ASSERT_MESSAGE( ( parent == 0 ) == ( path.size() == 1 ), "instance has invalid parent" );
+}
+virtual ~Instance(){
+}
+
+const scene::Path& path() const {
+ return m_path;
+}
+
+void* cast( TypeId typeId ) const {
+ return m_casts.cast( typeId, m_instance );
+}
+
+const Matrix4& localToWorld() const {
+ evaluateTransform();
+ return m_local2world;
+}
+void transformChangedLocal(){
+ ASSERT_NOTNULL( m_parent );
+ m_transformChanged = true;
+ m_boundsChanged = true;
+ m_childBoundsChanged = true;
+ m_transformChangedCallback();
+}
+void transformChanged(){
+ GlobalSceneGraph().traverse_subgraph( TransformChangedWalker(), m_path );
+ boundsChanged();
+}
+void setTransformChangedCallback( const Callback<void()>& callback ){
+ m_transformChangedCallback = callback;
+}
+
+
+const AABB& worldAABB() const {
+ evaluateBounds();
+ return m_bounds;
+}
+const AABB& childBounds() const {
+ evaluateChildBounds();
+ return m_childBounds;
+}
+void boundsChanged(){
+ m_boundsChanged = true;
+ m_childBoundsChanged = true;
+ if ( m_parent != 0 ) {
+ m_parent->boundsChanged();
+ }
+ GlobalSceneGraph().boundsChanged();
+}
+
+void childSelectedChanged(){
+ m_childSelectedChanged = true;
+ m_childSelectedChangedCallback();
+ if ( m_parent != 0 ) {
+ m_parent->childSelectedChanged();
+ }
+}
+bool childSelected() const {
+ if ( m_childSelectedChanged ) {
+ m_childSelectedChanged = false;
+ GlobalSceneGraph().traverse_subgraph( ChildSelectedWalker( m_childSelected ), m_path );
+ }
+ return m_childSelected;
+}
+
+void setChildSelectedChangedCallback( const Callback<void()>& callback ){
+ m_childSelectedChangedCallback = callback;
+}
+void selectedChanged(){
+ m_isSelectedChanged = true;
+ if ( m_parent != 0 ) {
+ m_parent->childSelectedChanged();
+ }
+ GlobalSceneGraph().traverse_subgraph( ParentSelectedChangedWalker(), m_path );
+}
+bool isSelected() const {
+ if ( m_isSelectedChanged ) {
+ m_isSelectedChanged = false;
+ const Selectable* selectable = Instance_getSelectable( *this );
+ m_isSelected = selectable != 0 && selectable->isSelected();
+ }
+ return m_isSelected;
+}
+
+void parentSelectedChanged(){
+ m_parentSelectedChanged = true;
+}
+bool parentSelected() const {
+ if ( m_parentSelectedChanged ) {
+ m_parentSelectedChanged = false;
+ m_parentSelected = m_parent != 0 && ( m_parent->isSelected() || m_parent->parentSelected() );
+ }
+ return m_parentSelected;
+}
+};
}
template<typename Type>
class InstanceTypeCast
{
public:
- static Type* cast(scene::Instance& instance)
- {
- return static_cast<Type*>(instance.cast(StaticInstanceType<Type>::getTypeId()));
- }
- static const Type* cast(const scene::Instance& instance)
- {
- return static_cast<const Type*>(instance.cast(StaticInstanceType<Type>::getTypeId()));
- }
+static Type* cast( scene::Instance& instance ){
+ return static_cast<Type*>( instance.cast( StaticInstanceType<Type>::getTypeId() ) );
+}
+static const Type* cast( const scene::Instance& instance ){
+ return static_cast<const Type*>( instance.cast( StaticInstanceType<Type>::getTypeId() ) );
+}
};
template<typename Functor>
class InstanceWalker : public scene::Graph::Walker
{
- const Functor& m_functor;
+const Functor& m_functor;
public:
- InstanceWalker(const Functor& functor) : m_functor(functor)
- {
- }
- bool pre(const scene::Path& path, scene::Instance& instance) const
- {
- m_functor(instance);
- return true;
- }
+InstanceWalker( const Functor& functor ) : m_functor( functor ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ m_functor( instance );
+ return true;
+}
};
template<typename Functor>
class ChildInstanceWalker : public scene::Graph::Walker
{
- const Functor& m_functor;
- mutable std::size_t m_depth;
+const Functor& m_functor;
+mutable std::size_t m_depth;
public:
- ChildInstanceWalker(const Functor& functor) : m_functor(functor), m_depth(0)
- {
- }
- bool pre(const scene::Path& path, scene::Instance& instance) const
- {
- if(m_depth == 1)
- {
- m_functor(instance);
- }
- return ++m_depth != 2;
- }
- void post(const scene::Path& path, scene::Instance& instance) const
- {
- --m_depth;
- }
+ChildInstanceWalker( const Functor& functor ) : m_functor( functor ), m_depth( 0 ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ if ( m_depth == 1 ) {
+ m_functor( instance );
+ }
+ return ++m_depth != 2;
+}
+void post( const scene::Path& path, scene::Instance& instance ) const {
+ --m_depth;
+}
};
template<typename Type, typename Functor>
class InstanceApply : public Functor
{
public:
- InstanceApply(const Functor& functor) : Functor(functor)
- {
- }
- void operator()(scene::Instance& instance) const
- {
- Type* result = InstanceTypeCast<Type>::cast(instance);
- if(result != 0)
- {
- Functor::operator()(*result);
- }
- }
+InstanceApply( const Functor& functor ) : Functor( functor ){
+}
+void operator()( scene::Instance& instance ) const {
+ Type* result = InstanceTypeCast<Type>::cast( instance );
+ if ( result != 0 ) {
+ Functor::operator()( *result );
+ }
+}
};
-inline Selectable* Instance_getSelectable(scene::Instance& instance)
-{
- return InstanceTypeCast<Selectable>::cast(instance);
+inline Selectable* Instance_getSelectable( scene::Instance& instance ){
+ return InstanceTypeCast<Selectable>::cast( instance );
}
-inline const Selectable* Instance_getSelectable(const scene::Instance& instance)
-{
- return InstanceTypeCast<Selectable>::cast(instance);
+inline const Selectable* Instance_getSelectable( const scene::Instance& instance ){
+ return InstanceTypeCast<Selectable>::cast( instance );
}
template<typename Functor>
-inline void Scene_forEachChildSelectable(const Functor& functor, const scene::Path& path)
-{
- GlobalSceneGraph().traverse_subgraph(ChildInstanceWalker< InstanceApply<Selectable, Functor> >(functor), path);
+inline void Scene_forEachChildSelectable( const Functor& functor, const scene::Path& path ){
+ GlobalSceneGraph().traverse_subgraph( ChildInstanceWalker< InstanceApply<Selectable, Functor> >( functor ), path );
}
class SelectableSetSelected
{
- bool m_selected;
+bool m_selected;
public:
- SelectableSetSelected(bool selected) : m_selected(selected)
- {
- }
- void operator()(Selectable& selectable) const
- {
- selectable.setSelected(m_selected);
- }
+SelectableSetSelected( bool selected ) : m_selected( selected ){
+}
+void operator()( Selectable& selectable ) const {
+ selectable.setSelected( m_selected );
+}
};
-inline Bounded* Instance_getBounded(scene::Instance& instance)
-{
- return InstanceTypeCast<Bounded>::cast(instance);
+inline Bounded* Instance_getBounded( scene::Instance& instance ){
+ return InstanceTypeCast<Bounded>::cast( instance );
}
-inline const Bounded* Instance_getBounded(const scene::Instance& instance)
-{
- return InstanceTypeCast<Bounded>::cast(instance);
+inline const Bounded* Instance_getBounded( const scene::Instance& instance ){
+ return InstanceTypeCast<Bounded>::cast( instance );
}
-inline Transformable* Instance_getTransformable(scene::Instance& instance)
-{
- return InstanceTypeCast<Transformable>::cast(instance);
+inline Transformable* Instance_getTransformable( scene::Instance& instance ){
+ return InstanceTypeCast<Transformable>::cast( instance );
}
-inline const Transformable* Instance_getTransformable(const scene::Instance& instance)
-{
- return InstanceTypeCast<Transformable>::cast(instance);
+inline const Transformable* Instance_getTransformable( const scene::Instance& instance ){
+ return InstanceTypeCast<Transformable>::cast( instance );
}
-inline ComponentSelectionTestable* Instance_getComponentSelectionTestable(scene::Instance& instance)
-{
- return InstanceTypeCast<ComponentSelectionTestable>::cast(instance);
+inline ComponentSelectionTestable* Instance_getComponentSelectionTestable( scene::Instance& instance ){
+ return InstanceTypeCast<ComponentSelectionTestable>::cast( instance );
}
-inline ComponentEditable* Instance_getComponentEditable(scene::Instance& instance)
-{
- return InstanceTypeCast<ComponentEditable>::cast(instance);
+inline ComponentEditable* Instance_getComponentEditable( scene::Instance& instance ){
+ return InstanceTypeCast<ComponentEditable>::cast( instance );
}
-inline ComponentSnappable* Instance_getComponentSnappable(scene::Instance& instance)
-{
- return InstanceTypeCast<ComponentSnappable>::cast(instance);
+inline ComponentSnappable* Instance_getComponentSnappable( scene::Instance& instance ){
+ return InstanceTypeCast<ComponentSnappable>::cast( instance );
}
-inline void Instance_setSelected(scene::Instance& instance, bool selected)
-{
- Selectable* selectable = Instance_getSelectable(instance);
- if(selectable != 0)
- {
- selectable->setSelected(selected);
- }
+inline void Instance_setSelected( scene::Instance& instance, bool selected ){
+ Selectable* selectable = Instance_getSelectable( instance );
+ if ( selectable != 0 ) {
+ selectable->setSelected( selected );
+ }
}
-inline bool Instance_isSelected(scene::Instance& instance)
-{
- Selectable* selectable = Instance_getSelectable(instance);
- if(selectable != 0)
- {
- return selectable->isSelected();
- }
- return false;
+inline bool Instance_isSelected( scene::Instance& instance ){
+ Selectable* selectable = Instance_getSelectable( instance );
+ if ( selectable != 0 ) {
+ return selectable->isSelected();
+ }
+ return false;
}
-inline scene::Instance& findInstance(const scene::Path& path)
-{
- scene::Instance* instance = GlobalSceneGraph().find(path);
- ASSERT_MESSAGE(instance != 0, "findInstance: path not found in scene-graph");
- return *instance;
+inline scene::Instance& findInstance( const scene::Path& path ){
+ scene::Instance* instance = GlobalSceneGraph().find( path );
+ ASSERT_MESSAGE( instance != 0, "findInstance: path not found in scene-graph" );
+ return *instance;
}
-inline void selectPath(const scene::Path& path, bool selected)
-{
- Instance_setSelected(findInstance(path), selected);
+inline void selectPath( const scene::Path& path, bool selected ){
+ Instance_setSelected( findInstance( path ), selected );
}
class SelectChildren : public scene::Traversable::Walker
{
- mutable scene::Path m_path;
+mutable scene::Path m_path;
public:
- SelectChildren(const scene::Path& root)
- : m_path(root)
- {
- }
- bool pre(scene::Node& node) const
- {
- m_path.push(makeReference(node));
- selectPath(m_path, true);
- return false;
- }
- void post(scene::Node& node) const
- {
- m_path.pop();
- }
+SelectChildren( const scene::Path& root )
+ : m_path( root ){
+}
+bool pre( scene::Node& node ) const {
+ m_path.push( makeReference( node ) );
+ selectPath( m_path, true );
+ return false;
+}
+void post( scene::Node& node ) const {
+ m_path.pop();
+}
};
-inline void Entity_setSelected(scene::Instance& entity, bool selected)
-{
- scene::Node& node = entity.path().top();
- if(node_is_group(node))
- {
- Node_getTraversable(node)->traverse(SelectChildren(entity.path()));
- }
- else
- {
- Instance_setSelected(entity, selected);
- }
-}
-
-inline bool Entity_isSelected(scene::Instance& entity)
-{
- if(node_is_group(entity.path().top()))
- {
- return entity.childSelected();
- }
- return Instance_isSelected(entity);
+inline void Entity_setSelected( scene::Instance& entity, bool selected ){
+ scene::Node& node = entity.path().top();
+ if ( node_is_group( node ) ) {
+ Node_getTraversable( node )->traverse( SelectChildren( entity.path() ) );
+ }
+ else
+ {
+ Instance_setSelected( entity, selected );
+ }
+}
+
+inline bool Entity_isSelected( scene::Instance& entity ){
+ if ( node_is_group( entity.path().top() ) ) {
+ return entity.childSelected();
+ }
+ return Instance_isSelected( entity );
}
class InstanceCounter
{
public:
- unsigned int m_count;
- InstanceCounter() : m_count(0)
- {
- }
+unsigned int m_count;
+InstanceCounter() : m_count( 0 ){
+}
};
class Counter
{
public:
- virtual void increment() = 0;
- virtual void decrement() = 0;
+virtual void increment() = 0;
+virtual void decrement() = 0;
};
#include "generic/callback.h"
class SimpleCounter : public Counter
{
- Callback m_countChanged;
- std::size_t m_count;
+Callback<void()> m_countChanged;
+std::size_t m_count;
public:
- void setCountChangedCallback(const Callback& countChanged)
- {
- m_countChanged = countChanged;
- }
- void increment()
- {
- ++m_count;
- m_countChanged();
- }
- void decrement()
- {
- --m_count;
- m_countChanged();
- }
- std::size_t get() const
- {
- return m_count;
- }
+void setCountChangedCallback( const Callback<void()>& countChanged ){
+ m_countChanged = countChanged;
+}
+void increment(){
+ ++m_count;
+ m_countChanged();
+}
+void decrement(){
+ --m_count;
+ m_countChanged();
+}
+std::size_t get() const {
+ return m_count;
+}
};