00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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