scenelib.h

Go to the documentation of this file.
00001 
00005 /*
00006  Copyright (C) 2001-2006, William Joseph.
00007  All Rights Reserved.
00008 
00009  This file is part of GtkRadiant.
00010 
00011  GtkRadiant is free software; you can redistribute it and/or modify
00012  it under the terms of the GNU General Public License as published by
00013  the Free Software Foundation; either version 2 of the License, or
00014  (at your option) any later version.
00015 
00016  GtkRadiant is distributed in the hope that it will be useful,
00017  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  GNU General Public License for more details.
00020 
00021  You should have received a copy of the GNU General Public License
00022  along with GtkRadiant; if not, write to the Free Software
00023  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00024  */
00025 
00026 #if !defined (INCLUDED_SCENELIB_H)
00027 #define INCLUDED_SCENELIB_H
00028 
00029 #include "Bounded.h"
00030 #include "iscenegraph.h"
00031 #include "iselection.h"
00032 
00033 #include <cstddef>
00034 #include <string.h>
00035 
00036 #include "math/aabb.h"
00037 #include "transformlib.h"
00038 #include "generic/callback.h"
00039 #include "generic/reference.h"
00040 #include "container/stack.h"
00041 #include "typesystem.h"
00042 
00043 class Selector;
00044 class SelectionTest;
00045 class VolumeTest;
00046 template<typename Element> class BasicVector3;
00047 typedef BasicVector3<float> Vector3;
00048 template<typename Element> class BasicVector4;
00049 typedef BasicVector4<float> Vector4;
00050 class Matrix4;
00051 typedef Vector4 Quaternion;
00052 class AABB;
00053 
00054 class ComponentSelectionTestable
00055 {
00056     public:
00057         STRING_CONSTANT(Name, "ComponentSelectionTestable");
00058 
00059         virtual ~ComponentSelectionTestable ()
00060         {
00061         }
00062 
00063         virtual bool isSelectedComponents () const = 0;
00064         virtual void setSelectedComponents (bool select, SelectionSystem::EComponentMode mode) = 0;
00065         virtual void testSelectComponents (Selector& selector, SelectionTest& test,
00066                 SelectionSystem::EComponentMode mode) = 0;
00067 };
00068 
00069 class ComponentEditable
00070 {
00071     public:
00072         STRING_CONSTANT(Name, "ComponentEditable");
00073 
00074         virtual ~ComponentEditable ()
00075         {
00076         }
00077         virtual const AABB& getSelectedComponentsBounds () const = 0;
00078 };
00079 
00080 class ComponentSnappable
00081 {
00082     public:
00083         STRING_CONSTANT(Name, "ComponentSnappable");
00084 
00085         virtual ~ComponentSnappable ()
00086         {
00087         }
00088         virtual void snapComponents (float snap) = 0;
00089 };
00090 
00091 typedef TypeCastTable<NODETYPEID_MAX> NodeTypeCastTable;
00092 
00093 template<typename Type>
00094 class NodeType: public StaticTypeSystemInitialiser
00095 {
00096         TypeId m_typeId;
00097     public:
00098         typedef typename Type::Name Name;
00099         NodeType () :
00100             m_typeId(NODETYPEID_NONE)
00101         {
00102             StaticTypeSystemInitialiser::instance().addInitialiser(InitialiseCaller(*this));
00103         }
00104         void initialise ()
00105         {
00106             m_typeId = GlobalSceneGraph().getNodeTypeId(Name());
00107         }
00108         typedef MemberCaller<NodeType<Type> , &NodeType<Type>::initialise> InitialiseCaller;
00109         TypeId getTypeId ()
00110         {
00111 #if defined(DEBUG)
00112             ASSERT_MESSAGE(m_typeId != NODETYPEID_NONE, "node-type " << makeQuoted(Name()) << " used before being initialised");
00113 #endif
00114             return m_typeId;
00115         }
00116 };
00117 
00118 template<typename Type>
00119 class StaticNodeType
00120 {
00121     public:
00122         enum unnamed0
00123         {
00124             SIZE = NODETYPEID_MAX
00125         };
00126         static TypeId getTypeId ()
00127         {
00128             return Static<NodeType<Type> >::instance().getTypeId();
00129         }
00130 };
00131 
00132 template<typename Type, typename Contained>
00133 class NodeContainedCast: public CastInstaller<StaticNodeType<Contained> , ContainedCast<Type, Contained> >
00134 {
00135 };
00136 
00137 template<typename Type>
00138 class NodeIdentityCast: public CastInstaller<StaticNodeType<Type> , IdentityCast<Type> >
00139 {
00140 };
00141 
00142 namespace scene
00143 {
00144     class Node
00145     {
00146         public:
00147             enum unnamed0
00148             {
00149                 eVisible = 0
00150             };
00151             enum unnamed1
00152             {
00153                 eHidden = 1 << 0
00154             };
00155             enum unnamed2
00156             {
00157                 eFiltered = 1 << 1
00158             };
00159             enum unnamed3
00160             {
00161                 eExcluded = 1 << 2
00162             };
00163 
00164         private:
00165             unsigned int m_state;
00166             std::size_t m_refcount;
00167             void* m_node;
00168             NodeTypeCastTable& m_casts;
00169 
00170         public:
00171             bool m_isRoot;
00172 
00173             bool isRoot ()
00174             {
00175                 return m_isRoot;
00176             }
00177 
00178             Node (void* node, NodeTypeCastTable& casts) :
00179                 m_state(eVisible), m_refcount(0), m_node(node), m_casts(casts), m_isRoot(false)
00180             {
00181             }
00182 
00183             virtual ~Node ()
00184             {
00185             }
00186 
00187             virtual void release ()
00188             {
00189                 // Default implementation: remove this node
00190                 delete this;
00191             }
00192 
00193             void IncRef ()
00194             {
00195                 ASSERT_MESSAGE(m_refcount < (1 << 24), "Node::decref: uninitialised refcount");
00196                 ++m_refcount;
00197             }
00198             void DecRef ()
00199             {
00200                 ASSERT_MESSAGE(m_refcount < (1 << 24), "Node::decref: uninitialised refcount");
00201                 if (--m_refcount == 0) {
00202                     release();
00203                 }
00204             }
00205             std::size_t getReferenceCount () const
00206             {
00207                 return m_refcount;
00208             }
00209 
00210             void* cast (TypeId typeId) const
00211             {
00212                 return m_casts.cast(typeId, m_node);
00213             }
00214 
00215             void enable (unsigned int state)
00216             {
00217                 m_state |= state;
00218             }
00219             void disable (unsigned int state)
00220             {
00221                 m_state &= ~state;
00222             }
00223             bool visible ()
00224             {
00225                 return m_state == eVisible;
00226             }
00227             bool excluded ()
00228             {
00229                 return (m_state & eExcluded) != 0;
00230             }
00231     };
00232 
00233     class NullNode: public Node
00234     {
00235             NodeTypeCastTable m_casts;
00236         public:
00237             NullNode () :
00238                 scene::Node(NULL, m_casts)
00239             {
00240             }
00241 
00242             scene::Node& node ()
00243             {
00244                 return *this;
00245             }
00246     };
00247 }
00248 
00249 template<typename Type>
00250 class NodeTypeCast
00251 {
00252     public:
00253         static Type* cast (scene::Node& node)
00254         {
00255             return static_cast<Type*> (node.cast(StaticNodeType<Type>::getTypeId()));
00256         }
00257         static const Type* cast (const scene::Node& node)
00258         {
00259             return static_cast<const Type*> (node.cast(StaticNodeType<Type>::getTypeId()));
00260         }
00261 };
00262 
00263 inline scene::Instantiable* Node_getInstantiable (scene::Node& node)
00264 {
00265     return dynamic_cast<scene::Instantiable*>(&node);
00266 }
00267 
00268 inline scene::Traversable* Node_getTraversable (scene::Node& node)
00269 {
00270     return NodeTypeCast<scene::Traversable>::cast(node);
00271 }
00272 
00273 inline void Node_traverseSubgraph (scene::Node& node, const scene::Traversable::Walker& walker)
00274 {
00275     if (walker.pre(node)) {
00276         scene::Traversable* traversable = Node_getTraversable(node);
00277         if (traversable != 0) {
00278             traversable->traverse(walker);
00279         }
00280     }
00281     walker.post(node);
00282 }
00283 
00284 inline TransformNode* Node_getTransformNode (scene::Node& node)
00285 {
00286     return NodeTypeCast<TransformNode>::cast(node);
00287 }
00288 
00289 inline bool operator< (scene::Node& node, scene::Node& other)
00290 {
00291     return &node < &other;
00292 }
00293 inline bool operator== (scene::Node& node, scene::Node& other)
00294 {
00295     return &node == &other;
00296 }
00297 inline bool operator!= (scene::Node& node, scene::Node& other)
00298 {
00299     return !::operator==(node, other);
00300 }
00301 
00302 inline scene::Node& NewNullNode ()
00303 {
00304     return (new scene::NullNode)->node();
00305 }
00306 
00307 inline void Path_deleteTop (const scene::Path& path)
00308 {
00309     Node_getTraversable(path.parent())->erase(path.top());
00310 }
00311 
00312 class delete_all: public scene::Traversable::Walker
00313 {
00314         scene::Node& m_parent;
00315     public:
00316         delete_all (scene::Node& parent) :
00317             m_parent(parent)
00318         {
00319         }
00320         bool pre (scene::Node& node) const
00321         {
00322             return false;
00323         }
00324         void post (scene::Node& node) const
00325         {
00326             Node_getTraversable(m_parent)->erase(node);
00327         }
00328 };
00329 
00330 inline void DeleteSubgraph (scene::Node& subgraph)
00331 {
00332     Node_getTraversable(subgraph)->traverse(delete_all(subgraph));
00333 }
00334 
00335 class EntityUndefined
00336 {
00337     public:
00338         STRING_CONSTANT(Name, "Entity");
00339 };
00340 
00341 inline bool Node_isEntity (scene::Node& node)
00342 {
00343     return NodeTypeCast<EntityUndefined>::cast(node) != 0;
00344 }
00345 
00346 template<typename Functor>
00347 class EntityWalker: public scene::Graph::Walker
00348 {
00349         const Functor& functor;
00350     public:
00351         EntityWalker (const Functor& functor) :
00352             functor(functor)
00353         {
00354         }
00355         bool pre (const scene::Path& path, scene::Instance& instance) const
00356         {
00357             if (Node_isEntity(path.top())) {
00358                 functor(instance);
00359                 return false;
00360             }
00361             return true;
00362         }
00363 };
00364 
00365 template<typename Functor>
00366 inline const Functor& Scene_forEachEntity (const Functor& functor)
00367 {
00368     GlobalSceneGraph().traverse(EntityWalker<Functor> (functor));
00369     return functor;
00370 }
00371 
00372 class BrushUndefined
00373 {
00374     public:
00375         STRING_CONSTANT(Name, "Brush");
00376 };
00377 
00378 inline bool Node_isBrush (scene::Node& node)
00379 {
00380     return NodeTypeCast<BrushUndefined>::cast(node) != 0;
00381 }
00382 
00383 inline bool Node_isPrimitive (scene::Node& node)
00384 {
00385     return Node_isBrush(node);
00386 }
00387 
00388 class ParentBrushes: public scene::Traversable::Walker
00389 {
00390         scene::Node& m_parent;
00391     public:
00392         ParentBrushes (scene::Node& parent) :
00393             m_parent(parent)
00394         {
00395         }
00396         bool pre (scene::Node& node) const
00397         {
00398             return false;
00399         }
00400         void post (scene::Node& node) const
00401         {
00402             if (Node_isPrimitive(node)) {
00403                 Node_getTraversable(m_parent)->insert(node);
00404             }
00405         }
00406 };
00407 
00408 inline void parentBrushes (scene::Node& subgraph, scene::Node& parent)
00409 {
00410     Node_getTraversable(subgraph)->traverse(ParentBrushes(parent));
00411 }
00412 
00413 class HasBrushes: public scene::Traversable::Walker
00414 {
00415         bool& m_hasBrushes;
00416     public:
00417         HasBrushes (bool& hasBrushes) :
00418             m_hasBrushes(hasBrushes)
00419         {
00420             m_hasBrushes = true;
00421         }
00422         bool pre (scene::Node& node) const
00423         {
00424             if (!Node_isPrimitive(node)) {
00425                 m_hasBrushes = false;
00426             }
00427             return false;
00428         }
00429 };
00430 
00431 inline bool node_is_group (scene::Node& node)
00432 {
00433     scene::Traversable* traversable = Node_getTraversable(node);
00434     if (traversable != 0) {
00435         bool hasBrushes = false;
00436         traversable->traverse(HasBrushes(hasBrushes));
00437         return hasBrushes;
00438     }
00439     return false;
00440 }
00441 
00442 typedef TypeCastTable<INSTANCETYPEID_MAX> InstanceTypeCastTable;
00443 
00444 template<typename Type>
00445 class InstanceType: public StaticTypeSystemInitialiser
00446 {
00447         TypeId m_typeId;
00448     public:
00449         typedef typename Type::Name Name;
00450         InstanceType () :
00451             m_typeId(INSTANCETYPEID_NONE)
00452         {
00453             StaticTypeSystemInitialiser::instance().addInitialiser(InitialiseCaller(*this));
00454         }
00455         void initialise ()
00456         {
00457             m_typeId = GlobalSceneGraph().getInstanceTypeId(Name());
00458         }
00459         typedef MemberCaller<InstanceType<Type> , &InstanceType<Type>::initialise> InitialiseCaller;
00460         TypeId getTypeId ()
00461         {
00462 #if defined(DEBUG)
00463             ASSERT_MESSAGE(m_typeId != INSTANCETYPEID_NONE, "instance-type " << makeQuoted(Name()) << " used before being initialised");
00464 #endif
00465             return m_typeId;
00466         }
00467 };
00468 
00469 template<typename Type>
00470 class StaticInstanceType
00471 {
00472     public:
00473         enum unnamed0
00474         {
00475             SIZE = INSTANCETYPEID_MAX
00476         };
00477         static TypeId getTypeId ()
00478         {
00479             return Static<InstanceType<Type> >::instance().getTypeId();
00480         }
00481 };
00482 
00483 template<typename Type, typename Base>
00484 class InstanceStaticCast: public CastInstaller<StaticInstanceType<Base> , StaticCast<Type, Base> >
00485 {
00486 };
00487 
00488 template<typename Type, typename Contained>
00489 class InstanceContainedCast: public CastInstaller<StaticInstanceType<Contained> , ContainedCast<Type, Contained> >
00490 {
00491 };
00492 
00493 template<typename Type>
00494 class InstanceIdentityCast: public CastInstaller<StaticInstanceType<Type> , IdentityCast<Type> >
00495 {
00496 };
00497 
00498 inline Selectable* Instance_getSelectable (scene::Instance& instance);
00499 inline const Selectable* Instance_getSelectable (const scene::Instance& instance);
00500 
00501 inline Bounded* Instance_getBounded (scene::Instance& instance);
00502 inline const Bounded* Instance_getBounded (const scene::Instance& instance);
00503 
00504 namespace scene
00505 {
00506     class Instance
00507     {
00508             class AABBAccumulateWalker: public scene::Graph::Walker
00509             {
00510                     AABB& m_aabb;
00511                     mutable std::size_t m_depth;
00512                 public:
00513                     AABBAccumulateWalker (AABB& aabb) :
00514                         m_aabb(aabb), m_depth(0)
00515                     {
00516                     }
00517                     bool pre (const scene::Path& path, scene::Instance& instance) const
00518                     {
00519                         if (m_depth == 1) {
00520                             m_aabb.includeAABB(instance.worldAABB());
00521                         }
00522                         return ++m_depth != 2;
00523                     }
00524                     void post (const scene::Path& path, scene::Instance& instance) const
00525                     {
00526                         --m_depth;
00527                     }
00528             };
00529 
00530             class TransformChangedWalker: public scene::Graph::Walker
00531             {
00532                 public:
00533                     bool pre (const scene::Path& path, scene::Instance& instance) const
00534                     {
00535                         instance.transformChangedLocal();
00536                         return true;
00537                     }
00538             };
00539 
00540             class ParentSelectedChangedWalker: public scene::Graph::Walker
00541             {
00542                 public:
00543                     bool pre (const scene::Path& path, scene::Instance& instance) const
00544                     {
00545                         instance.parentSelectedChanged();
00546                         return true;
00547                     }
00548             };
00549 
00550             class ChildSelectedWalker: public scene::Graph::Walker
00551             {
00552                     bool& m_childSelected;
00553                     mutable std::size_t m_depth;
00554                 public:
00555                     ChildSelectedWalker (bool& childSelected) :
00556                         m_childSelected(childSelected), m_depth(0)
00557                     {
00558                         m_childSelected = false;
00559                     }
00560                     bool pre (const scene::Path& path, scene::Instance& instance) const
00561                     {
00562                         if (m_depth == 1 && !m_childSelected) {
00563                             m_childSelected = instance.isSelected() || instance.childSelected();
00564                         }
00565                         return ++m_depth != 2;
00566                     }
00567                     void post (const scene::Path& path, scene::Instance& instance) const
00568                     {
00569                         --m_depth;
00570                     }
00571             };
00572 
00573             Path m_path;
00574             Instance* m_parent;
00575             void* m_instance;
00576             InstanceTypeCastTable& m_casts;
00577 
00578             mutable Matrix4 m_local2world;
00579             mutable AABB m_bounds;
00580             mutable AABB m_childBounds;
00581             mutable bool m_transformChanged;
00582             mutable bool m_transformMutex;
00583             mutable bool m_boundsChanged;
00584             mutable bool m_boundsMutex;
00585             mutable bool m_childBoundsChanged;
00586             mutable bool m_childBoundsMutex;
00587             mutable bool m_isSelected;
00588             mutable bool m_isSelectedChanged;
00589             mutable bool m_childSelected;
00590             mutable bool m_childSelectedChanged;
00591             mutable bool m_parentSelected;
00592             mutable bool m_parentSelectedChanged;
00593             Callback m_childSelectedChangedCallback;
00594             Callback m_transformChangedCallback;
00595 
00596             void evaluateTransform () const
00597             {
00598                 if (m_transformChanged) {
00599                     ASSERT_MESSAGE(!m_transformMutex, "re-entering transform evaluation");
00600                     m_transformMutex = true;
00601 
00602                     m_local2world = (m_parent != 0) ? m_parent->localToWorld() : g_matrix4_identity;
00603                     TransformNode* transformNode = Node_getTransformNode(m_path.top());
00604                     if (transformNode != 0) {
00605                         matrix4_multiply_by_matrix4(m_local2world, transformNode->localToParent());
00606                     }
00607 
00608                     m_transformMutex = false;
00609                     m_transformChanged = false;
00610                 }
00611             }
00612             void evaluateChildBounds () const
00613             {
00614                 if (m_childBoundsChanged) {
00615                     ASSERT_MESSAGE(!m_childBoundsMutex, "re-entering bounds evaluation");
00616                     m_childBoundsMutex = true;
00617 
00618                     m_childBounds = AABB();
00619 
00620                     GlobalSceneGraph().traverse_subgraph(AABBAccumulateWalker(m_childBounds), m_path);
00621 
00622                     m_childBoundsMutex = false;
00623                     m_childBoundsChanged = false;
00624                 }
00625             }
00626             void evaluateBounds () const
00627             {
00628                 if (m_boundsChanged) {
00629                     ASSERT_MESSAGE(!m_boundsMutex, "re-entering bounds evaluation");
00630                     m_boundsMutex = true;
00631 
00632                     m_bounds = childBounds();
00633 
00634                     const Bounded* bounded = Instance_getBounded(*this);
00635                     if (bounded != 0) {
00636                         m_bounds.includeAABB(aabb_for_oriented_aabb_safe(bounded->localAABB(), localToWorld()));
00637                     }
00638 
00639                     m_boundsMutex = false;
00640                     m_boundsChanged = false;
00641                 }
00642             }
00643 
00644             Instance (const scene::Instance& other);
00645             Instance& operator= (const scene::Instance& other);
00646         public:
00647 
00648             Instance (const scene::Path& path, Instance* parent, void* instance, InstanceTypeCastTable& casts) :
00649                 m_path(path), m_parent(parent), m_instance(instance), m_casts(casts),
00650                         m_local2world(g_matrix4_identity), m_transformChanged(true), m_transformMutex(false),
00651                         m_boundsChanged(true), m_boundsMutex(false), m_childBoundsChanged(true), m_childBoundsMutex(
00652                                 false), m_isSelectedChanged(true), m_childSelectedChanged(true),
00653                         m_parentSelectedChanged(true)
00654             {
00655                 ASSERT_MESSAGE((parent == 0) == (path.size() == 1), "instance has invalid parent");
00656             }
00657             virtual ~Instance ()
00658             {
00659             }
00660 
00661             const scene::Path& path () const
00662             {
00663                 return m_path;
00664             }
00665 
00666             void* cast (TypeId typeId) const
00667             {
00668                 return m_casts.cast(typeId, m_instance);
00669             }
00670 
00671             const Matrix4& localToWorld () const
00672             {
00673                 evaluateTransform();
00674                 return m_local2world;
00675             }
00676             void transformChangedLocal ()
00677             {
00678                 ASSERT_NOTNULL(m_parent);
00679                 m_transformChanged = true;
00680                 m_boundsChanged = true;
00681                 m_childBoundsChanged = true;
00682                 m_transformChangedCallback();
00683             }
00684             void transformChanged ()
00685             {
00686                 GlobalSceneGraph().traverse_subgraph(TransformChangedWalker(), m_path);
00687                 boundsChanged();
00688             }
00689             void setTransformChangedCallback (const Callback& callback)
00690             {
00691                 m_transformChangedCallback = callback;
00692             }
00693 
00694             const AABB& worldAABB () const
00695             {
00696                 evaluateBounds();
00697                 return m_bounds;
00698             }
00699             const AABB& childBounds () const
00700             {
00701                 evaluateChildBounds();
00702                 return m_childBounds;
00703             }
00704             void boundsChanged ()
00705             {
00706                 m_boundsChanged = true;
00707                 m_childBoundsChanged = true;
00708                 if (m_parent != 0) {
00709                     m_parent->boundsChanged();
00710                 }
00711                 GlobalSceneGraph().boundsChanged();
00712             }
00713 
00714             void childSelectedChanged ()
00715             {
00716                 m_childSelectedChanged = true;
00717                 m_childSelectedChangedCallback();
00718                 if (m_parent != 0) {
00719                     m_parent->childSelectedChanged();
00720                 }
00721             }
00722             bool childSelected () const
00723             {
00724                 if (m_childSelectedChanged) {
00725                     m_childSelectedChanged = false;
00726                     GlobalSceneGraph().traverse_subgraph(ChildSelectedWalker(m_childSelected), m_path);
00727                 }
00728                 return m_childSelected;
00729             }
00730 
00731             void setChildSelectedChangedCallback (const Callback& callback)
00732             {
00733                 m_childSelectedChangedCallback = callback;
00734             }
00735             void selectedChanged ()
00736             {
00737                 m_isSelectedChanged = true;
00738                 if (m_parent != 0) {
00739                     m_parent->childSelectedChanged();
00740                 }
00741                 GlobalSceneGraph().traverse_subgraph(ParentSelectedChangedWalker(), m_path);
00742             }
00743             bool isSelected () const
00744             {
00745                 if (m_isSelectedChanged) {
00746                     m_isSelectedChanged = false;
00747                     const Selectable* selectable = Instance_getSelectable(*this);
00748                     m_isSelected = selectable != 0 && selectable->isSelected();
00749                 }
00750                 return m_isSelected;
00751             }
00752 
00753             void parentSelectedChanged ()
00754             {
00755                 m_parentSelectedChanged = true;
00756             }
00757             bool parentSelected () const
00758             {
00759                 if (m_parentSelectedChanged) {
00760                     m_parentSelectedChanged = false;
00761                     m_parentSelected = m_parent != 0 && (m_parent->isSelected() || m_parent->parentSelected());
00762                 }
00763                 return m_parentSelected;
00764             }
00765     };
00766 }
00767 
00768 template<typename Type>
00769 class InstanceTypeCast
00770 {
00771     public:
00772         static Type* cast (scene::Instance& instance)
00773         {
00774             return static_cast<Type*> (instance.cast(StaticInstanceType<Type>::getTypeId()));
00775         }
00776         static const Type* cast (const scene::Instance& instance)
00777         {
00778             return static_cast<const Type*> (instance.cast(StaticInstanceType<Type>::getTypeId()));
00779         }
00780 };
00781 
00782 template<typename Functor>
00783 class InstanceWalker: public scene::Graph::Walker
00784 {
00785         const Functor& m_functor;
00786     public:
00787         InstanceWalker (const Functor& functor) :
00788             m_functor(functor)
00789         {
00790         }
00791         bool pre (const scene::Path& path, scene::Instance& instance) const
00792         {
00793             m_functor(instance);
00794             return true;
00795         }
00796 };
00797 
00798 template<typename Functor>
00799 class ChildInstanceWalker: public scene::Graph::Walker
00800 {
00801         const Functor& m_functor;
00802         mutable std::size_t m_depth;
00803     public:
00804         ChildInstanceWalker (const Functor& functor) :
00805             m_functor(functor), m_depth(0)
00806         {
00807         }
00808         bool pre (const scene::Path& path, scene::Instance& instance) const
00809         {
00810             if (m_depth == 1) {
00811                 m_functor(instance);
00812             }
00813             return ++m_depth != 2;
00814         }
00815         void post (const scene::Path& path, scene::Instance& instance) const
00816         {
00817             --m_depth;
00818         }
00819 };
00820 
00821 template<typename Type, typename Functor>
00822 class InstanceApply: public Functor
00823 {
00824     public:
00825         InstanceApply (const Functor& functor) :
00826             Functor(functor)
00827         {
00828         }
00829         void operator() (scene::Instance& instance) const
00830         {
00831             Type* result = InstanceTypeCast<Type>::cast(instance);
00832             if (result != 0) {
00833                 Functor::operator()(*result);
00834             }
00835         }
00836 };
00837 
00838 inline Selectable* Instance_getSelectable (scene::Instance& instance)
00839 {
00840     return InstanceTypeCast<Selectable>::cast(instance);
00841 }
00842 inline const Selectable* Instance_getSelectable (const scene::Instance& instance)
00843 {
00844     return InstanceTypeCast<Selectable>::cast(instance);
00845 }
00846 
00847 template<typename Functor>
00848 inline void Scene_forEachChildSelectable (const Functor& functor, const scene::Path& path)
00849 {
00850     GlobalSceneGraph().traverse_subgraph(ChildInstanceWalker<InstanceApply<Selectable, Functor> > (functor), path);
00851 }
00852 
00853 class SelectableSetSelected
00854 {
00855         bool m_selected;
00856     public:
00857         SelectableSetSelected (bool selected) :
00858             m_selected(selected)
00859         {
00860         }
00861         void operator() (Selectable& selectable) const
00862         {
00863             selectable.setSelected(m_selected);
00864         }
00865 };
00866 
00867 inline Bounded* Instance_getBounded (scene::Instance& instance)
00868 {
00869     return InstanceTypeCast<Bounded>::cast(instance);
00870 }
00871 inline const Bounded* Instance_getBounded (const scene::Instance& instance)
00872 {
00873     return InstanceTypeCast<Bounded>::cast(instance);
00874 }
00875 
00876 inline Transformable* Instance_getTransformable (scene::Instance& instance)
00877 {
00878     return InstanceTypeCast<Transformable>::cast(instance);
00879 }
00880 inline const Transformable* Instance_getTransformable (const scene::Instance& instance)
00881 {
00882     return InstanceTypeCast<Transformable>::cast(instance);
00883 }
00884 
00885 inline ComponentSelectionTestable* Instance_getComponentSelectionTestable (scene::Instance& instance)
00886 {
00887     return InstanceTypeCast<ComponentSelectionTestable>::cast(instance);
00888 }
00889 
00890 inline ComponentEditable* Instance_getComponentEditable (scene::Instance& instance)
00891 {
00892     return InstanceTypeCast<ComponentEditable>::cast(instance);
00893 }
00894 
00895 inline ComponentSnappable* Instance_getComponentSnappable (scene::Instance& instance)
00896 {
00897     return InstanceTypeCast<ComponentSnappable>::cast(instance);
00898 }
00899 
00900 inline void Instance_setSelected (scene::Instance& instance, bool selected)
00901 {
00902     Selectable* selectable = Instance_getSelectable(instance);
00903     if (selectable != 0) {
00904         selectable->setSelected(selected);
00905     }
00906 }
00907 
00908 inline bool Instance_isSelected (scene::Instance& instance)
00909 {
00910     Selectable* selectable = Instance_getSelectable(instance);
00911     if (selectable != 0) {
00912         return selectable->isSelected();
00913     }
00914     return false;
00915 }
00916 
00917 inline scene::Instance& findInstance (const scene::Path& path)
00918 {
00919     scene::Instance* instance = GlobalSceneGraph().find(path);
00920     ASSERT_MESSAGE(instance != 0, "findInstance: path not found in scene-graph");
00921     return *instance;
00922 }
00923 
00924 inline void selectPath (const scene::Path& path, bool selected)
00925 {
00926     Instance_setSelected(findInstance(path), selected);
00927 }
00928 
00929 class SelectChildren: public scene::Traversable::Walker
00930 {
00931         mutable scene::Path m_path;
00932     public:
00933         SelectChildren (const scene::Path& root) :
00934             m_path(root)
00935         {
00936         }
00937         ~SelectChildren ()
00938         {
00939         }
00940         bool pre (scene::Node& node) const
00941         {
00942             m_path.push(makeReference(node));
00943             selectPath(m_path, true);
00944             return false;
00945         }
00946         void post (scene::Node& node) const
00947         {
00948             m_path.pop();
00949         }
00950 };
00951 
00952 inline void Entity_setSelected (scene::Instance& entity, bool selected)
00953 {
00954     scene::Node& node = entity.path().top();
00955     if (node_is_group(node)) {
00956         Node_getTraversable(node)->traverse(SelectChildren(entity.path()));
00957     } else {
00958         Instance_setSelected(entity, selected);
00959     }
00960 }
00961 
00962 inline bool Entity_isSelected (scene::Instance& entity)
00963 {
00964     if (node_is_group(entity.path().top())) {
00965         return entity.childSelected();
00966     }
00967     return Instance_isSelected(entity);
00968 }
00969 
00970 class InstanceCounter
00971 {
00972     public:
00973         unsigned int m_count;
00974         InstanceCounter () :
00975             m_count(0)
00976         {
00977         }
00978 };
00979 
00980 class Counter
00981 {
00982     public:
00983         virtual ~Counter ()
00984         {
00985         }
00986         virtual void increment () = 0;
00987         virtual void decrement () = 0;
00988 };
00989 
00990 #include "generic/callback.h"
00991 
00992 class SimpleCounter: public Counter
00993 {
00994         Callback m_countChanged;
00995         std::size_t m_count;
00996     public:
00997         void setCountChangedCallback (const Callback& countChanged)
00998         {
00999             m_countChanged = countChanged;
01000         }
01001         void increment ()
01002         {
01003             ++m_count;
01004             m_countChanged();
01005         }
01006         void decrement ()
01007         {
01008             --m_count;
01009             m_countChanged();
01010         }
01011         std::size_t get () const
01012         {
01013             return m_count;
01014         }
01015 };
01016 
01017 template<typename Contained>
01018 class ConstReference;
01019 typedef ConstReference<scene::Path> PathConstReference;
01020 
01021 #include "generic/referencecounted.h"
01022 typedef SmartReference<scene::Node, IncRefDecRefCounter<scene::Node> > NodeSmartReference;
01023 
01024 #endif

Generated by  doxygen 1.6.2