root/OpenSceneGraph/trunk/include/osg/Node @ 13041

Revision 13041, 21.3 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14
15#ifndef OSG_NODE
16#define OSG_NODE 1
17
18#include <osg/Object>
19#include <osg/StateSet>
20#include <osg/BoundingSphere>
21#include <osg/NodeCallback>
22
23#include <string>
24#include <vector>
25
26
27// forward declare osgTerrrain::Terrain to enable declaration of asTerrain() method.
28namespace osgTerrain {
29class Terrain;
30}
31
32namespace osg {
33
34// forcing declare classes to enable declaration of as*() methods.
35class NodeVisitor;
36class Group;
37class Transform;
38class Node;
39class Switch;
40class Geode;
41class Camera;
42
43/** A vector of Nodes pointers which is used to describe the path from a root node to a descendant.*/
44typedef std::vector< Node* > NodePath;
45
46/** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
47typedef std::vector< NodePath > NodePathList;
48
49/** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
50typedef std::vector< Matrix > MatrixList;
51
52/** META_Node macro define the standard clone, isSameKindAs, className
53  * and accept methods.  Use when subclassing from Node to make it
54  * more convenient to define the required pure virtual methods.*/
55#define META_Node(library,name) \
56        virtual osg::Object* cloneType() const { return new name (); } \
57        virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \
58        virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \
59        virtual const char* className() const { return #name; } \
60        virtual const char* libraryName() const { return #library; } \
61        virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } } \
62
63
64/** Base class for all internal nodes in the scene graph.
65    Provides interface for most common node operations (Composite Pattern).
66*/
67class OSG_EXPORT Node : public Object
68{
69    public:
70
71        /** Construct a node.
72            Initialize the parent list to empty, node name to "" and
73            bounding sphere dirty flag to true.*/
74        Node();
75
76        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
77        Node(const Node&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
78
79        /** clone an object of the same type as the node.*/
80        virtual Object* cloneType() const { return new Node(); }
81
82        /** return a clone of a node, with Object* return type.*/
83        virtual Object* clone(const CopyOp& copyop) const { return new Node(*this,copyop); }
84
85        /** return true if this and obj are of the same kind of object.*/
86        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Node*>(obj)!=NULL; }
87
88        /** return the name of the node's library.*/
89        virtual const char* libraryName() const { return "osg"; }
90
91        /** return the name of the node's class type.*/
92        virtual const char* className() const { return "Node"; }
93
94        /** convert 'this' into a Group pointer if Node is a Group, otherwise return 0.
95          * Equivalent to dynamic_cast<Group*>(this).*/
96        virtual Group* asGroup() { return 0; }
97        /** convert 'const this' into a const Group pointer if Node is a Group, otherwise return 0.
98          * Equivalent to dynamic_cast<const Group*>(this).*/
99        virtual const Group* asGroup() const { return 0; }
100
101        /** Convert 'this' into a Transform pointer if Node is a Transform, otherwise return 0.
102          * Equivalent to dynamic_cast<Transform*>(this).*/
103        virtual Transform* asTransform() { return 0; }
104
105        /** convert 'const this' into a const Transform pointer if Node is a Transform, otherwise return 0.
106          * Equivalent to dynamic_cast<const Transform*>(this).*/
107        virtual const Transform* asTransform() const { return 0; }
108
109
110        /** Convert 'this' into a Camera pointer if Node is a Camera, otherwise return 0.
111          * Equivalent to dynamic_cast<Camera*>(this).*/
112        virtual Camera* asCamera() { return 0; }
113        /** convert 'const this' into a const Camera pointer if Node is a Camera, otherwise return 0.
114          * Equivalent to dynamic_cast<const Camera*>(this).*/
115        virtual const Camera* asCamera() const { return 0; }
116
117
118        /** Convert 'this' into a Switch pointer if Node is a Switch, otherwise return 0.
119          * Equivalent to dynamic_cast<Switch*>(this).*/
120        virtual Switch* asSwitch() { return 0; }
121
122        /** convert 'const this' into a const Switch pointer if Node is a Switch, otherwise return 0.
123          * Equivalent to dynamic_cast<const Switch*>(this).*/
124        virtual const Switch* asSwitch() const { return 0; }
125
126        /** Convert 'this' into a Geode pointer if Node is a Geode, otherwise return 0.
127          * Equivalent to dynamic_cast<Geode*>(this).*/
128        virtual Geode* asGeode() { return 0; }
129
130        /** convert 'const this' into a const Geode pointer if Node is a Geode, otherwise return 0.
131          * Equivalent to dynamic_cast<const Geode*>(this).*/
132        virtual const Geode* asGeode() const { return 0; }
133
134        /** Convert 'this' into a Transform pointer if Node is a Terrain, otherwise return 0.
135          * Equivalent to dynamic_cast<Terrrain*>(this).*/
136        virtual osgTerrain::Terrain* asTerrain() { return 0; }
137
138        /** convert 'const this' into a const Terrain pointer if Node is a Terrain, otherwise return 0.
139          * Equivalent to dynamic_cast<const Terrain*>(this).*/
140        virtual const osgTerrain::Terrain* asTerrain() const { return 0; }
141
142
143        /** Visitor Pattern : calls the apply method of a NodeVisitor with this node's type.*/
144        virtual void accept(NodeVisitor& nv);
145        /** Traverse upwards : calls parents' accept method with NodeVisitor.*/
146        virtual void ascend(NodeVisitor& nv);
147        /** Traverse downwards : calls children's accept method with NodeVisitor.*/
148        virtual void traverse(NodeVisitor& /*nv*/) {}
149
150        /** A vector of osg::Group pointers which is used to store the parent(s) of node.*/
151        typedef std::vector<Group*> ParentList;
152
153        /** Get the parent list of node. */
154        inline const ParentList& getParents() const { return _parents; }
155
156        /** Get the a copy of parent list of node. A copy is returned to
157          * prevent modification of the parent list.*/
158        inline ParentList getParents() { return _parents; }
159
160        inline Group* getParent(unsigned int i)  { return _parents[i]; }
161
162        /**
163         * Get a single const parent of node.
164         * @param i index of the parent to get.
165         * @return the parent i.
166         */
167        inline const Group* getParent(unsigned int i) const  { return _parents[i]; }
168
169        /**
170         * Get the number of parents of node.
171         * @return the number of parents of this node.
172         */
173        inline unsigned int getNumParents() const { return static_cast<unsigned int>(_parents.size()); }
174
175        /** Get the list of node paths parent paths.
176          * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */
177        NodePathList getParentalNodePaths(osg::Node* haltTraversalAtNode=0) const;
178
179        /** Get the list of matrices that transform this node from local coordinates to world coordinates.
180          * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */
181        MatrixList getWorldMatrices(const osg::Node* haltTraversalAtNode=0) const;
182
183
184        /** Set update node callback, called during update traversal. */
185        void setUpdateCallback(NodeCallback* nc);
186
187        /** Get update node callback, called during update traversal. */
188        inline NodeCallback* getUpdateCallback() { return _updateCallback.get(); }
189
190        /** Get const update node callback, called during update traversal. */
191        inline const NodeCallback* getUpdateCallback() const { return _updateCallback.get(); }
192
193        /** Convenience method that sets the update callback of the node if it doesn't exist, or nest it into the existing one. */
194        inline void addUpdateCallback(NodeCallback* nc) {
195            if (nc != NULL) {
196                if (_updateCallback.valid()) _updateCallback->addNestedCallback(nc);
197                else setUpdateCallback(nc);
198            }
199        }
200
201        /** 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. */
202        inline void removeUpdateCallback(NodeCallback* nc) {
203            if (nc != NULL && _updateCallback.valid()) {
204                if (_updateCallback == nc) setUpdateCallback(nc->getNestedCallback());        // replace the callback by the nested one
205                else _updateCallback->removeNestedCallback(nc);
206            }
207        }
208
209        /** Get the number of Children of this node which require Update traversal,
210          * since they have an Update Callback attached to them or their children.*/
211        inline unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; }
212
213
214        /** Set event node callback, called during event traversal. */
215        void setEventCallback(NodeCallback* nc);
216
217        /** Get event node callback, called during event traversal. */
218        inline NodeCallback* getEventCallback() { return _eventCallback.get(); }
219
220        /** Get const event node callback, called during event traversal. */
221        inline const NodeCallback* getEventCallback() const { return _eventCallback.get(); }
222
223        /** Convenience method that sets the event callback of the node if it doesn't exist, or nest it into the existing one. */
224        inline void addEventCallback(NodeCallback* nc) {
225            if (nc != NULL) {
226                if (_eventCallback.valid()) _eventCallback->addNestedCallback(nc);
227                else setEventCallback(nc);
228            }
229        }
230
231        /** 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. */
232        inline void removeEventCallback(NodeCallback* nc) {
233            if (nc != NULL && _eventCallback.valid()) {
234                if (_eventCallback == nc) setEventCallback(nc->getNestedCallback());        // replace the callback by the nested one
235                else _eventCallback->removeNestedCallback(nc);
236            }
237        }
238
239        /** Get the number of Children of this node which require Event traversal,
240          * since they have an Event Callback attached to them or their children.*/
241        inline unsigned int getNumChildrenRequiringEventTraversal() const { return _numChildrenRequiringEventTraversal; }
242
243
244        /** Set cull node callback, called during cull traversal. */
245        void setCullCallback(NodeCallback* nc) { _cullCallback = nc; }
246
247        /** Get cull node callback, called during cull traversal. */
248        inline NodeCallback* getCullCallback() { return _cullCallback.get(); }
249
250        /** Get const cull node callback, called during cull traversal. */
251        inline const NodeCallback* getCullCallback() const { return _cullCallback.get(); }
252
253        /** Convenience method that sets the cull callback of the node if it doesn't exist, or nest it into the existing one. */
254        inline void addCullCallback(NodeCallback* nc) {
255            if (nc != NULL) {
256                if (_cullCallback.valid()) _cullCallback->addNestedCallback(nc);
257                else setCullCallback(nc);
258            }
259        }
260
261        /** 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. */
262        inline void removeCullCallback(NodeCallback* nc) {
263            if (nc != NULL && _cullCallback.valid()) {
264                if (_cullCallback == nc) setCullCallback(nc->getNestedCallback());        // replace the callback by the nested one
265                else _cullCallback->removeNestedCallback(nc);
266            }
267        }
268
269        /** Set the view frustum/small feature culling of this node to be active or inactive.
270          * The default value is true for _cullingActive. Used as a guide
271          * to the cull traversal.*/
272        void setCullingActive(bool active);
273
274        /** Get the view frustum/small feature _cullingActive flag for this node. Used as a guide
275          * to the cull traversal.*/
276        inline bool getCullingActive() const { return _cullingActive; }
277
278        /** Get the number of Children of this node which have culling disabled.*/
279        inline unsigned int getNumChildrenWithCullingDisabled() const { return _numChildrenWithCullingDisabled; }
280
281        /** Return true if this node can be culled by view frustum, occlusion or small feature culling during the cull traversal.
282          * Note, returns true only if no children have culling disabled, and the local _cullingActive flag is true.*/
283        inline bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && getBound().valid(); }
284
285        /** Get the number of Children of this node which are or have OccluderNode's.*/
286        inline unsigned int getNumChildrenWithOccluderNodes() const { return _numChildrenWithOccluderNodes; }
287
288
289        /** return true if this node is an OccluderNode or the subgraph below this node are OccluderNodes.*/
290        bool containsOccluderNodes() const;
291
292
293        /**
294        * This is a set of bits (flags) that represent the Node.
295        * The default value is 0xffffffff (all bits set).
296        *
297        * The most common use of these is during traversal of the scene graph.
298        * For instance, when traversing the scene graph the osg::NodeVisitor does a bitwise
299        * AND of its TraversalMask with the Node's NodeMask to
300        * determine if the Node should be processed/traversed.
301        *
302        * For example, if a Node has a NodeMask value of 0x02 (only 2nd bit set)
303        * and the osg::Camera has a CullMask of 0x4 (2nd bit not set) then during cull traversal,
304        * which takes it's TraversalMask from the Camera's CullMask, the node and any children
305        * would be ignored and thereby treated as "culled" and thus not rendered.
306        * Conversely, if the osg::Camera CullMask were 0x3 (2nd bit set) then the node
307        * would be processed and child Nodes would be examined.
308        */
309        typedef unsigned int NodeMask;
310        /** Set the node mask.*/
311        inline void setNodeMask(NodeMask nm) { _nodeMask = nm; }
312        /** Get the node Mask.*/
313        inline NodeMask getNodeMask() const { return _nodeMask; }
314
315
316
317        /** Set the node's StateSet.*/
318        void setStateSet(osg::StateSet* stateset);
319
320        /** return the node's StateSet, if one does not already exist create it
321          * set the node and return the newly created StateSet. This ensures
322          * that a valid StateSet is always returned and can be used directly.*/
323        osg::StateSet* getOrCreateStateSet();
324
325        /** Return the node's StateSet. returns NULL if a stateset is not attached.*/
326        inline osg::StateSet* getStateSet() { return _stateset.get(); }
327
328        /** Return the node's const StateSet. Returns NULL if a stateset is not attached.*/
329        inline const osg::StateSet* getStateSet() const { return _stateset.get(); }
330
331
332        /** A vector of std::string's which are used to describe the object.*/
333        typedef std::vector<std::string> DescriptionList;
334
335        /** Set the list of string descriptions.*/
336        void setDescriptions(const DescriptionList& descriptions);
337
338        /** Get the description list of the node.*/
339        DescriptionList& getDescriptions();
340
341        /** Get the const description list of the const node.*/
342        const DescriptionList& getDescriptions() const;
343
344
345        /** Get a single const description of the const node.*/
346        const std::string& getDescription(unsigned int i) const;
347
348        /** Get a single description of the node.*/
349        std::string& getDescription(unsigned int i);
350
351        /** Get the number of descriptions of the node.*/
352        unsigned int getNumDescriptions() const;
353
354        /** Add a description string to the node.*/
355        void addDescription(const std::string& desc);
356
357
358        /** Set the initial bounding volume to use when computing the overall bounding volume.*/
359        void setInitialBound(const osg::BoundingSphere& bsphere) { _initialBound = bsphere; dirtyBound(); }
360
361        /** Set the initial bounding volume to use when computing the overall bounding volume.*/
362        const BoundingSphere& getInitialBound() const { return _initialBound; }
363
364        /** Mark this node's bounding sphere dirty.
365            Forcing it to be computed on the next call to getBound().*/
366        void dirtyBound();
367
368        /** Get the bounding sphere of node.
369           Using lazy evaluation computes the bounding sphere if it is 'dirty'.*/
370        inline const BoundingSphere& getBound() const
371        {
372            if(!_boundingSphereComputed)
373            {
374                _boundingSphere = _initialBound;
375                if (_computeBoundCallback.valid())
376                    _boundingSphere.expandBy(_computeBoundCallback->computeBound(*this));
377                else
378                    _boundingSphere.expandBy(computeBound());
379
380                _boundingSphereComputed = true;
381            }
382            return _boundingSphere;
383        }
384
385
386        /** Compute the bounding sphere around Node's geometry or children.
387            This method is automatically called by getBound() when the bounding
388            sphere has been marked dirty via dirtyBound().*/
389        virtual BoundingSphere computeBound() const;
390
391        /** Callback to allow users to override the default computation of bounding volume.*/
392        struct ComputeBoundingSphereCallback : public osg::Object
393        {
394            ComputeBoundingSphereCallback() {}
395
396            ComputeBoundingSphereCallback(const ComputeBoundingSphereCallback&,const CopyOp&) {}
397
398            META_Object(osg,ComputeBoundingSphereCallback);
399
400           virtual BoundingSphere computeBound(const osg::Node&) const { return BoundingSphere(); }
401        };
402
403        /** Set the compute bound callback to override the default computeBound.*/
404        void setComputeBoundingSphereCallback(ComputeBoundingSphereCallback* callback) { _computeBoundCallback = callback; }
405
406        /** Get the compute bound callback.*/
407        ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() { return _computeBoundCallback.get(); }
408
409        /** Get the const compute bound callback.*/
410        const ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() const { return _computeBoundCallback.get(); }
411
412        /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
413        virtual void setThreadSafeRefUnref(bool threadSafe);
414
415        /** Resize any per context GLObject buffers to specified size. */
416        virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/);
417
418        /** If State is non-zero, this function releases any associated OpenGL objects for
419           * the specified graphics context. Otherwise, releases OpenGL objects
420           * for all graphics contexts. */
421        virtual void releaseGLObjects(osg::State* = 0) const;
422
423
424    protected:
425
426        /** Node destructor. Note, is protected so that Nodes cannot
427            be deleted other than by being dereferenced and the reference
428            count being zero (see osg::Referenced), preventing the deletion
429            of nodes which are still in use. This also means that
430            Nodes cannot be created on stack i.e Node node will not compile,
431            forcing all nodes to be created on the heap i.e Node* node
432            = new Node().*/
433        virtual ~Node();
434
435
436
437        BoundingSphere                          _initialBound;
438        ref_ptr<ComputeBoundingSphereCallback>  _computeBoundCallback;
439        mutable BoundingSphere                  _boundingSphere;
440        mutable bool                            _boundingSphereComputed;
441
442        void addParent(osg::Group* node);
443        void removeParent(osg::Group* node);
444
445        ParentList _parents;
446        friend class osg::Group;
447        friend class osg::Drawable;
448        friend class osg::StateSet;
449
450        ref_ptr<NodeCallback> _updateCallback;
451        unsigned int _numChildrenRequiringUpdateTraversal;
452        void setNumChildrenRequiringUpdateTraversal(unsigned int num);
453
454        ref_ptr<NodeCallback> _eventCallback;
455        unsigned int _numChildrenRequiringEventTraversal;
456        void setNumChildrenRequiringEventTraversal(unsigned int num);
457
458        ref_ptr<NodeCallback> _cullCallback;
459
460        bool _cullingActive;
461        unsigned int _numChildrenWithCullingDisabled;
462        void setNumChildrenWithCullingDisabled(unsigned int num);
463
464        unsigned int _numChildrenWithOccluderNodes;
465        void setNumChildrenWithOccluderNodes(unsigned int num);
466
467        NodeMask _nodeMask;
468
469        ref_ptr<StateSet> _stateset;
470
471};
472
473}
474
475#endif
Note: See TracBrowser for help on using the browser.