Open main menu

CDOT Wiki β

Changes

Visitor

8,869 bytes added, 21:35, 8 April 2007
Code Examples
== Code Examples ==
 
<pre>
/* -*-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_NODEVISITOR
#define OSG_NODEVISITOR 1
 
#include <osg/Node>
#include <osg/Matrix>
#include <osg/FrameStamp>
 
namespace osg {
 
class Billboard;
class ClearNode;
class ClipNode;
class CoordinateSystemNode;
class Geode;
class Group;
class LightSource;
class LOD;
class MatrixTransform;
class OccluderNode;
class PagedLOD;
class PositionAttitudeTransform;
class Projection;
class ProxyNode;
class Sequence;
class Switch;
class TexGenNode;
class Transform;
class CameraNode;
class CameraView;
 
class OSG_EXPORT NodeVisitor : public virtual Referenced
{
public:
 
enum TraversalMode
{
TRAVERSE_NONE,
TRAVERSE_PARENTS,
TRAVERSE_ALL_CHILDREN,
TRAVERSE_ACTIVE_CHILDREN
};
 
enum VisitorType
{
NODE_VISITOR = 0,
UPDATE_VISITOR,
EVENT_VISITOR,
COLLECT_OCCLUDER_VISITOR,
CULL_VISITOR
};
NodeVisitor(TraversalMode tm=TRAVERSE_NONE);
 
NodeVisitor(VisitorType type,TraversalMode tm=TRAVERSE_NONE);
 
virtual ~NodeVisitor();
virtual void reset() {}
inline void setVisitorType(VisitorType type) { _visitorType = type; }
inline VisitorType getVisitorType() const { return _visitorType; }
inline void setTraversalNumber(int fn) { _traversalNumber = fn; }
inline int getTraversalNumber() const { return _traversalNumber; }
inline void setFrameStamp(FrameStamp* fs) { _frameStamp = fs; }
inline const FrameStamp* getFrameStamp() const { return _frameStamp.get(); }
inline void setTraversalMask(Node::NodeMask mask) { _traversalMask = mask; }
 
/** Get the TraversalMask.*/
inline Node::NodeMask getTraversalMask() const { return _traversalMask; }
inline void setNodeMaskOverride(Node::NodeMask mask) { _nodeMaskOverride = mask; }
inline Node::NodeMask getNodeMaskOverride() const { return _nodeMaskOverride; }
inline bool validNodeMask(const osg::Node& node) const
{
return (getTraversalMask() & (getNodeMaskOverride() | node.getNodeMask()))!=0;
}
 
/** 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.*/
inline void setTraversalMode(TraversalMode mode) { _traversalMode = mode; }
 
/** Get the traversal mode.*/
inline TraversalMode getTraversalMode() const { return _traversalMode; }
 
inline void setUserData(Referenced* obj) { _userData = obj; }
 
/** Get user data.*/
inline Referenced* getUserData() { return _userData.get(); }
 
/** Get const user data.*/
inline const Referenced* getUserData() const { return _userData.get(); }
 
 
inline void traverse(Node& node)
{
if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);
else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);
}
 
/** Method called by osg::Node::accept() method before
* a call to the NodeVisitor::apply(..). The back of the list will,
* therefore, be the current node being visited inside the apply(..),
* and the rest of the list will be the parental sequence of nodes
* from the top most node applied down the graph to the current node.
* Note, the user does not typically call pushNodeOnPath() as it
* will be called automatically by the Node::accept() method.*/
inline void pushOntoNodePath(Node* node) { if (_traversalMode!=TRAVERSE_PARENTS) _nodePath.push_back(node); else _nodePath.insert(_nodePath.begin(),node); }
 
inline void popFromNodePath() { if (_traversalMode!=TRAVERSE_PARENTS) _nodePath.pop_back(); else _nodePath.erase(_nodePath.begin()); }
 
/** Get the non const NodePath from the top most node applied down
* to the current Node being visited.*/
NodePath& getNodePath() { return _nodePath; }
 
/** Get the const NodePath from the top most node applied down
* to the current Node being visited.*/
const NodePath& getNodePath() const { return _nodePath; }
 
virtual osg::Vec3 getEyePoint() const { return Vec3(0.0f,0.0f,0.0f); }
 
virtual float getDistanceToEyePoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
 
virtual float getDistanceFromEyePoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
 
virtual void apply(Node& node) { traverse(node);}
 
virtual void apply(Geode& node) { apply((Node&)node); }
virtual void apply(Billboard& node) { apply((Geode&)node); }
 
virtual void apply(Group& node) { apply((Node&)node); }
 
virtual void apply(ProxyNode& node) { apply((Group&)node); }
 
virtual void apply(Projection& node) { apply((Group&)node); }
 
virtual void apply(CoordinateSystemNode& node) { apply((Group&)node); }
 
virtual void apply(ClipNode& node) { apply((Group&)node); }
virtual void apply(TexGenNode& node) { apply((Group&)node); }
virtual void apply(LightSource& node) { apply((Group&)node); }
 
virtual void apply(Transform& node) { apply((Group&)node); }
virtual void apply(CameraNode& node) { apply((Transform&)node); }
virtual void apply(CameraView& node) { apply((Transform&)node); }
virtual void apply(MatrixTransform& node) { apply((Transform&)node); }
virtual void apply(PositionAttitudeTransform& node) { apply((Transform&)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(PagedLOD& node) { apply((LOD&)node); }
virtual void apply(ClearNode& node) { apply((Group&)node); }
virtual void apply(OccluderNode& node) { apply((Group&)node); }
 
 
/** Callback for managing database paging, such as generated by PagedLOD nodes.*/
class DatabaseRequestHandler : public osg::Referenced
{
public:
virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const FrameStamp* framestamp) = 0;
 
protected:
virtual ~DatabaseRequestHandler() {}
};
 
/** Set the handler for database requests.*/
void setDatabaseRequestHandler(DatabaseRequestHandler* handler) { _databaseRequestHandler = handler; }
 
/** Get the handler for database requests.*/
DatabaseRequestHandler* getDatabaseRequestHandler() { return _databaseRequestHandler.get(); }
 
/** Get the const handler for database requests.*/
const DatabaseRequestHandler* getDatabaseRequestHandler() const { return _databaseRequestHandler.get(); }
 
 
 
protected:
 
VisitorType _visitorType;
int _traversalNumber;
 
ref_ptr<FrameStamp> _frameStamp;
 
TraversalMode _traversalMode;
Node::NodeMask _traversalMask;
Node::NodeMask _nodeMaskOverride;
 
NodePath _nodePath;
 
ref_ptr<Referenced> _userData;
 
ref_ptr<DatabaseRequestHandler> _databaseRequestHandler;
 
};
 
 
/** Convenience 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
 
 
 
</pre>
1
edit