2001-01-11 00:32:10 +08:00
|
|
|
#ifndef OSG_NODEVISITOR
|
|
|
|
#define OSG_NODEVISITOR 1
|
|
|
|
|
|
|
|
#include <osg/Node>
|
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
|
|
|
class Geode;
|
|
|
|
class Billboard;
|
|
|
|
class LightSource;
|
|
|
|
class Group;
|
2001-09-20 05:08:56 +08:00
|
|
|
class Transform;
|
2001-01-11 00:32:10 +08:00
|
|
|
class LOD;
|
|
|
|
class Sequence;
|
|
|
|
class Switch;
|
2001-09-20 05:08:56 +08:00
|
|
|
class Impostor;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** Visitor for type safe operations on osg::Node's.
|
|
|
|
Based on GOF's Visitor pattern.*/
|
|
|
|
class SG_EXPORT NodeVisitor : public Referenced
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum TraversalMode {
|
|
|
|
TRAVERSE_NONE,
|
|
|
|
TRAVERSE_PARENTS,
|
|
|
|
TRAVERSE_ALL_CHILDREN,
|
|
|
|
TRAVERSE_ACTIVE_CHILDREN,
|
|
|
|
TRAVERSE_VISITOR
|
|
|
|
};
|
|
|
|
|
|
|
|
NodeVisitor(TraversalMode tm=TRAVERSE_NONE);
|
|
|
|
virtual ~NodeVisitor();
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Method to call to reset visitor. Useful for your visitor accumulates
|
|
|
|
state during a traversal, and you plan to resuse the visitor.
|
|
|
|
To flush that state for the next traversal than call reset() prior
|
|
|
|
to each traversal.*/
|
|
|
|
virtual void reset() {}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** Set the traversal mode for Node::traverse() to use when
|
|
|
|
deciding which children of a node to traverse. If a
|
|
|
|
NodeVisitor has been attached via setTraverseVisitor()
|
|
|
|
and the new mode is not TRAVERSE_VISITOR then the attached
|
|
|
|
visitor is detached. Default mode is TRAVERSE_NONE.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
void setTraversalMode(const TraversalMode mode);
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Get the traversal mode.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const TraversalMode getTraversalMode() const { return _traversalMode; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Set a visitor to handle traversal.
|
|
|
|
Overides the traverse mode setting it to TRAVERSAL_VISITOR.*/
|
|
|
|
void setTraversalVisitor(NodeVisitor* nv);
|
|
|
|
|
|
|
|
/** Get the traversal visitor, returns NULL if none is attached.*/
|
|
|
|
NodeVisitor* getTraversalVisitor() { return _traversalVisitor.get(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
/** Inline method for passing handling traversal of a nodes.
|
|
|
|
If you intend to use the visitor for actively traversing
|
|
|
|
the scene graph then make sure the accept() methods call
|
|
|
|
this method unless they handle traversal directly.*/
|
|
|
|
void traverse(Node& node)
|
|
|
|
{
|
2001-09-20 05:08:56 +08:00
|
|
|
if (_traversalVisitor.valid()) node.accept(*_traversalVisitor);
|
|
|
|
else if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);
|
|
|
|
else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);
|
2001-01-11 00:32:10 +08:00
|
|
|
}
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual void apply(Node& node) { traverse(node);}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual void apply(Geode& node) { apply((Node&)node); }
|
|
|
|
virtual void apply(Billboard& node) { apply((Geode&)node); }
|
2001-01-11 00:32:10 +08:00
|
|
|
virtual void apply(LightSource& node){ apply((Node&)node); }
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual void apply(Group& node) { apply((Node&)node); }
|
|
|
|
virtual void apply(Transform& node) { apply((Group&)node); }
|
|
|
|
virtual void apply(Switch& node) { apply((Group&)node); }
|
|
|
|
virtual void apply(Sequence& node) { apply((Group&)node); }
|
|
|
|
virtual void apply(LOD& node) { apply((Group&)node); }
|
|
|
|
virtual void apply(Impostor& node) { apply((LOD&)node); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
ref_ptr<NodeVisitor> _traversalVisitor;
|
|
|
|
TraversalMode _traversalMode;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Convinience functor for assisting visiting of arrays of osg::Node's.*/
|
|
|
|
struct NodeAcceptOp
|
|
|
|
{
|
|
|
|
NodeVisitor& _nv;
|
|
|
|
NodeAcceptOp(NodeVisitor& nv):_nv(nv) {}
|
|
|
|
void operator () (Node* node) { node->accept(_nv); }
|
|
|
|
void operator () (ref_ptr<Node> node) { node->accept(_nv); }
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|