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).*/
|
* Equivalent to dynamic_cast<const Geometry*>(this).*/
|
||||||
virtual const Geometry* asGeometry() const { return 0; }
|
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.*/
|
/** Compute the DataVariance based on an assessment of callback etc.*/
|
||||||
virtual void computeDataVariance();
|
virtual void computeDataVariance();
|
||||||
|
@ -41,6 +41,8 @@ class OSG_EXPORT Geode : public Node
|
|||||||
virtual Geode* asGeode() { return this; }
|
virtual Geode* asGeode() { return this; }
|
||||||
virtual const Geode* asGeode() const { return this; }
|
virtual const Geode* asGeode() const { return this; }
|
||||||
|
|
||||||
|
virtual void traverse(NodeVisitor& nv);
|
||||||
|
|
||||||
/** Add a \c Drawable to the \c Geode.
|
/** Add a \c Drawable to the \c Geode.
|
||||||
* If \c drawable is not \c NULL and is not contained in 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
|
* 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 Geometry* asGeometry() { return this; }
|
||||||
virtual const Geometry* asGeometry() const { return this; }
|
virtual const Geometry* asGeometry() const { return this; }
|
||||||
|
|
||||||
|
virtual void accept(NodeVisitor& nv) { nv.apply(*this); }
|
||||||
|
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
typedef std::vector< osg::ref_ptr<osg::Array> > ArrayList;
|
typedef std::vector< osg::ref_ptr<osg::Array> > ArrayList;
|
||||||
|
@ -41,6 +41,8 @@ class TexGenNode;
|
|||||||
class Transform;
|
class Transform;
|
||||||
class Camera;
|
class Camera;
|
||||||
class CameraView;
|
class CameraView;
|
||||||
|
class Drawable;
|
||||||
|
class Geometry;
|
||||||
|
|
||||||
const unsigned int UNINITIALIZED_FRAME_NUMBER=0xffffffff;
|
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);
|
NodeVisitor(const NodeVisitor& nv, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||||
|
|
||||||
virtual ~NodeVisitor();
|
virtual ~NodeVisitor();
|
||||||
|
|
||||||
META_Object(osg, 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.*/
|
* 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 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);
|
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::Node&);
|
||||||
virtual void apply(osg::Geode& node);
|
virtual void apply(osg::Geode& node);
|
||||||
|
virtual void apply(osg::Drawable& drawable);
|
||||||
virtual void apply(osg::Billboard& node);
|
virtual void apply(osg::Billboard& node);
|
||||||
virtual void apply(osg::LightSource& node);
|
virtual void apply(osg::LightSource& node);
|
||||||
virtual void apply(osg::ClipNode& 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(); }
|
bool empty() const { return _textures.empty() && _programs.empty() && _drawables.empty(); }
|
||||||
|
|
||||||
virtual void apply(osg::Node& node);
|
virtual void apply(osg::Node& node);
|
||||||
virtual void apply(osg::Geode& node);
|
|
||||||
|
|
||||||
virtual void apply(osg::Drawable& drawable);
|
virtual void apply(osg::Drawable& drawable);
|
||||||
virtual void apply(osg::StateSet& stateset);
|
virtual void apply(osg::StateSet& stateset);
|
||||||
|
@ -272,6 +272,11 @@ Drawable::~Drawable()
|
|||||||
dirtyDisplayList();
|
dirtyDisplayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Drawable::accept(NodeVisitor& nv)
|
||||||
|
{
|
||||||
|
nv.apply(*this);
|
||||||
|
}
|
||||||
|
|
||||||
osg::MatrixList Drawable::getWorldMatrices(const osg::Node* haltTraversalAtNode) const
|
osg::MatrixList Drawable::getWorldMatrices(const osg::Node* haltTraversalAtNode) const
|
||||||
{
|
{
|
||||||
osg::MatrixList matrices;
|
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 )
|
bool Geode::addDrawable( Drawable *drawable )
|
||||||
{
|
{
|
||||||
if (drawable /* && !containsDrawable(drawable)*/)
|
if (drawable /* && !containsDrawable(drawable)*/)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <osg/Transform>
|
#include <osg/Transform>
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
#include <osg/CameraView>
|
#include <osg/CameraView>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -75,6 +76,16 @@ NodeVisitor::~NodeVisitor()
|
|||||||
// if (_traversalVisitor) detach from _traversalVisitor;
|
// 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)
|
void NodeVisitor::apply(Node& node)
|
||||||
{
|
{
|
||||||
traverse(node);
|
traverse(node);
|
||||||
|
@ -961,91 +961,94 @@ void CullVisitor::apply(Geode& node)
|
|||||||
{
|
{
|
||||||
if (isCulled(node)) return;
|
if (isCulled(node)) return;
|
||||||
|
|
||||||
|
// push the culling mode.
|
||||||
|
pushCurrentMask();
|
||||||
|
|
||||||
// push the node's state.
|
// push the node's state.
|
||||||
StateSet* node_state = node.getStateSet();
|
StateSet* node_state = node.getStateSet();
|
||||||
if (node_state) pushStateSet(node_state);
|
if (node_state) pushStateSet(node_state);
|
||||||
|
|
||||||
// traverse any call callbacks and traverse any children.
|
|
||||||
handle_cull_callbacks_and_traverse(node);
|
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.
|
// pop the node's state off the geostate stack.
|
||||||
if (node_state) popStateSet();
|
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();
|
StateSet* node_state = node.getStateSet();
|
||||||
if (node_state) pushStateSet(node_state);
|
if (node_state) pushStateSet(node_state);
|
||||||
|
|
||||||
// traverse any call callbacks and traverse any children.
|
// Don't traverse billboard, since drawables are handled manually below
|
||||||
handle_cull_callbacks_and_traverse(node);
|
//handle_cull_callbacks_and_traverse(node);
|
||||||
|
|
||||||
const Vec3& eye_local = getEyeLocal();
|
const Vec3& eye_local = getEyeLocal();
|
||||||
const RefMatrix& modelview = *getModelViewMatrix();
|
const RefMatrix& modelview = *getModelViewMatrix();
|
||||||
|
@ -61,18 +61,7 @@ void GLObjectsVisitor::apply(osg::Geode& node)
|
|||||||
apply(*(node.getStateSet()));
|
apply(*(node.getStateSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
traverse(node);
|
||||||
{
|
|
||||||
osg::Drawable* drawable = node.getDrawable(i);
|
|
||||||
if (drawable)
|
|
||||||
{
|
|
||||||
apply(*drawable);
|
|
||||||
if (drawable->getStateSet())
|
|
||||||
{
|
|
||||||
apply(*(drawable->getStateSet()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool programSetAfter = _lastCompiledProgram.valid();
|
bool programSetAfter = _lastCompiledProgram.valid();
|
||||||
if (!programSetBefore && programSetAfter)
|
if (!programSetBefore && programSetAfter)
|
||||||
@ -120,6 +109,11 @@ void GLObjectsVisitor::apply(osg::Drawable& drawable)
|
|||||||
{
|
{
|
||||||
drawable.releaseGLObjects(_renderInfo.getState());
|
drawable.releaseGLObjects(_renderInfo.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drawable.getStateSet())
|
||||||
|
{
|
||||||
|
apply(*(drawable.getStateSet()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLObjectsVisitor::apply(osg::StateSet& stateset)
|
void GLObjectsVisitor::apply(osg::StateSet& stateset)
|
||||||
|
@ -70,27 +70,6 @@ void StateToCompile::apply(osg::Node& node)
|
|||||||
traverse(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)
|
void StateToCompile::apply(osg::Drawable& drawable)
|
||||||
{
|
{
|
||||||
if (_drawablesHandled.count(&drawable)!=0) return;
|
if (_drawablesHandled.count(&drawable)!=0) return;
|
||||||
@ -122,6 +101,11 @@ void StateToCompile::apply(osg::Drawable& drawable)
|
|||||||
{
|
{
|
||||||
_drawables.insert(&drawable);
|
_drawables.insert(&drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drawable.getStateSet())
|
||||||
|
{
|
||||||
|
apply(*(drawable.getStateSet()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateToCompile::apply(osg::StateSet& stateset)
|
void StateToCompile::apply(osg::StateSet& stateset)
|
||||||
|
@ -251,11 +251,6 @@ void StatsVisitor::apply(osg::Geode& node)
|
|||||||
++_numInstancedGeode;
|
++_numInstancedGeode;
|
||||||
_geodeSet.insert(&node);
|
_geodeSet.insert(&node);
|
||||||
|
|
||||||
for(unsigned int i=0; i<node.getNumDrawables();++i)
|
|
||||||
{
|
|
||||||
apply(*node.getDrawable(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
traverse(node);
|
traverse(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user