root/OpenSceneGraph/trunk/include/osg/NodeVisitor @ 13191

Revision 13191, 15.5 kB (checked in by robert, 11 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • 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#ifndef OSG_NODEVISITOR
15#define OSG_NODEVISITOR 1
16
17#include <osg/Node>
18#include <osg/Matrix>
19#include <osg/FrameStamp>
20
21namespace osg {
22
23class Billboard;
24class ClearNode;
25class ClipNode;
26class CoordinateSystemNode;
27class Geode;
28class Group;
29class LightSource;
30class LOD;
31class MatrixTransform;
32class OccluderNode;
33class OcclusionQueryNode;
34class PagedLOD;
35class PositionAttitudeTransform;
36class Projection;
37class ProxyNode;
38class Sequence;
39class Switch;
40class TexGenNode;
41class Transform;
42class Camera;
43class CameraView;
44
45const unsigned int UNINITIALIZED_FRAME_NUMBER=0xffffffff;
46
47#define META_NodeVisitor(library,name) \
48        virtual const char* libraryName() const { return #library; }\
49        virtual const char* className() const { return #name; }
50
51/** Visitor for type safe operations on osg::Nodes.
52    Based on GOF's Visitor pattern. The NodeVisitor
53    is useful for developing type safe operations to nodes
54    in the scene graph (as per Visitor pattern), and adds to this
55    support for optional scene graph traversal to allow
56    operations to be applied to whole scenes at once. The Visitor
57    pattern uses a technique of double dispatch as a mechanism to
58    call the appropriate apply(..) method of the NodeVisitor.  To
59    use this feature one must use the Node::accept(NodeVisitor) which
60    is extended in each Node subclass, rather than the NodeVisitor
61    apply directly.  So use root->accept(myVisitor); instead of
62    myVisitor.apply(*root).  The later method will bypass the double
63    dispatch and the appropriate NodeVisitor::apply(..) method will
64    not be called. */
65class OSG_EXPORT NodeVisitor : public virtual Referenced
66{
67    public:
68
69        enum TraversalMode
70        {
71            TRAVERSE_NONE,
72            TRAVERSE_PARENTS,
73            TRAVERSE_ALL_CHILDREN,
74            TRAVERSE_ACTIVE_CHILDREN
75        };
76
77        enum VisitorType
78        {
79            NODE_VISITOR = 0,
80            UPDATE_VISITOR,
81            EVENT_VISITOR,
82            COLLECT_OCCLUDER_VISITOR,
83            CULL_VISITOR
84        };
85
86        NodeVisitor(TraversalMode tm=TRAVERSE_NONE);
87
88        NodeVisitor(VisitorType type,TraversalMode tm=TRAVERSE_NONE);
89
90        virtual ~NodeVisitor();
91
92        /** return the library name/namespapce of the visitor's. Should be defined by derived classes.*/
93        virtual const char* libraryName() const { return "osg"; }
94
95        /** return the name of the visitor's class type. Should be defined by derived classes.*/
96        virtual const char* className() const { return "NodeVisitor"; }
97
98        /** Method to call to reset visitor. Useful if your visitor accumulates
99            state during a traversal, and you plan to reuse the visitor.
100            To flush that state for the next traversal: call reset() prior
101            to each traversal.*/
102        virtual void reset() {}
103
104
105        /** Set the VisitorType, used to distinguish different visitors during
106          * traversal of the scene, typically used in the Node::traverse() method
107          * to select which behaviour to use for different types of traversal/visitors.*/
108        inline void setVisitorType(VisitorType type) { _visitorType = type; }
109
110        /** Get the VisitorType.*/
111        inline VisitorType getVisitorType() const { return _visitorType; }
112
113        /** Set the traversal number. Typically used to denote the frame count.*/
114        inline void setTraversalNumber(unsigned int fn) { _traversalNumber = fn; }
115
116        /** Get the traversal number. Typically used to denote the frame count.*/
117        inline unsigned int getTraversalNumber() const { return _traversalNumber; }
118
119        /** Set the FrameStamp that this traversal is associated with.*/
120        inline void setFrameStamp(FrameStamp* fs) { _frameStamp = fs; }
121
122        /** Get the FrameStamp that this traversal is associated with.*/
123        inline const FrameStamp* getFrameStamp() const { return _frameStamp.get(); }
124
125
126        /** Set the TraversalMask of this NodeVisitor.
127          * The TraversalMask is used by the NodeVisitor::validNodeMask() method
128          * to determine whether to operate on a node and its subgraph.
129          * validNodeMask() is called automatically in the Node::accept() method before
130          * any call to NodeVisitor::apply(), apply() is only ever called if validNodeMask
131          * returns true. Note, if NodeVisitor::_traversalMask is 0 then all operations
132          * will be switched off for all nodes.  Whereas setting both _traversalMask and
133          * _nodeMaskOverride to 0xffffffff will allow a visitor to work on all nodes
134          * regardless of their own Node::_nodeMask state.*/
135        inline void setTraversalMask(Node::NodeMask mask) { _traversalMask = mask; }
136
137        /** Get the TraversalMask.*/
138        inline Node::NodeMask getTraversalMask() const { return _traversalMask; }
139
140        /** Set the NodeMaskOverride mask.
141          * Used in validNodeMask() to determine whether to operate on a node or its
142          * subgraph, by OR'ing NodeVisitor::_nodeMaskOverride with the Node's own Node::_nodeMask.
143          * Typically used to force on nodes which may have
144          * been switched off by their own Node::_nodeMask.*/
145        inline void setNodeMaskOverride(Node::NodeMask mask) { _nodeMaskOverride = mask; }
146
147        /** Get the NodeMaskOverride mask.*/
148        inline Node::NodeMask getNodeMaskOverride() const { return _nodeMaskOverride; }
149
150        /** Method to called by Node and its subclass' Node::accept() method, if the result is true
151          * it is used to cull operations of nodes and their subgraphs.
152          * Return true if the result of a bit wise and of the NodeVisitor::_traversalMask
153          * with the bit or between NodeVistor::_nodeMaskOverride and the Node::_nodeMask.
154          * default values for _traversalMask is 0xffffffff, _nodeMaskOverride is 0x0,
155          * and osg::Node::_nodeMask is 0xffffffff. */
156        inline bool validNodeMask(const osg::Node& node) const
157        {
158            return (getTraversalMask() & (getNodeMaskOverride() | node.getNodeMask()))!=0;
159        }
160
161        /** Set the traversal mode for Node::traverse() to use when
162            deciding which children of a node to traverse. If a
163            NodeVisitor has been attached via setTraverseVisitor()
164            and the new mode is not TRAVERSE_VISITOR then the attached
165            visitor is detached. Default mode is TRAVERSE_NONE.*/
166        inline void setTraversalMode(TraversalMode mode) { _traversalMode = mode; }
167
168        /** Get the traversal mode.*/
169        inline TraversalMode getTraversalMode() const { return _traversalMode; }
170
171        /**
172         * Set user data, data must be subclassed from Referenced to allow
173         * automatic memory handling.  If your own data isn't directly
174         * subclassed from Referenced then create an adapter object
175         * which points to your own objects and handles the memory addressing.
176         */
177        inline void setUserData(Referenced* obj) { _userData = obj; }
178
179        /** Get user data.*/
180        inline Referenced* getUserData() { return _userData.get(); }
181
182        /** Get const user data.*/
183        inline const Referenced* getUserData() const { return _userData.get(); }
184
185
186        /** Method for handling traversal of a nodes.
187            If you intend to use the visitor for actively traversing
188            the scene graph then make sure the accept() methods call
189            this method unless they handle traversal directly.*/
190        inline void traverse(Node& node)
191        {
192            if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);
193            else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);
194        }
195
196        /** Method called by osg::Node::accept() method before
197          * a call to the NodeVisitor::apply(..).  The back of the list will,
198          * therefore, be the current node being visited inside the apply(..),
199          * and the rest of the list will be the parental sequence of nodes
200          * from the top most node applied down the graph to the current node.
201          * Note, the user does not typically call pushNodeOnPath() as it
202          * will be called automatically by the Node::accept() method.*/
203        inline void pushOntoNodePath(Node* node) { if (_traversalMode!=TRAVERSE_PARENTS) _nodePath.push_back(node); else _nodePath.insert(_nodePath.begin(),node); }
204
205        /** Method called by osg::Node::accept() method after
206          * a call to NodeVisitor::apply(..).
207          * Note, the user does not typically call popFromNodePath() as it
208          * will be called automatically by the Node::accept() method.*/
209        inline void popFromNodePath()            { if (_traversalMode!=TRAVERSE_PARENTS) _nodePath.pop_back(); else _nodePath.erase(_nodePath.begin()); }
210
211        /** Get the non const NodePath from the top most node applied down
212          * to the current Node being visited.*/
213        NodePath& getNodePath() { return _nodePath; }
214
215        /** Get the const NodePath from the top most node applied down
216          * to the current Node being visited.*/
217        const NodePath& getNodePath() const { return _nodePath; }
218
219        /** Get the eye point in local coordinates.
220          * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.*/
221        virtual osg::Vec3 getEyePoint() const { return Vec3(0.0f,0.0f,0.0f); }
222
223        /** Get the view point in local coordinates.
224          * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.*/
225        virtual osg::Vec3 getViewPoint() const { return getEyePoint(); }
226
227        /** Get the distance from a point to the eye point, distance value in local coordinate system.
228          * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.
229          * If the getDistanceFromEyePoint(pos) is not implemented then a default value of 0.0 is returned.*/
230        virtual float getDistanceToEyePoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
231
232        /** Get the distance of a point from the eye point, distance value in the eye coordinate system.
233          * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.
234          * If the getDistanceFromEyePoint(pos) is not implemented than a default value of 0.0 is returned.*/
235        virtual float getDistanceFromEyePoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
236
237        /** Get the distance from a point to the view point, distance value in local coordinate system.
238          * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.
239          * If the getDistanceToViewPoint(pos) is not implemented then a default value of 0.0 is returned.*/
240        virtual float getDistanceToViewPoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
241
242
243        virtual void apply(Node& node);
244
245        virtual void apply(Geode& node);
246        virtual void apply(Billboard& node);
247
248        virtual void apply(Group& node);
249
250        virtual void apply(ProxyNode& node);
251
252        virtual void apply(Projection& node);
253
254        virtual void apply(CoordinateSystemNode& node);
255
256        virtual void apply(ClipNode& node);
257        virtual void apply(TexGenNode& node);
258        virtual void apply(LightSource& node);
259
260        virtual void apply(Transform& node);
261        virtual void apply(Camera& node);
262        virtual void apply(CameraView& node);
263        virtual void apply(MatrixTransform& node);
264        virtual void apply(PositionAttitudeTransform& node);
265
266        virtual void apply(Switch& node);
267        virtual void apply(Sequence& node);
268        virtual void apply(LOD& node);
269        virtual void apply(PagedLOD& node);
270        virtual void apply(ClearNode& node);
271        virtual void apply(OccluderNode& node);
272        virtual void apply(OcclusionQueryNode& node);
273
274
275        /** Callback for managing database paging, such as generated by PagedLOD nodes.*/
276        class DatabaseRequestHandler : public osg::Referenced
277        {
278        public:
279
280            DatabaseRequestHandler():
281                Referenced(true) {}
282
283             virtual void requestNodeFile(const std::string& fileName, osg::NodePath& nodePath, float priority, const FrameStamp* framestamp, osg::ref_ptr<osg::Referenced>& databaseRequest, const osg::Referenced* options=0) = 0;
284
285        protected:
286            virtual ~DatabaseRequestHandler() {}
287        };
288
289        /** Set the handler for database requests.*/
290        void setDatabaseRequestHandler(DatabaseRequestHandler* handler) { _databaseRequestHandler = handler; }
291
292        /** Get the handler for database requests.*/
293        DatabaseRequestHandler* getDatabaseRequestHandler() { return _databaseRequestHandler.get(); }
294
295        /** Get the const handler for database requests.*/
296        const DatabaseRequestHandler* getDatabaseRequestHandler() const { return _databaseRequestHandler.get(); }
297
298
299        /** Callback for managing image paging, such as generated by PagedLOD nodes.*/
300        class ImageRequestHandler : public osg::Referenced
301        {
302        public:
303
304            ImageRequestHandler():
305                Referenced(true) {}
306
307            virtual double getPreLoadTime() const = 0;
308
309            virtual osg::Image* readImageFile(const std::string& fileName) = 0;
310
311            virtual void requestImageFile(const std::string& fileName,osg::Object* attachmentPoint, int attachmentIndex, double timeToMergeBy, const FrameStamp* framestamp, osg::ref_ptr<osg::Referenced>& imageRequest, const osg::Referenced* options=0) = 0;
312
313        protected:
314            virtual ~ImageRequestHandler() {}
315        };
316
317        /** Set the handler for image requests.*/
318        void setImageRequestHandler(ImageRequestHandler* handler) { _imageRequestHandler = handler; }
319
320        /** Get the handler for image requests.*/
321        ImageRequestHandler* getImageRequestHandler() { return _imageRequestHandler.get(); }
322
323        /** Get the const handler for image requests.*/
324        const ImageRequestHandler* getImageRequestHandler() const { return _imageRequestHandler.get(); }
325
326
327
328    protected:
329
330        VisitorType                     _visitorType;
331        unsigned int                    _traversalNumber;
332
333        ref_ptr<FrameStamp>             _frameStamp;
334
335        TraversalMode                   _traversalMode;
336        Node::NodeMask                  _traversalMask;
337        Node::NodeMask                  _nodeMaskOverride;
338
339        NodePath                        _nodePath;
340
341        ref_ptr<Referenced>             _userData;
342
343        ref_ptr<DatabaseRequestHandler> _databaseRequestHandler;
344        ref_ptr<ImageRequestHandler>    _imageRequestHandler;
345
346};
347
348
349/** Convenience functor for assisting visiting of arrays of osg::Node's.*/
350class NodeAcceptOp
351{
352    public:
353
354        NodeAcceptOp(NodeVisitor& nv):_nv(nv) {}
355        NodeAcceptOp(const NodeAcceptOp& naop):_nv(naop._nv) {}
356
357        void operator () (Node* node) { node->accept(_nv); }
358        void operator () (ref_ptr<Node> node) { node->accept(_nv); }
359
360    protected:
361
362        NodeAcceptOp& operator = (const NodeAcceptOp&) { return *this; }
363
364        NodeVisitor& _nv;
365};
366
367}
368
369#endif
Note: See TracBrowser for help on using the browser.