diff --git a/include/osg/CollectOccludersVisitor b/include/osg/CollectOccludersVisitor index 29455edbd..0496e6ed5 100644 --- a/include/osg/CollectOccludersVisitor +++ b/include/osg/CollectOccludersVisitor @@ -8,6 +8,8 @@ #include #include +#include + namespace osg { class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::CullStack @@ -15,6 +17,8 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C public: + typedef std::set ShadowVolumeOccluderSet; + CollectOccludersVisitor(); virtual ~CollectOccludersVisitor(); @@ -37,9 +41,12 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C void setCreateDrawablesOnOccludeNodes(bool flag) { _createDrawables=flag; } bool getCreateDrawablesOnOccludeNodes() const { return _createDrawables; } - void setCollectedOcculderList(const ShadowVolumeOccluderList& svol) { _occluderList = svol; } - ShadowVolumeOccluderList& getCollectedOccluderList() { return _occluderList; } - const ShadowVolumeOccluderList& getCollectedOccluderList() const { return _occluderList; } + void setCollectedOcculderList(const ShadowVolumeOccluderSet& svol) { _occluderSet = svol; } + ShadowVolumeOccluderSet& getCollectedOccluderSet() { return _occluderSet; } + const ShadowVolumeOccluderSet& getCollectedOccluderSet() const { return _occluderSet; } + + /** remove occluded occluders for the collected occluders list.*/ + void removeOccludedOccluders(); protected: @@ -66,7 +73,7 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C float _minimumShadowOccluderVolume; bool _createDrawables; - ShadowVolumeOccluderList _collectedOccluderList; + ShadowVolumeOccluderSet _occluderSet; }; diff --git a/include/osg/Polytope b/include/osg/Polytope index cf2c29ab3..201deef07 100644 --- a/include/osg/Polytope +++ b/include/osg/Polytope @@ -18,16 +18,18 @@ class SG_EXPORT Polytope public: - typedef unsigned int ClippingMask; - typedef std::vector PlaneList; - typedef fast_back_stack MaskStack; + typedef unsigned int ClippingMask; + typedef std::vector PlaneList; + typedef std::vector VertexList; + typedef fast_back_stack MaskStack; inline Polytope() {setupMask();} inline Polytope(const Polytope& cv) : _maskStack(cv._maskStack), _resultMask(cv._resultMask), - _planeList(cv._planeList) {} + _planeList(cv._planeList), + _referenceVertexList(cv._referenceVertexList) {} inline Polytope(const PlaneList& pl) : _planeList(pl) {setupMask();} @@ -41,6 +43,7 @@ class SG_EXPORT Polytope _maskStack = cv._maskStack; _resultMask = cv._resultMask; _planeList = cv._planeList; + _referenceVertexList = cv._referenceVertexList; return *this; } @@ -77,6 +80,14 @@ class SG_EXPORT Polytope inline const PlaneList& getPlaneList() const { return _planeList; } + + inline void setReferenceVertexList(VertexList& vertices) { _referenceVertexList=vertices; } + + inline VertexList& getReferenceVertexList() { return _referenceVertexList; } + + inline const VertexList& getReferenceVertexList() const { return _referenceVertexList; } + + inline void setupMask() { _resultMask = 0; @@ -312,6 +323,7 @@ class SG_EXPORT Polytope MaskStack _maskStack; ClippingMask _resultMask; PlaneList _planeList; + VertexList _referenceVertexList; }; diff --git a/include/osg/ShadowVolumeOccluder b/include/osg/ShadowVolumeOccluder index 6aa213090..ad59fcf06 100644 --- a/include/osg/ShadowVolumeOccluder +++ b/include/osg/ShadowVolumeOccluder @@ -33,6 +33,8 @@ class SG_EXPORT ShadowVolumeOccluder _volume(0.0f) {} + bool operator < (const ShadowVolumeOccluder& svo) const { return getVolume()>svo.getVolume(); } // not greater volume first. + /** compute the shadow volume occluder. */ bool computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack,bool createDrawables=false); @@ -86,7 +88,7 @@ class SG_EXPORT ShadowVolumeOccluder } - protected: +// protected: float _volume; NodePath _nodePath; diff --git a/src/osg/CollectOccludersVisitor.cpp b/src/osg/CollectOccludersVisitor.cpp index 787198c38..846386c64 100644 --- a/src/osg/CollectOccludersVisitor.cpp +++ b/src/osg/CollectOccludersVisitor.cpp @@ -5,6 +5,8 @@ #include #include +#include + using namespace osg; CollectOccludersVisitor::CollectOccludersVisitor() @@ -137,7 +139,7 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node) { // need to test occluder against view frustum. //std::cout << " adding in Occluder"<(&(*occluderItr)); + if (occluder->contains(occludee._occluderVolume.getReferenceVertexList())) + { + // erase occluder from set. + // take a copy of the iterator then rewind it one element so to prevent invalidating the occludeeItr. + ShadowVolumeOccluderSet::iterator eraseItr = occludeeItr--; + _occluderSet.erase(eraseItr); + break; + } + } + } +} diff --git a/src/osg/ShadowVolumeOccluder.cpp b/src/osg/ShadowVolumeOccluder.cpp index 5006eb451..4688db293 100644 --- a/src/osg/ShadowVolumeOccluder.cpp +++ b/src/osg/ShadowVolumeOccluder.cpp @@ -14,8 +14,8 @@ typedef std::vector PointList; typedef std::vector VertexList; -// convert a vector for Vec3 into a vector of Point's. -void convert(const VertexList& in,PointList& out) +// copyVertexListToPointList a vector for Vec3 into a vector of Point's. +void copyVertexListToPointList(const VertexList& in,PointList& out) { out.reserve(in.size()); for(VertexList::const_iterator itr=in.begin(); @@ -26,6 +26,17 @@ void convert(const VertexList& in,PointList& out) } } +void copyPointListToVertexList(const PointList& in,VertexList& out) +{ + out.reserve(in.size()); + for(PointList::const_iterator itr=in.begin(); + itr!=in.end(); + ++itr) + { + out.push_back(itr->second); + } +} + // clip the convex hull 'in' to plane to generate a clipped convex hull 'out' // return true if points remain after clipping. unsigned int clip(const Plane& plane,const PointList& in, PointList& out,unsigned int planeMask) @@ -74,7 +85,7 @@ unsigned int clip(const Plane& plane,const PointList& in, PointList& out,unsigne unsigned int clip(const Polytope::PlaneList& planeList,const VertexList& vin,PointList& out) { PointList in; - convert(vin,in); + copyVertexListToPointList(vin,in); unsigned int planeMask = 0x1; for(Polytope::PlaneList::const_iterator itr=planeList.begin(); @@ -138,22 +149,6 @@ Plane computeFrontPlane(const PointList& front) return Plane(front[2].second,front[1].second,front[0].second); } - -// // compute the volume of tetrahedron -// inline float computeVolume(const osg::Vec3& a,const osg::Vec3& b,const osg::Vec3& c,const osg::Vec3& d) -// { -// return fabs(((b-c)^(a-b))*(d-b)); -// } -// -// // compute the volume of prism. -// inline float computeVolume(const osg::Vec3& f1,const osg::Vec3& f2,const osg::Vec3& f3, -// const osg::Vec3& b1,const osg::Vec3& b2,const osg::Vec3& b3) -// { -// return computeVolume(f1,f2,f3,b1)+ -// computeVolume(b1,b2,b3,f2)+ -// computeVolume(b1,b3,f2,f3); -// } - // compute the volume between the front and back polygons of the occluder/hole. float computePolytopeVolume(const PointList& front, const PointList& back) { @@ -275,6 +270,10 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex // move the occlude points into projection space. transform(points,MV); + // use the points on the front plane as reference vertices on the _occluderVolume + // so that the vertices can later by used to test for occlusion of the occluder itself. + copyPointListToVertexList(points,_occluderVolume.getReferenceVertexList()); + // create the front face of the occluder Plane occludePlane = computeFrontPlane(points); _occluderVolume.add(occludePlane); @@ -331,6 +330,10 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex // move the occlude points into projection space. transform(points,MV); + // use the points on the front plane as reference vertices on the _occluderVolume + // so that the vertices can later by used to test for occlusion of the occluder itself. + copyPointListToVertexList(points,polytope.getReferenceVertexList()); + // create the front face of the occluder Plane occludePlane = computeFrontPlane(points); diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index dd37dbbfd..bef5e32ab 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -341,9 +341,14 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil cov.popProjectionMatrix(); cov.popViewport(); - //std::cout << "finished searching for occluder"<setOccluderList(cov.getCollectedOccluderList()); + + //std::cout << "finished searching for occluder"<getOccluderList().clear(); + std::copy(cov.getCollectedOccluderSet().begin(),cov.getCollectedOccluderSet().end(), std::back_insert_iterator(cullVisitor->getOccluderList())); }