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

Revision 13798, 15.4 kB (checked in by robert, 4 hours ago)

Added DragCallback? class to help dialog dragging support.
Introduced a new Widget::computeExtentsPositionInLocalCoordinates() method that intersects with a ray through mouse pointer and the extents of the widget.

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