From Farshid Lashkari, "As discussed, I've added the ability to handle Drawable objects within the NodeVisitor class. Here is an overview of the changes:
- Added apply(Drawable) and apply(Geometry) to NodeVisitor - Added accept(NodeVisitor) method to Drawable/Geometry - Added traverse(NodeVisitor) to Geode which calls accept(NodeVisitor) on all Drawables - Updated CullVisitor to use new apply(Drawable) to handle drawables. The apply(Billboard) method still manually handles the drawables since it is depends on the billboard settings. I needed to disable the traverse within billboard to prevent duplicate traversal of drawables. - Update other osgUtil node visitors (GLObjectsVisitor, IncrementalCompileOperation, ..) to use new apply(Drawable) method. "
This commit is contained in:
parent
ead92353fe
commit
b2c7bacfe9
@ -115,6 +115,8 @@ class OSG_EXPORT Drawable : public Object
|
||||
* Equivalent to dynamic_cast<const Geometry*>(this).*/
|
||||
virtual const Geometry* asGeometry() const { return 0; }
|
||||
|
||||
/** Visitor Pattern : calls the apply method of a NodeVisitor with this drawable's type.*/
|
||||
virtual void accept(NodeVisitor& nv);
|
||||
|
||||
/** Compute the DataVariance based on an assessment of callback etc.*/
|
||||
virtual void computeDataVariance();
|
||||
|
@ -41,6 +41,8 @@ class OSG_EXPORT Geode : public Node
|
||||
virtual Geode* asGeode() { return this; }
|
||||
virtual const Geode* asGeode() const { return this; }
|
||||
|
||||
virtual void traverse(NodeVisitor& nv);
|
||||
|
||||
/** Add a \c Drawable to the \c Geode.
|
||||
* If \c drawable is not \c NULL and is not contained in the \c Geode
|
||||
* then increment its reference count, add it to the drawables list and
|
||||
|
@ -44,6 +44,8 @@ class OSG_EXPORT Geometry : public Drawable
|
||||
virtual Geometry* asGeometry() { return this; }
|
||||
virtual const Geometry* asGeometry() const { return this; }
|
||||
|
||||
virtual void accept(NodeVisitor& nv) { nv.apply(*this); }
|
||||
|
||||
bool empty() const;
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::Array> > ArrayList;
|
||||
|
@ -41,6 +41,8 @@ class TexGenNode;
|
||||
class Transform;
|
||||
class Camera;
|
||||
class CameraView;
|
||||
class Drawable;
|
||||
class Geometry;
|
||||
|
||||
const unsigned int UNINITIALIZED_FRAME_NUMBER=0xffffffff;
|
||||
|
||||
@ -89,7 +91,7 @@ class OSG_EXPORT NodeVisitor : public virtual Object
|
||||
|
||||
NodeVisitor(const NodeVisitor& nv, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual ~NodeVisitor();
|
||||
virtual ~NodeVisitor();
|
||||
|
||||
META_Object(osg, NodeVisitor)
|
||||
|
||||
@ -237,6 +239,8 @@ class OSG_EXPORT NodeVisitor : public virtual Object
|
||||
* If the getDistanceToViewPoint(pos) is not implemented then a default value of 0.0 is returned.*/
|
||||
virtual float getDistanceToViewPoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
|
||||
|
||||
virtual void apply(Drawable& drawable);
|
||||
virtual void apply(Geometry& drawable);
|
||||
|
||||
virtual void apply(Node& node);
|
||||
|
||||
|
@ -90,6 +90,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
|
||||
|
||||
virtual void apply(osg::Node&);
|
||||
virtual void apply(osg::Geode& node);
|
||||
virtual void apply(osg::Drawable& drawable);
|
||||
virtual void apply(osg::Billboard& node);
|
||||
virtual void apply(osg::LightSource& node);
|
||||
virtual void apply(osg::ClipNode& node);
|
||||
|
@ -44,7 +44,6 @@ class OSGUTIL_EXPORT StateToCompile : public osg::NodeVisitor
|
||||
bool empty() const { return _textures.empty() && _programs.empty() && _drawables.empty(); }
|
||||
|
||||
virtual void apply(osg::Node& node);
|
||||
virtual void apply(osg::Geode& node);
|
||||
|
||||
virtual void apply(osg::Drawable& drawable);
|
||||
virtual void apply(osg::StateSet& stateset);
|
||||
|
@ -272,6 +272,11 @@ Drawable::~Drawable()
|
||||
dirtyDisplayList();
|
||||
}
|
||||
|
||||
void Drawable::accept(NodeVisitor& nv)
|
||||
{
|
||||
nv.apply(*this);
|
||||
}
|
||||
|
||||
osg::MatrixList Drawable::getWorldMatrices(const osg::Node* haltTraversalAtNode) const
|
||||
{
|
||||
osg::MatrixList matrices;
|
||||
|
@ -48,6 +48,16 @@ Geode::~Geode()
|
||||
}
|
||||
}
|
||||
|
||||
void Geode::traverse(NodeVisitor& nv)
|
||||
{
|
||||
for(DrawableList::iterator itr=_drawables.begin();
|
||||
itr!=_drawables.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->accept(nv);
|
||||
}
|
||||
}
|
||||
|
||||
bool Geode::addDrawable( Drawable *drawable )
|
||||
{
|
||||
if (drawable /* && !containsDrawable(drawable)*/)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <osg/Transform>
|
||||
#include <osg/Camera>
|
||||
#include <osg/CameraView>
|
||||
#include <osg/Geometry>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -75,6 +76,16 @@ NodeVisitor::~NodeVisitor()
|
||||
// if (_traversalVisitor) detach from _traversalVisitor;
|
||||
}
|
||||
|
||||
void NodeVisitor::apply(Drawable& drawable)
|
||||
{
|
||||
// It all ends here...
|
||||
}
|
||||
|
||||
void NodeVisitor::apply(Geometry& drawable)
|
||||
{
|
||||
apply(static_cast<Drawable&>(drawable));
|
||||
}
|
||||
|
||||
void NodeVisitor::apply(Node& node)
|
||||
{
|
||||
traverse(node);
|
||||
|
@ -961,91 +961,94 @@ void CullVisitor::apply(Geode& node)
|
||||
{
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
// traverse any call callbacks and traverse any children.
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
RefMatrix& matrix = *getModelViewMatrix();
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
Drawable* drawable = node.getDrawable(i);
|
||||
const BoundingBox &bb =drawable->getBound();
|
||||
|
||||
if( drawable->getCullCallback() )
|
||||
{
|
||||
if( drawable->getCullCallback()->cull( this, drawable, &_renderInfo ) == true )
|
||||
continue;
|
||||
}
|
||||
|
||||
//else
|
||||
{
|
||||
if (node.isCullingActive() && isCulled(bb)) continue;
|
||||
}
|
||||
|
||||
|
||||
if (_computeNearFar && bb.valid())
|
||||
{
|
||||
if (!updateCalculatedNearFar(matrix,*drawable,false)) continue;
|
||||
}
|
||||
|
||||
// need to track how push/pops there are, so we can unravel the stack correctly.
|
||||
unsigned int numPopStateSetRequired = 0;
|
||||
|
||||
// push the geoset's state on the geostate stack.
|
||||
StateSet* stateset = drawable->getStateSet();
|
||||
if (stateset)
|
||||
{
|
||||
++numPopStateSetRequired;
|
||||
pushStateSet(stateset);
|
||||
}
|
||||
|
||||
CullingSet& cs = getCurrentCullingSet();
|
||||
if (!cs.getStateFrustumList().empty())
|
||||
{
|
||||
osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
|
||||
for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
|
||||
itr != sfl.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second.contains(bb))
|
||||
{
|
||||
++numPopStateSetRequired;
|
||||
pushStateSet(itr->first.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;
|
||||
|
||||
if (osg::isNaN(depth))
|
||||
{
|
||||
OSG_NOTICE<<"CullVisitor::apply(Geode&) detected NaN,"<<std::endl
|
||||
<<" depth="<<depth<<", center=("<<bb.center()<<"),"<<std::endl
|
||||
<<" matrix="<<matrix<<std::endl;
|
||||
OSG_DEBUG << " NodePath:" << std::endl;
|
||||
for (NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
|
||||
{
|
||||
OSG_DEBUG << " \"" << (*i)->getName() << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addDrawableAndDepth(drawable,&matrix,depth);
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i< numPopStateSetRequired; ++i)
|
||||
{
|
||||
popStateSet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// pop the node's state off the geostate stack.
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void CullVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
RefMatrix& matrix = *getModelViewMatrix();
|
||||
|
||||
const BoundingBox &bb =drawable.getBound();
|
||||
|
||||
if( drawable.getCullCallback() )
|
||||
{
|
||||
if( drawable.getCullCallback()->cull( this, &drawable, &_renderInfo ) == true )
|
||||
return;
|
||||
}
|
||||
|
||||
//else
|
||||
{
|
||||
if (getNodePath().back()->isCullingActive() && isCulled(bb)) return;
|
||||
}
|
||||
|
||||
|
||||
if (_computeNearFar && bb.valid())
|
||||
{
|
||||
if (!updateCalculatedNearFar(matrix,drawable,false)) return;
|
||||
}
|
||||
|
||||
// need to track how push/pops there are, so we can unravel the stack correctly.
|
||||
unsigned int numPopStateSetRequired = 0;
|
||||
|
||||
// push the geoset's state on the geostate stack.
|
||||
StateSet* stateset = drawable.getStateSet();
|
||||
if (stateset)
|
||||
{
|
||||
++numPopStateSetRequired;
|
||||
pushStateSet(stateset);
|
||||
}
|
||||
|
||||
CullingSet& cs = getCurrentCullingSet();
|
||||
if (!cs.getStateFrustumList().empty())
|
||||
{
|
||||
osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
|
||||
for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
|
||||
itr != sfl.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second.contains(bb))
|
||||
{
|
||||
++numPopStateSetRequired;
|
||||
pushStateSet(itr->first.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;
|
||||
|
||||
if (osg::isNaN(depth))
|
||||
{
|
||||
OSG_NOTICE<<"CullVisitor::apply(Geode&) detected NaN,"<<std::endl
|
||||
<<" depth="<<depth<<", center=("<<bb.center()<<"),"<<std::endl
|
||||
<<" matrix="<<matrix<<std::endl;
|
||||
OSG_DEBUG << " NodePath:" << std::endl;
|
||||
for (NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
|
||||
{
|
||||
OSG_DEBUG << " \"" << (*i)->getName() << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addDrawableAndDepth(&drawable,&matrix,depth);
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i< numPopStateSetRequired; ++i)
|
||||
{
|
||||
popStateSet();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1057,8 +1060,8 @@ void CullVisitor::apply(Billboard& node)
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
// traverse any call callbacks and traverse any children.
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
// Don't traverse billboard, since drawables are handled manually below
|
||||
//handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
const Vec3& eye_local = getEyeLocal();
|
||||
const RefMatrix& modelview = *getModelViewMatrix();
|
||||
|
@ -61,18 +61,7 @@ void GLObjectsVisitor::apply(osg::Geode& node)
|
||||
apply(*(node.getStateSet()));
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = node.getDrawable(i);
|
||||
if (drawable)
|
||||
{
|
||||
apply(*drawable);
|
||||
if (drawable->getStateSet())
|
||||
{
|
||||
apply(*(drawable->getStateSet()));
|
||||
}
|
||||
}
|
||||
}
|
||||
traverse(node);
|
||||
|
||||
bool programSetAfter = _lastCompiledProgram.valid();
|
||||
if (!programSetBefore && programSetAfter)
|
||||
@ -120,6 +109,11 @@ void GLObjectsVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
drawable.releaseGLObjects(_renderInfo.getState());
|
||||
}
|
||||
|
||||
if (drawable.getStateSet())
|
||||
{
|
||||
apply(*(drawable.getStateSet()));
|
||||
}
|
||||
}
|
||||
|
||||
void GLObjectsVisitor::apply(osg::StateSet& stateset)
|
||||
|
@ -70,27 +70,6 @@ void StateToCompile::apply(osg::Node& node)
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void StateToCompile::apply(osg::Geode& node)
|
||||
{
|
||||
if (node.getStateSet())
|
||||
{
|
||||
apply(*(node.getStateSet()));
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = node.getDrawable(i);
|
||||
if (drawable)
|
||||
{
|
||||
apply(*drawable);
|
||||
if (drawable->getStateSet())
|
||||
{
|
||||
apply(*(drawable->getStateSet()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StateToCompile::apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (_drawablesHandled.count(&drawable)!=0) return;
|
||||
@ -122,6 +101,11 @@ void StateToCompile::apply(osg::Drawable& drawable)
|
||||
{
|
||||
_drawables.insert(&drawable);
|
||||
}
|
||||
|
||||
if (drawable.getStateSet())
|
||||
{
|
||||
apply(*(drawable.getStateSet()));
|
||||
}
|
||||
}
|
||||
|
||||
void StateToCompile::apply(osg::StateSet& stateset)
|
||||
|
@ -251,11 +251,6 @@ void StatsVisitor::apply(osg::Geode& node)
|
||||
++_numInstancedGeode;
|
||||
_geodeSet.insert(&node);
|
||||
|
||||
for(unsigned int i=0; i<node.getNumDrawables();++i)
|
||||
{
|
||||
apply(*node.getDrawable(i));
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user