Added support for cullable state, that uses a polytope to define the extents

of objects that will be influenced by it.
This commit is contained in:
Robert Osfield 2005-09-07 16:18:43 +00:00
parent 58112d9591
commit 765db1998c
5 changed files with 106 additions and 20 deletions

View File

@ -323,14 +323,14 @@ int main(int argc, char **argv)
// tell the overlay node to continously update its overlay texture // tell the overlay node to continously update its overlay texture
// as we know we'll be tracking a moving target. // as we know we'll be tracking a moving target.
overlayNode->setContinousUpdate(true); // overlayNode->setContinousUpdate(true);
} }
osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
if (cessna) if (cessna)
{ {
double s = 30000.0 / cessna->getBound().radius(); double s = 600000.0 / cessna->getBound().radius();
osg::MatrixTransform* scaler = new osg::MatrixTransform; osg::MatrixTransform* scaler = new osg::MatrixTransform;
scaler->addChild(cessna); scaler->addChild(cessna);

View File

@ -28,7 +28,9 @@ class OSG_EXPORT CullingSet : public Referenced
{ {
public: public:
typedef std::pair< osg::ref_ptr<osg::StateSet>, osg::Polytope > StateFrustumPair;
typedef std::vector< StateFrustumPair > StateFrustumList;
CullingSet(); CullingSet();
@ -36,6 +38,7 @@ class OSG_EXPORT CullingSet : public Referenced
Referenced(), Referenced(),
_mask(cs._mask), _mask(cs._mask),
_frustum(cs._frustum), _frustum(cs._frustum),
_stateFrustumList(cs._stateFrustumList),
_occluderList(cs._occluderList), _occluderList(cs._occluderList),
_pixelSizeVector(cs._pixelSizeVector), _pixelSizeVector(cs._pixelSizeVector),
_smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize) _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
@ -45,6 +48,7 @@ class OSG_EXPORT CullingSet : public Referenced
CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector): CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector):
_mask(cs._mask), _mask(cs._mask),
_frustum(cs._frustum), _frustum(cs._frustum),
_stateFrustumList(cs._stateFrustumList),
_occluderList(cs._occluderList), _occluderList(cs._occluderList),
_pixelSizeVector(pixelSizeVector), _pixelSizeVector(pixelSizeVector),
_smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize) _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
@ -64,6 +68,7 @@ class OSG_EXPORT CullingSet : public Referenced
_mask = cs._mask; _mask = cs._mask;
_frustum = cs._frustum; _frustum = cs._frustum;
_stateFrustumList = cs._stateFrustumList;
_occluderList = cs._occluderList; _occluderList = cs._occluderList;
_pixelSizeVector = cs._pixelSizeVector; _pixelSizeVector = cs._pixelSizeVector;
_smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
@ -76,6 +81,7 @@ class OSG_EXPORT CullingSet : public Referenced
{ {
_mask = cs._mask; _mask = cs._mask;
_frustum = cs._frustum; _frustum = cs._frustum;
_stateFrustumList = cs._stateFrustumList;
_occluderList = cs._occluderList; _occluderList = cs._occluderList;
_pixelSizeVector = cs._pixelSizeVector; _pixelSizeVector = cs._pixelSizeVector;
_smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
@ -84,6 +90,7 @@ class OSG_EXPORT CullingSet : public Referenced
inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector) inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector)
{ {
_mask = cs._mask; _mask = cs._mask;
_stateFrustumList = cs._stateFrustumList;
_occluderList = cs._occluderList; _occluderList = cs._occluderList;
_pixelSizeVector = pixelSizeVector; _pixelSizeVector = pixelSizeVector;
_smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
@ -93,6 +100,13 @@ class OSG_EXPORT CullingSet : public Referenced
_frustum.setAndTransformProvidingInverse(cs._frustum,matrix); _frustum.setAndTransformProvidingInverse(cs._frustum,matrix);
for(StateFrustumList::iterator itr=_stateFrustumList.begin();
itr!=_stateFrustumList.end();
++itr)
{
itr->second.transformProvidingInverse(matrix);
}
for(OccluderList::iterator itr=_occluderList.begin(); for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end(); itr!=_occluderList.end();
++itr) ++itr)
@ -133,8 +147,12 @@ class OSG_EXPORT CullingSet : public Referenced
Polytope& getFrustum() { return _frustum; } Polytope& getFrustum() { return _frustum; }
const Polytope& getFrustum() const { return _frustum; } const Polytope& getFrustum() const { return _frustum; }
void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); } void addStateFrustum(StateSet* stateset, Polytope& polytope) { _stateFrustumList.push_back(StateFrustumPair(stateset,polytope)); }
void getStateFrustumList(StateFrustumList& sfl) { _stateFrustumList = sfl; }
StateFrustumList& getStateFrustumList() { return _stateFrustumList; }
void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); }
void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; } void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; }
@ -247,6 +265,17 @@ class OSG_EXPORT CullingSet : public Referenced
{ {
_frustum.pushCurrentMask(); _frustum.pushCurrentMask();
if (!_stateFrustumList.empty())
{
for(StateFrustumList::iterator itr=_stateFrustumList.begin();
itr!=_stateFrustumList.end();
++itr)
{
itr->second.pushCurrentMask();
}
}
#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING #ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
if (!_occluderList.empty()) if (!_occluderList.empty())
{ {
@ -264,6 +293,16 @@ class OSG_EXPORT CullingSet : public Referenced
{ {
_frustum.popCurrentMask(); _frustum.popCurrentMask();
if (!_stateFrustumList.empty())
{
for(StateFrustumList::iterator itr=_stateFrustumList.begin();
itr!=_stateFrustumList.end();
++itr)
{
itr->second.popCurrentMask();
}
}
#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING #ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
if (!_occluderList.empty()) if (!_occluderList.empty())
{ {
@ -286,11 +325,12 @@ class OSG_EXPORT CullingSet : public Referenced
protected: protected:
Mask _mask; Mask _mask;
Polytope _frustum; Polytope _frustum;
OccluderList _occluderList; StateFrustumList _stateFrustumList;
Vec4 _pixelSizeVector; OccluderList _occluderList;
float _smallFeatureCullingPixelSize; Vec4 _pixelSizeVector;
float _smallFeatureCullingPixelSize;
}; };

View File

@ -16,6 +16,7 @@
#include <osg/buffered_value> #include <osg/buffered_value>
#include <osg/CameraNode> #include <osg/CameraNode>
#include <osg/Texture2D>
#include <osg/TexGenNode> #include <osg/TexGenNode>
#include <osgSim/Export> #include <osgSim/Export>
@ -92,7 +93,7 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group
osg::ref_ptr<osg::Texture2D> _texture; osg::ref_ptr<osg::Texture2D> _texture;
bool _continousUpdate; bool _continousUpdate;
osg::BoundingSphere _overlaySubgraphBound; osg::Polytope _textureFrustum;
}; };
} }

View File

@ -13,6 +13,7 @@
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/CoordinateSystemNode> #include <osg/CoordinateSystemNode>
#include <osg/io_utils>
#include <osgUtil/CullVisitor> #include <osgUtil/CullVisitor>
#include <osgSim/OverlayNode> #include <osgSim/OverlayNode>
@ -116,10 +117,6 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
if (bs.valid()) if (bs.valid())
{ {
// update the bounding volume for later testing
// whether the overlay can be seen or not.
_overlaySubgraphBound = bs;
// see if we are within a coordinate system node. // see if we are within a coordinate system node.
osg::CoordinateSystemNode* csn = 0; osg::CoordinateSystemNode* csn = 0;
osg::NodePath& nodePath = nv.getNodePath(); osg::NodePath& nodePath = nv.getNodePath();
@ -171,8 +168,10 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
// compute the matrix which takes a vertex from local coords into tex coords // compute the matrix which takes a vertex from local coords into tex coords
// will use this later to specify osg::TexGen.. // will use this later to specify osg::TexGen..
osg::Matrix MVPT = _camera->getViewMatrix() * osg::Matrix MVP = _camera->getViewMatrix() *
_camera->getProjectionMatrix() * _camera->getProjectionMatrix();
osg::Matrix MVPT = MVP *
osg::Matrix::translate(1.0,1.0,1.0) * osg::Matrix::translate(1.0,1.0,1.0) *
osg::Matrix::scale(0.5,0.5,0.5); osg::Matrix::scale(0.5,0.5,0.5);
@ -180,6 +179,11 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
_texgenNode->getTexGen()->setPlanesFromMatrix(MVPT); _texgenNode->getTexGen()->setPlanesFromMatrix(MVPT);
_textureFrustum.setToUnitFrustum(false,false);
// const osg::Matrix modelView = (cv->getModelViewMatrix());
// _textureFrustum.transformProvidingInverse(osg::Matrix::inverse(modelView)*MVP);
_textureFrustum.transformProvidingInverse(MVP);
_camera->accept(*cv); _camera->accept(*cv);
_textureObjectValidList[contextID] = 1; _textureObjectValidList[contextID] = 1;
@ -202,14 +206,28 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
else else
#endif #endif
{ {
_texgenNode->accept(*cv); _texgenNode->accept(*cv);
osg::CullingSet& pcs = cv->getProjectionCullingStack().back();
osg::CullingSet& ccs = cv->getCurrentCullingSet();
const osg::Matrix modelView = (cv->getModelViewMatrix());
osg::Polytope viewTextureFrustum;
viewTextureFrustum.setAndTransformProvidingInverse(_textureFrustum, osg::Matrix::inverse(modelView));
pcs.addStateFrustum(_mainSubgraphStateSet.get(), viewTextureFrustum);
ccs.addStateFrustum(_mainSubgraphStateSet.get(), _textureFrustum);
// push the stateset. // push the stateset.
cv->pushStateSet(_mainSubgraphStateSet.get()); // cv->pushStateSet(_mainSubgraphStateSet.get());
Group::traverse(nv); Group::traverse(nv);
cv->popStateSet(); // cv->popStateSet();
ccs.getStateFrustumList().pop_back();
pcs.getStateFrustumList().pop_back();
} }
} }

View File

@ -25,6 +25,7 @@
#include <osg/LineSegment> #include <osg/LineSegment>
#include <osg/TriangleFunctor> #include <osg/TriangleFunctor>
#include <osg/Geometry> #include <osg/Geometry>
#include <osg/io_utils>
#include <osgUtil/CullVisitor> #include <osgUtil/CullVisitor>
@ -745,14 +746,40 @@ void CullVisitor::apply(Geode& node)
if (!updateCalculatedNearFar(matrix,*drawable,false)) continue; 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. // push the geoset's state on the geostate stack.
StateSet* stateset = drawable->getStateSet(); StateSet* stateset = drawable->getStateSet();
if (stateset) pushStateSet(stateset); 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());
}
}
}
if (bb.valid()) addDrawableAndDepth(drawable,&matrix,distance(bb.center(),matrix)); if (bb.valid()) addDrawableAndDepth(drawable,&matrix,distance(bb.center(),matrix));
else addDrawableAndDepth(drawable,&matrix,0.0f); else addDrawableAndDepth(drawable,&matrix,0.0f);
if (stateset) popStateSet(); for(unsigned int i=0;i< numPopStateSetRequired; ++i)
{
popStateSet();
}
} }