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:
Robert Osfield 2002-06-10 13:50:25 +00:00
parent 348419219d
commit e1ba8a6292
9 changed files with 209 additions and 0 deletions

4
NEWS
View File

@ -10,6 +10,10 @@ OSG News (most significant items from ChangeLog)
osgSim a seperate add-on library adds support for navigational light points. osgSim a seperate add-on library adds support for navigational light points.
osgGA (Gui Abstrabtion) library introduced to provide classes for adatping
different GUI toolkits to work with a standard set of manipulators for
modifying the scene, such as camera and state manipulators.
Support for NodeKits. Support for NodeKits.

View File

@ -133,6 +133,10 @@ SOURCE=..\..\src\osg\ColorMatrix.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\src\osg\CollectOccludersVisitor.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\ConvexPlanerOccluder.cpp SOURCE=..\..\src\osg\ConvexPlanerOccluder.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -429,6 +433,10 @@ SOURCE=..\..\Include\Osg\ColorMatrix
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Include\Osg\CollectOccludersVisitor
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\CopyOp SOURCE=..\..\Include\Osg\CopyOp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -0,0 +1,54 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_COLLECTOCCLUDERSVISITOR
#define OSG_COLLECTOCCLUDERSVISITOR 1
#include <osg/NodeVisitor>
#include <osg/CullStack>
namespace osg {
class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::CullStack
{
public:
CollectOccludersVisitor();
virtual ~CollectOccludersVisitor();
virtual CollectOccludersVisitor* cloneType() const { return new CollectOccludersVisitor(); }
virtual void reset();
virtual void apply(osg::Node&);
virtual void apply(osg::Transform& node);
virtual void apply(osg::Projection& node);
virtual void apply(osg::Switch& node);
virtual void apply(osg::LOD& node);
virtual void apply(osg::OccluderNode& node);
typedef std::vector<ShadowVolumeOccluder> OccluderList;
OccluderList& getOccluderList() { return _occluderList; }
const OccluderList& getOccluderList() const { return _occluderList; }
protected:
/** prevent unwanted copy construction.*/
CollectOccludersVisitor(const CollectOccludersVisitor&):osg::NodeVisitor(),osg::CullStack() {}
/** prevent unwanted copy operator.*/
CollectOccludersVisitor& operator = (const CollectOccludersVisitor&) { return *this; }
OccluderList _occluderList;
};
}
#endif

View File

@ -141,6 +141,12 @@ class SG_EXPORT Node : public Object
* note, return true only if no children have culling disabled, and the local _cullingActive flag is true.*/ * note, return true only if no children have culling disabled, and the local _cullingActive flag is true.*/
inline const bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && _bsphere.isValid(); } inline const bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && _bsphere.isValid(); }
/** Get the number of Children of this node which are or have OccluderNode's.*/
inline const int getNumChildrenWithOccluderNodes() const { return _numChildrenWithOccluderNodes; }
/** return true if this node is an OccluderNode or the subgraph below this node are OccluderNodes.*/
inline const bool containsOccluderNodes() const;
/** /**
* Set user data, data must be subclased from Referenced to allow * Set user data, data must be subclased from Referenced to allow
@ -248,6 +254,9 @@ class SG_EXPORT Node : public Object
int _numChildrenWithCullingDisabled; int _numChildrenWithCullingDisabled;
void setNumChildrenWithCullingDisabled(const int num); void setNumChildrenWithCullingDisabled(const int num);
int _numChildrenWithOccluderNodes;
void setNumChildrenWithOccluderNodes(const int num);
osg::ref_ptr<Referenced> _userData; osg::ref_ptr<Referenced> _userData;
NodeMask _nodeMask; NodeMask _nodeMask;

View 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)
{
}

View File

@ -3,6 +3,7 @@
#include <osg/Group> #include <osg/Group>
#include <osg/BoundingBox> #include <osg/BoundingBox>
#include <osg/Transform> #include <osg/Transform>
#include <osg/OccluderNode>
#include <algorithm> #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; return true;
} }
else return false; 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. // note ref_ptr<> automatically handles decrementing child's reference count.
_children.erase(itr); _children.erase(itr);
dirtyBound(); dirtyBound();

View File

@ -12,6 +12,7 @@ CXXFILES =\
ClipPlane.cpp\ ClipPlane.cpp\
ColorMask.cpp\ ColorMask.cpp\
ColorMatrix.cpp\ ColorMatrix.cpp\
CollectOccludersVisitor.cpp\
ConvexPlanerPolygon.cpp\ ConvexPlanerPolygon.cpp\
ConvexPlanerOccluder.cpp\ ConvexPlanerOccluder.cpp\
CopyOp.cpp\ CopyOp.cpp\

View File

@ -2,6 +2,7 @@
#include <osg/Group> #include <osg/Group>
#include <osg/NodeVisitor> #include <osg/NodeVisitor>
#include <osg/Notify> #include <osg/Notify>
#include <osg/OccluderNode>
#include <algorithm> #include <algorithm>
@ -17,6 +18,7 @@ Node::Node()
_cullingActive = true; _cullingActive = true;
_numChildrenWithCullingDisabled = 0; _numChildrenWithCullingDisabled = 0;
_numChildrenWithOccluderNodes = 0;
} }
Node::Node(const Node& node,const CopyOp& copyop): Node::Node(const Node& node,const CopyOp& copyop):
@ -30,6 +32,7 @@ Node::Node(const Node& node,const CopyOp& copyop):
_cullCallback(node._cullCallback), _cullCallback(node._cullCallback),
_cullingActive(node._cullingActive), _cullingActive(node._cullingActive),
_numChildrenWithCullingDisabled(0), // assume no children yet. _numChildrenWithCullingDisabled(0), // assume no children yet.
_numChildrenWithOccluderNodes(0),
_userData(copyop(node._userData.get())), _userData(copyop(node._userData.get())),
_nodeMask(node._nodeMask), _nodeMask(node._nodeMask),
_descriptions(node._descriptions), _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 const bool Node::computeBound() const
{ {
_bsphere.init(); _bsphere.init();

View File

@ -8,6 +8,7 @@
#include <osg/TexEnv> #include <osg/TexEnv>
#include <osg/ColorMatrix> #include <osg/ColorMatrix>
#include <osg/LightModel> #include <osg/LightModel>
#include <osg/CollectOccludersVisitor>
#include <osg/GLU> #include <osg/GLU>
@ -306,6 +307,34 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
if (!_initCalled) init(); 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(); cullVisitor->reset();