From 765db1998c17bbbb9853d87868cc8f6a48a0e714 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 7 Sep 2005 16:18:43 +0000 Subject: [PATCH] Added support for cullable state, that uses a polytope to define the extents of objects that will be influenced by it. --- examples/osgsimulation/osgsimulation.cpp | 4 +- include/osg/CullingSet | 54 +++++++++++++++++++++--- include/osgSim/OverlayNode | 3 +- src/osgSim/OverlayNode.cpp | 34 +++++++++++---- src/osgUtil/CullVisitor.cpp | 31 +++++++++++++- 5 files changed, 106 insertions(+), 20 deletions(-) diff --git a/examples/osgsimulation/osgsimulation.cpp b/examples/osgsimulation/osgsimulation.cpp index b61396bf4..03eec7117 100644 --- a/examples/osgsimulation/osgsimulation.cpp +++ b/examples/osgsimulation/osgsimulation.cpp @@ -323,14 +323,14 @@ int main(int argc, char **argv) // tell the overlay node to continously update its overlay texture // as we know we'll be tracking a moving target. - overlayNode->setContinousUpdate(true); + // overlayNode->setContinousUpdate(true); } osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); if (cessna) { - double s = 30000.0 / cessna->getBound().radius(); + double s = 600000.0 / cessna->getBound().radius(); osg::MatrixTransform* scaler = new osg::MatrixTransform; scaler->addChild(cessna); diff --git a/include/osg/CullingSet b/include/osg/CullingSet index 05add7eb3..14f24d031 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -28,7 +28,9 @@ class OSG_EXPORT CullingSet : public Referenced { public: - + + typedef std::pair< osg::ref_ptr, osg::Polytope > StateFrustumPair; + typedef std::vector< StateFrustumPair > StateFrustumList; CullingSet(); @@ -36,6 +38,7 @@ class OSG_EXPORT CullingSet : public Referenced Referenced(), _mask(cs._mask), _frustum(cs._frustum), + _stateFrustumList(cs._stateFrustumList), _occluderList(cs._occluderList), _pixelSizeVector(cs._pixelSizeVector), _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize) @@ -45,6 +48,7 @@ class OSG_EXPORT CullingSet : public Referenced CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector): _mask(cs._mask), _frustum(cs._frustum), + _stateFrustumList(cs._stateFrustumList), _occluderList(cs._occluderList), _pixelSizeVector(pixelSizeVector), _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize) @@ -64,6 +68,7 @@ class OSG_EXPORT CullingSet : public Referenced _mask = cs._mask; _frustum = cs._frustum; + _stateFrustumList = cs._stateFrustumList; _occluderList = cs._occluderList; _pixelSizeVector = cs._pixelSizeVector; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; @@ -76,6 +81,7 @@ class OSG_EXPORT CullingSet : public Referenced { _mask = cs._mask; _frustum = cs._frustum; + _stateFrustumList = cs._stateFrustumList; _occluderList = cs._occluderList; _pixelSizeVector = cs._pixelSizeVector; _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) { _mask = cs._mask; + _stateFrustumList = cs._stateFrustumList; _occluderList = cs._occluderList; _pixelSizeVector = pixelSizeVector; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; @@ -93,6 +100,13 @@ class OSG_EXPORT CullingSet : public Referenced _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(); itr!=_occluderList.end(); ++itr) @@ -133,8 +147,12 @@ class OSG_EXPORT CullingSet : public Referenced Polytope& getFrustum() { 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; } @@ -247,6 +265,17 @@ class OSG_EXPORT CullingSet : public Referenced { _frustum.pushCurrentMask(); + if (!_stateFrustumList.empty()) + { + for(StateFrustumList::iterator itr=_stateFrustumList.begin(); + itr!=_stateFrustumList.end(); + ++itr) + { + itr->second.pushCurrentMask(); + } + } + + #ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING if (!_occluderList.empty()) { @@ -264,6 +293,16 @@ class OSG_EXPORT CullingSet : public Referenced { _frustum.popCurrentMask(); + if (!_stateFrustumList.empty()) + { + for(StateFrustumList::iterator itr=_stateFrustumList.begin(); + itr!=_stateFrustumList.end(); + ++itr) + { + itr->second.popCurrentMask(); + } + } + #ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING if (!_occluderList.empty()) { @@ -286,11 +325,12 @@ class OSG_EXPORT CullingSet : public Referenced protected: - Mask _mask; - Polytope _frustum; - OccluderList _occluderList; - Vec4 _pixelSizeVector; - float _smallFeatureCullingPixelSize; + Mask _mask; + Polytope _frustum; + StateFrustumList _stateFrustumList; + OccluderList _occluderList; + Vec4 _pixelSizeVector; + float _smallFeatureCullingPixelSize; }; diff --git a/include/osgSim/OverlayNode b/include/osgSim/OverlayNode index 1b6796a21..3e452e047 100644 --- a/include/osgSim/OverlayNode +++ b/include/osgSim/OverlayNode @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -92,7 +93,7 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group osg::ref_ptr _texture; bool _continousUpdate; - osg::BoundingSphere _overlaySubgraphBound; + osg::Polytope _textureFrustum; }; } diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index 5b83d5c48..887cffdaf 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -116,10 +117,6 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) 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. osg::CoordinateSystemNode* csn = 0; 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 // will use this later to specify osg::TexGen.. - osg::Matrix MVPT = _camera->getViewMatrix() * - _camera->getProjectionMatrix() * + osg::Matrix MVP = _camera->getViewMatrix() * + _camera->getProjectionMatrix(); + + osg::Matrix MVPT = MVP * osg::Matrix::translate(1.0,1.0,1.0) * osg::Matrix::scale(0.5,0.5,0.5); @@ -180,6 +179,11 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) _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); _textureObjectValidList[contextID] = 1; @@ -202,14 +206,28 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) else #endif { + _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. - cv->pushStateSet(_mainSubgraphStateSet.get()); + // cv->pushStateSet(_mainSubgraphStateSet.get()); Group::traverse(nv); - cv->popStateSet(); + // cv->popStateSet(); + + ccs.getStateFrustumList().pop_back(); + pcs.getStateFrustumList().pop_back(); } } diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 0eed5d89a..407b7e8d4 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -745,14 +746,40 @@ void CullVisitor::apply(Geode& node) 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) 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)); else addDrawableAndDepth(drawable,&matrix,0.0f); - if (stateset) popStateSet(); + for(unsigned int i=0;i< numPopStateSetRequired; ++i) + { + popStateSet(); + } }