123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library 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
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSG_NODE
- #define OSG_NODE 1
- #include <osg/Object>
- #include <osg/StateSet>
- #include <osg/BoundingSphere>
- #include <osg/BoundingBox>
- #include <osg/Callback>
- #include <string>
- #include <vector>
- // forward declare osgTerrrain::Terrain to enable declaration of asTerrain() method.
- namespace osgTerrain {
- class Terrain;
- }
- namespace osg {
- // forcing declare classes to enable declaration of as*() methods.
- class NodeVisitor;
- class Drawable;
- class Geometry;
- class Group;
- class Transform;
- class Node;
- class Switch;
- class Geode;
- class Camera;
- /** A vector of Nodes pointers which is used to describe the path from a root node to a descendant.*/
- typedef std::vector< Node* > NodePath;
- /** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
- typedef std::vector< NodePath > NodePathList;
- /** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
- typedef std::vector< Matrix > MatrixList;
- /** META_Node macro define the standard clone, isSameKindAs, className
- * and accept methods. Use when subclassing from Node to make it
- * more convenient to define the required pure virtual methods.*/
- #define META_Node(library,name) \
- virtual osg::Object* cloneType() const { return new name (); } \
- virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \
- virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \
- virtual const char* className() const { return #name; } \
- virtual const char* libraryName() const { return #library; } \
- virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } } \
- /** Base class for all internal nodes in the scene graph.
- Provides interface for most common node operations (Composite Pattern).
- */
- class OSG_EXPORT Node : public Object
- {
- public:
- /** Construct a node.
- Initialize the parent list to empty, node name to "" and
- bounding sphere dirty flag to true.*/
- Node();
- /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
- Node(const Node&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
- /** clone an object of the same type as the node.*/
- virtual Object* cloneType() const { return new Node(); }
- /** return a clone of a node, with Object* return type.*/
- virtual Object* clone(const CopyOp& copyop) const { return new Node(*this,copyop); }
- /** return true if this and obj are of the same kind of object.*/
- virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Node*>(obj)!=NULL; }
- /** return the name of the node's library.*/
- virtual const char* libraryName() const { return "osg"; }
- /** return the name of the node's class type.*/
- virtual const char* className() const { return "Node"; }
- /** Convert 'this' into a Node pointer if Object is a Node, otherwise return 0.
- * Equivalent to dynamic_cast<Node*>(this).*/
- virtual Node* asNode() { return this; }
- /** convert 'const this' into a const Node pointer if Object is a Node, otherwise return 0.
- * Equivalent to dynamic_cast<const Node*>(this).*/
- virtual const Node* asNode() const { return this; }
- /** convert 'this' into a Drawable pointer if Node is a Drawable, otherwise return 0.
- * Equivalent to dynamic_cast<Group*>(this).*/
- virtual Drawable* asDrawable() { return 0; }
- /** convert 'const this' into a const Drawable pointer if Node is a Drawable, otherwise return 0.
- * Equivalent to dynamic_cast<const Group*>(this).*/
- virtual const Drawable* asDrawable() const { return 0; }
- /** convert 'this' into a Geometry pointer if Node is a Geometry, otherwise return 0.
- * Equivalent to dynamic_cast<Group*>(this).*/
- virtual Geometry* asGeometry() { return 0; }
- /** convert 'const this' into a const Geometry pointer if Node is a Geometry, otherwise return 0.
- * Equivalent to dynamic_cast<const Group*>(this).*/
- virtual const Geometry* asGeometry() const { return 0; }
- /** convert 'this' into a Group pointer if Node is a Group, otherwise return 0.
- * Equivalent to dynamic_cast<Group*>(this).*/
- virtual Group* asGroup() { return 0; }
- /** convert 'const this' into a const Group pointer if Node is a Group, otherwise return 0.
- * Equivalent to dynamic_cast<const Group*>(this).*/
- virtual const Group* asGroup() const { return 0; }
- /** Convert 'this' into a Transform pointer if Node is a Transform, otherwise return 0.
- * Equivalent to dynamic_cast<Transform*>(this).*/
- virtual Transform* asTransform() { return 0; }
- /** convert 'const this' into a const Transform pointer if Node is a Transform, otherwise return 0.
- * Equivalent to dynamic_cast<const Transform*>(this).*/
- virtual const Transform* asTransform() const { return 0; }
- /** Convert 'this' into a Switch pointer if Node is a Switch, otherwise return 0.
- * Equivalent to dynamic_cast<Switch*>(this).*/
- virtual Switch* asSwitch() { return 0; }
- /** convert 'const this' into a const Switch pointer if Node is a Switch, otherwise return 0.
- * Equivalent to dynamic_cast<const Switch*>(this).*/
- virtual const Switch* asSwitch() const { return 0; }
- /** Convert 'this' into a Geode pointer if Node is a Geode, otherwise return 0.
- * Equivalent to dynamic_cast<Geode*>(this).*/
- virtual Geode* asGeode() { return 0; }
- /** convert 'const this' into a const Geode pointer if Node is a Geode, otherwise return 0.
- * Equivalent to dynamic_cast<const Geode*>(this).*/
- virtual const Geode* asGeode() const { return 0; }
- /** Convert 'this' into a Transform pointer if Node is a Terrain, otherwise return 0.
- * Equivalent to dynamic_cast<Terrrain*>(this).*/
- virtual osgTerrain::Terrain* asTerrain() { return 0; }
- /** convert 'const this' into a const Terrain pointer if Node is a Terrain, otherwise return 0.
- * Equivalent to dynamic_cast<const Terrain*>(this).*/
- virtual const osgTerrain::Terrain* asTerrain() const { return 0; }
- /** Visitor Pattern : calls the apply method of a NodeVisitor with this node's type.*/
- virtual void accept(NodeVisitor& nv);
- /** Traverse upwards : calls parents' accept method with NodeVisitor.*/
- virtual void ascend(NodeVisitor& nv);
- /** Traverse downwards : calls children's accept method with NodeVisitor.*/
- virtual void traverse(NodeVisitor& /*nv*/) {}
- /** A vector of osg::Group pointers which is used to store the parent(s) of node.*/
- typedef std::vector<Group*> ParentList;
- /** Get the parent list of node. */
- inline const ParentList& getParents() const { return _parents; }
- /** Get the a copy of parent list of node. A copy is returned to
- * prevent modification of the parent list.*/
- inline ParentList getParents() { return _parents; }
- inline Group* getParent(unsigned int i) { return _parents[i]; }
- /**
- * Get a single const parent of node.
- * @param i index of the parent to get.
- * @return the parent i.
- */
- inline const Group* getParent(unsigned int i) const { return _parents[i]; }
- /**
- * Get the number of parents of node.
- * @return the number of parents of this node.
- */
- inline unsigned int getNumParents() const { return static_cast<unsigned int>(_parents.size()); }
- /** Get the list of node paths parent paths.
- * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specified node. */
- NodePathList getParentalNodePaths(osg::Node* haltTraversalAtNode=0) const;
- /** Get the list of matrices that transform this node from local coordinates to world coordinates.
- * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specified node. */
- MatrixList getWorldMatrices(const osg::Node* haltTraversalAtNode=0) const;
- /** Set update node callback, called during update traversal. */
- void setUpdateCallback(Callback* nc);
- template<class T> void setUpdateCallback(const ref_ptr<T>& nc) { setUpdateCallback(nc.get()); }
- /** Get update node callback, called during update traversal. */
- inline Callback* getUpdateCallback() { return _updateCallback.get(); }
- /** Get const update node callback, called during update traversal. */
- inline const Callback* getUpdateCallback() const { return _updateCallback.get(); }
- /** Convenience method that sets the update callback of the node if it doesn't exist, or nest it into the existing one. */
- inline void addUpdateCallback(Callback* nc) {
- if (nc != NULL) {
- if (_updateCallback.valid()) _updateCallback->addNestedCallback(nc);
- else setUpdateCallback(nc);
- }
- }
- template<class T> void addUpdateCallback(const ref_ptr<T>& nc) { addUpdateCallback(nc.get()); }
- /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
- inline void removeUpdateCallback(Callback* nc) {
- if (nc != NULL && _updateCallback.valid()) {
- if (_updateCallback == nc)
- {
- ref_ptr<osg::Callback> new_nested_callback = nc->getNestedCallback();
- nc->setNestedCallback(0);
- setUpdateCallback(new_nested_callback.get());
- }
- else _updateCallback->removeNestedCallback(nc);
- }
- }
- template<class T> void removeUpdateCallback(const ref_ptr<T>& nc) { removeUpdateCallback(nc.get()); }
- /** Get the number of Children of this node which require Update traversal,
- * since they have an Update Callback attached to them or their children.*/
- inline unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; }
- /** Set event node callback, called during event traversal. */
- void setEventCallback(Callback* nc);
- template<class T> void setEventCallback(const ref_ptr<T>& nc) { setEventCallback(nc.get()); }
- /** Get event node callback, called during event traversal. */
- inline Callback* getEventCallback() { return _eventCallback.get(); }
- /** Get const event node callback, called during event traversal. */
- inline const Callback* getEventCallback() const { return _eventCallback.get(); }
- /** Convenience method that sets the event callback of the node if it doesn't exist, or nest it into the existing one. */
- inline void addEventCallback(Callback* nc) {
- if (nc != NULL) {
- if (_eventCallback.valid()) _eventCallback->addNestedCallback(nc);
- else setEventCallback(nc);
- }
- }
- template<class T> void addEventCallback(const ref_ptr<T>& nc) { addEventCallback(nc.get()); }
- /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
- inline void removeEventCallback(Callback* nc) {
- if (nc != NULL && _eventCallback.valid()) {
- if (_eventCallback == nc)
- {
- ref_ptr<osg::Callback> new_nested_callback = nc->getNestedCallback();
- nc->setNestedCallback(0);
- setEventCallback(new_nested_callback.get()); // replace the callback by the nested one
- }
- else _eventCallback->removeNestedCallback(nc);
- }
- }
- template<class T> void removeEventCallback(const ref_ptr<T>& nc) { removeEventCallback(nc.get()); }
- /** Get the number of Children of this node which require Event traversal,
- * since they have an Event Callback attached to them or their children.*/
- inline unsigned int getNumChildrenRequiringEventTraversal() const { return _numChildrenRequiringEventTraversal; }
- /** Set cull node callback, called during cull traversal. */
- void setCullCallback(Callback* nc) { _cullCallback = nc; }
- template<class T> void setCullCallback(const ref_ptr<T>& nc) { setCullCallback(nc.get()); }
- /** Get cull node callback, called during cull traversal. */
- inline Callback* getCullCallback() { return _cullCallback.get(); }
- /** Get const cull node callback, called during cull traversal. */
- inline const Callback* getCullCallback() const { return _cullCallback.get(); }
- /** Convenience method that sets the cull callback of the node if it doesn't exist, or nest it into the existing one. */
- inline void addCullCallback(Callback* nc) {
- if (nc != NULL) {
- if (_cullCallback.valid()) _cullCallback->addNestedCallback(nc);
- else setCullCallback(nc);
- }
- }
- template<class T> void addCullCallback(const ref_ptr<T>& nc) { addCullCallback(nc.get()); }
- /** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
- inline void removeCullCallback(Callback* nc) {
- if (nc != NULL && _cullCallback.valid()) {
- if (_cullCallback == nc)
- {
- ref_ptr<osg::Callback> new_nested_callback = nc->getNestedCallback();
- nc->setNestedCallback(0);
- setCullCallback(new_nested_callback.get()); // replace the callback by the nested one
- }
- else _cullCallback->removeNestedCallback(nc);
- }
- }
- template<class T> void removeCullCallback(const ref_ptr<T>& nc) { removeCullCallback(nc.get()); }
- /** Set the view frustum/small feature culling of this node to be active or inactive.
- * The default value is true for _cullingActive. Used as a guide
- * to the cull traversal.*/
- void setCullingActive(bool active);
- /** Get the view frustum/small feature _cullingActive flag for this node. Used as a guide
- * to the cull traversal.*/
- inline bool getCullingActive() const { return _cullingActive; }
- /** Get the number of Children of this node which have culling disabled.*/
- inline unsigned int getNumChildrenWithCullingDisabled() const { return _numChildrenWithCullingDisabled; }
- /** Return true if this node can be culled by view frustum, occlusion or small feature culling during the cull traversal.
- * Note, returns true only if no children have culling disabled, and the local _cullingActive flag is true.*/
- inline bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && getBound().valid(); }
- /** Get the number of Children of this node which are or have OccluderNode's.*/
- inline unsigned int getNumChildrenWithOccluderNodes() const { return _numChildrenWithOccluderNodes; }
- /** return true if this node is an OccluderNode or the subgraph below this node are OccluderNodes.*/
- bool containsOccluderNodes() const;
- /**
- * This is a set of bits (flags) that represent the Node.
- * The default value is 0xffffffff (all bits set).
- *
- * The most common use of these is during traversal of the scene graph.
- * For instance, when traversing the scene graph the osg::NodeVisitor does a bitwise
- * AND of its TraversalMask with the Node's NodeMask to
- * determine if the Node should be processed/traversed.
- *
- * For example, if a Node has a NodeMask value of 0x02 (only 2nd bit set)
- * and the osg::Camera has a CullMask of 0x4 (2nd bit not set) then during cull traversal,
- * which takes it's TraversalMask from the Camera's CullMask, the node and any children
- * would be ignored and thereby treated as "culled" and thus not rendered.
- * Conversely, if the osg::Camera CullMask were 0x3 (2nd bit set) then the node
- * would be processed and child Nodes would be examined.
- */
- typedef unsigned int NodeMask;
- /** Set the node mask.*/
- inline void setNodeMask(NodeMask nm) { _nodeMask = nm; }
- /** Get the node Mask.*/
- inline NodeMask getNodeMask() const { return _nodeMask; }
- /** Set the node's StateSet.*/
- void setStateSet(osg::StateSet* stateset);
- template<class T> void setStateSet(const osg::ref_ptr<T>& stateset) { setStateSet(stateset.get()); }
- /** return the node's StateSet, if one does not already exist create it
- * set the node and return the newly created StateSet. This ensures
- * that a valid StateSet is always returned and can be used directly.*/
- osg::StateSet* getOrCreateStateSet();
- /** Return the node's StateSet. returns NULL if a stateset is not attached.*/
- inline osg::StateSet* getStateSet() { return _stateset.get(); }
- /** Return the node's const StateSet. Returns NULL if a stateset is not attached.*/
- inline const osg::StateSet* getStateSet() const { return _stateset.get(); }
- /** A vector of std::string's which are used to describe the object.*/
- typedef std::vector<std::string> DescriptionList;
- /** Set the list of string descriptions.*/
- void setDescriptions(const DescriptionList& descriptions);
- /** Get the description list of the node.*/
- DescriptionList& getDescriptions();
- /** Get the const description list of the const node.*/
- const DescriptionList& getDescriptions() const;
- /** Get a single const description of the const node.*/
- const std::string& getDescription(unsigned int i) const;
- /** Get a single description of the node.*/
- std::string& getDescription(unsigned int i);
- /** Get the number of descriptions of the node.*/
- unsigned int getNumDescriptions() const;
- /** Add a description string to the node.*/
- void addDescription(const std::string& desc);
- /** Set the initial bounding volume to use when computing the overall bounding volume.*/
- void setInitialBound(const osg::BoundingSphere& bsphere) { _initialBound = bsphere; dirtyBound(); }
- /** Set the initial bounding volume to use when computing the overall bounding volume.*/
- const BoundingSphere& getInitialBound() const { return _initialBound; }
- /** Mark this node's bounding sphere dirty.
- Forcing it to be computed on the next call to getBound().*/
- void dirtyBound();
- inline const BoundingSphere& getBound() const
- {
- if(!_boundingSphereComputed)
- {
- _boundingSphere = _initialBound;
- if (_computeBoundCallback.valid())
- _boundingSphere.expandBy(_computeBoundCallback->computeBound(*this));
- else
- _boundingSphere.expandBy(computeBound());
- _boundingSphereComputed = true;
- }
- return _boundingSphere;
- }
- /** Compute the bounding sphere around Node's geometry or children.
- This method is automatically called by getBound() when the bounding
- sphere has been marked dirty via dirtyBound().*/
- virtual BoundingSphere computeBound() const;
- /** Callback to allow users to override the default computation of bounding volume.*/
- struct ComputeBoundingSphereCallback : public osg::Object
- {
- ComputeBoundingSphereCallback() {}
- ComputeBoundingSphereCallback(const ComputeBoundingSphereCallback& org,const CopyOp& copyop):
- Object(org, copyop) {}
- META_Object(osg,ComputeBoundingSphereCallback);
- virtual BoundingSphere computeBound(const osg::Node&) const { return BoundingSphere(); }
- };
- /** Set the compute bound callback to override the default computeBound.*/
- void setComputeBoundingSphereCallback(ComputeBoundingSphereCallback* callback) { _computeBoundCallback = callback; }
- template<class T> void setComputeBoundingSphereCallback(const ref_ptr<T>& callback) { setComputeBoundingSphereCallback(callback.get()); }
- /** Get the compute bound callback.*/
- ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() { return _computeBoundCallback.get(); }
- /** Get the const compute bound callback.*/
- const ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() const { return _computeBoundCallback.get(); }
- /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
- virtual void setThreadSafeRefUnref(bool threadSafe);
- /** Resize any per context GLObject buffers to specified size. */
- virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/);
- /** If State is non-zero, this function releases any associated OpenGL objects for
- * the specified graphics context. Otherwise, releases OpenGL objects
- * for all graphics contexts. */
- virtual void releaseGLObjects(osg::State* = 0) const;
- protected:
- /** Node destructor. Note, is protected so that Nodes cannot
- be deleted other than by being dereferenced and the reference
- count being zero (see osg::Referenced), preventing the deletion
- of nodes which are still in use. This also means that
- Nodes cannot be created on stack i.e Node node will not compile,
- forcing all nodes to be created on the heap i.e Node* node
- = new Node().*/
- virtual ~Node();
- BoundingSphere _initialBound;
- ref_ptr<ComputeBoundingSphereCallback> _computeBoundCallback;
- mutable BoundingSphere _boundingSphere;
- mutable bool _boundingSphereComputed;
- void addParent(osg::Group* parent);
- void removeParent(osg::Group* parent);
- ParentList _parents;
- friend class osg::Group;
- friend class osg::Drawable;
- friend class osg::StateSet;
- ref_ptr<Callback> _updateCallback;
- unsigned int _numChildrenRequiringUpdateTraversal;
- void setNumChildrenRequiringUpdateTraversal(unsigned int num);
- ref_ptr<Callback> _eventCallback;
- unsigned int _numChildrenRequiringEventTraversal;
- void setNumChildrenRequiringEventTraversal(unsigned int num);
- ref_ptr<Callback> _cullCallback;
- bool _cullingActive;
- unsigned int _numChildrenWithCullingDisabled;
- void setNumChildrenWithCullingDisabled(unsigned int num);
- unsigned int _numChildrenWithOccluderNodes;
- void setNumChildrenWithOccluderNodes(unsigned int num);
- NodeMask _nodeMask;
- ref_ptr<StateSet> _stateset;
- };
- }
- #endif
|