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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user