Added osg::CollectOccludersVisitor which is a helper class for finding active
occluder in the view frustum, to be used as pre cull traversal.
This commit is contained in:
42
src/osg/CollectOccludersVisitor.cpp
Normal file
42
src/osg/CollectOccludersVisitor.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <osg/CollectOccludersVisitor>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
CollectOccludersVisitor::CollectOccludersVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
CollectOccludersVisitor::~CollectOccludersVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::reset()
|
||||
{
|
||||
CullStack::reset();
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::apply(osg::Node&)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::apply(osg::Transform& node)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::apply(osg::Projection& node)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::apply(osg::Switch& node)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::apply(osg::LOD& node)
|
||||
{
|
||||
}
|
||||
|
||||
void CollectOccludersVisitor::apply(osg::OccluderNode& node)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <osg/Group>
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/Transform>
|
||||
#include <osg/OccluderNode>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -80,6 +81,14 @@ bool Group::addChild( Node *child )
|
||||
);
|
||||
}
|
||||
|
||||
if (child->getNumChildrenWithOccluderNodes()>0 ||
|
||||
dynamic_cast<osg::OccluderNode*>(child))
|
||||
{
|
||||
setNumChildrenWithOccluderNodes(
|
||||
getNumChildrenWithOccluderNodes()+1
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
@@ -114,6 +123,14 @@ bool Group::removeChild( Node *child )
|
||||
);
|
||||
}
|
||||
|
||||
if (child->getNumChildrenWithOccluderNodes()>0 ||
|
||||
dynamic_cast<osg::OccluderNode*>(child))
|
||||
{
|
||||
setNumChildrenWithOccluderNodes(
|
||||
getNumChildrenWithOccluderNodes()-1
|
||||
);
|
||||
}
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
dirtyBound();
|
||||
|
||||
@@ -12,6 +12,7 @@ CXXFILES =\
|
||||
ClipPlane.cpp\
|
||||
ColorMask.cpp\
|
||||
ColorMatrix.cpp\
|
||||
CollectOccludersVisitor.cpp\
|
||||
ConvexPlanerPolygon.cpp\
|
||||
ConvexPlanerOccluder.cpp\
|
||||
CopyOp.cpp\
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <osg/Group>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Notify>
|
||||
#include <osg/OccluderNode>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -17,6 +18,7 @@ Node::Node()
|
||||
_cullingActive = true;
|
||||
_numChildrenWithCullingDisabled = 0;
|
||||
|
||||
_numChildrenWithOccluderNodes = 0;
|
||||
}
|
||||
|
||||
Node::Node(const Node& node,const CopyOp& copyop):
|
||||
@@ -30,6 +32,7 @@ Node::Node(const Node& node,const CopyOp& copyop):
|
||||
_cullCallback(node._cullCallback),
|
||||
_cullingActive(node._cullingActive),
|
||||
_numChildrenWithCullingDisabled(0), // assume no children yet.
|
||||
_numChildrenWithOccluderNodes(0),
|
||||
_userData(copyop(node._userData.get())),
|
||||
_nodeMask(node._nodeMask),
|
||||
_descriptions(node._descriptions),
|
||||
@@ -227,6 +230,48 @@ void Node::setNumChildrenWithCullingDisabled(const int num)
|
||||
}
|
||||
|
||||
|
||||
void Node::setNumChildrenWithOccluderNodes(const int num)
|
||||
{
|
||||
// if no changes just return.
|
||||
if (_numChildrenWithOccluderNodes==num) return;
|
||||
|
||||
// note, if this node is a OccluderNode then the
|
||||
// parents won't be affected by any changes to
|
||||
// _numChildrenWithOccluderNodes so no need to inform them.
|
||||
if (!dynamic_cast<OccluderNode*>(this) && !_parents.empty())
|
||||
{
|
||||
|
||||
// need to pass on changes to parents.
|
||||
int delta = 0;
|
||||
if (_numChildrenWithOccluderNodes>0) --delta;
|
||||
if (num>0) ++delta;
|
||||
if (delta!=0)
|
||||
{
|
||||
// the number of callbacks has changed, need to pass this
|
||||
// on to parents so they know whether app traversal is
|
||||
// reqired on this subgraph.
|
||||
for(ParentList::iterator itr =_parents.begin();
|
||||
itr != _parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setNumChildrenWithOccluderNodes(
|
||||
(*itr)->getNumChildrenWithOccluderNodes()+delta
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// finally update this objects value.
|
||||
_numChildrenWithOccluderNodes=num;
|
||||
|
||||
}
|
||||
|
||||
const bool Node::containsOccluderNodes() const
|
||||
{
|
||||
return _numChildrenWithOccluderNodes>0 || dynamic_cast<const OccluderNode*>(this);
|
||||
}
|
||||
|
||||
const bool Node::computeBound() const
|
||||
{
|
||||
_bsphere.init();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/ColorMatrix>
|
||||
#include <osg/LightModel>
|
||||
#include <osg/CollectOccludersVisitor>
|
||||
|
||||
#include <osg/GLU>
|
||||
|
||||
@@ -306,6 +307,34 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
|
||||
if (!_initCalled) init();
|
||||
|
||||
|
||||
// collect any occluder in the view frustum.
|
||||
if (_sceneData->containsOccluderNodes())
|
||||
{
|
||||
std::cout << "Scene graph contains occluder nodes, searching for them"<<std::endl;
|
||||
osg::CollectOccludersVisitor cov;
|
||||
|
||||
cov.setFrameStamp(_frameStamp.get());
|
||||
|
||||
// use the frame number for the traversal number.
|
||||
if (_frameStamp.valid())
|
||||
{
|
||||
cov.setTraversalNumber(_frameStamp->getFrameNumber());
|
||||
}
|
||||
|
||||
cov.pushViewport(_viewport.get());
|
||||
cov.pushProjectionMatrix(projection);
|
||||
cov.pushModelViewMatrix(modelview);
|
||||
|
||||
// traverse the scene graph to search for occluder in there new positions.
|
||||
_sceneData->accept(cov);
|
||||
|
||||
cov.popModelViewMatrix();
|
||||
cov.popProjectionMatrix();
|
||||
cov.popViewport();
|
||||
|
||||
std::cout << "finished searching for occluder"<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
cullVisitor->reset();
|
||||
|
||||
Reference in New Issue
Block a user