From c7e99ff77aecb0adf174e4999f223693389a0f9f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 12 Jun 2002 09:22:30 +0000 Subject: [PATCH] Further work on occludision code. --- VisualStudio/osg/osg.dsp | 4 +- include/osg/CullStack | 5 ++ include/osg/CullingSet | 29 ++++++++++++ include/osg/Plane | 31 +++++++++++++ include/osg/Polytope | 46 +++++++++++++++++++ ...dowOccluderVolume => ShadowVolumeOccluder} | 4 ++ src/osg/CollectOccludersVisitor.cpp | 13 +++++- src/osg/Makefile | 2 +- ...derVolume.cpp => ShadowVolumeOccluder.cpp} | 16 +++++++ 9 files changed, 145 insertions(+), 5 deletions(-) rename include/osg/{ShadowOccluderVolume => ShadowVolumeOccluder} (94%) rename src/osg/{ShadowOccluderVolume.cpp => ShadowVolumeOccluder.cpp} (68%) diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 727bbcc73..2cf22a5da 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -317,7 +317,7 @@ SOURCE=..\..\src\osg\ShadeModel.cpp # End Source File # Begin Source File -SOURCE=..\..\src\osg\ShadowOccluderVolume.cpp +SOURCE=..\..\src\osg\ShadowVolumeOccluder.cpp # End Source File # Begin Source File @@ -649,7 +649,7 @@ SOURCE=..\..\Include\Osg\ShadeModel # End Source File # Begin Source File -SOURCE=..\..\Include\Osg\ShadowOccluderVolume +SOURCE=..\..\Include\Osg\ShadowVolumeOccluder # End Source File # Begin Source File diff --git a/include/osg/CullStack b/include/osg/CullStack index 02e315a9c..e67c86ef4 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -79,6 +79,11 @@ class SG_EXPORT CullStack _modelviewCullingStack.back()->disableOccluder(nodePath); } + inline bool isCulled(const std::vector& vertices) + { + return _modelviewCullingStack.back()->isCulled(vertices); + } + inline bool isCulled(const BoundingBox& bb) { return bb.isValid() && _modelviewCullingStack.back()->isCulled(bb); diff --git a/include/osg/CullingSet b/include/osg/CullingSet index a0b275c83..45710bbaa 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -94,6 +94,35 @@ class SG_EXPORT CullingSet : public Referenced } + inline bool isCulled(const std::vector& vertices) + { + if (_mask&VIEW_FRUSTUM_CULLING) + { + // is it outside the view frustum... + if (!_frustum.contains(vertices)) return true; + } + + if (_mask&SMALL_FEATURE_CULLING) + { + } + + if (_mask&SHADOW_OCCLUSION_CULLING) + { + // is it in one of the shadow occluder volumes. + if (!_occluderList.empty()) + { + for(OccluderList::iterator itr=_occluderList.begin(); + itr!=_occluderList.end(); + ++itr) + { + if (itr->contains(vertices)) return true; + } + } + } + + return false; + } + inline bool isCulled(const BoundingBox& bb) { if (_mask&VIEW_FRUSTUM_CULLING) diff --git a/include/osg/Plane b/include/osg/Plane index 71be37fc3..4890a07ac 100644 --- a/include/osg/Plane +++ b/include/osg/Plane @@ -11,6 +11,8 @@ #include #include +#include + namespace osg { /** A plane class. It can be used to represent an infinite plane.*/ @@ -89,6 +91,35 @@ class SG_EXPORT Plane _fv[3]; } + /** intersection test between plane and vertex list + return 1 if the bs is completely above plane, + return 0 if the bs intersects the plane, + return -1 if the bs is completely below the plane.*/ + inline const int intersect(const std::vector& vertices) const + { + if (vertices.empty()) return -1; + + int noAbove = 0; + int noBelow = 0; + int noOn = 0; + for(std::vector::const_iterator itr=vertices.begin(); + itr != vertices.end(); + ++itr) + { + float d = distance(*itr); + if (d>0.0f) ++noAbove; + else if (d<0.0f) ++noBelow; + else ++noOn; + } + + if (noAbove>0) + { + if (noBelow>0) return 0; + else return 1; + } + return -1; // treat points on line as outside... + } + /** intersection test between plane and bounding sphere. return 1 if the bs is completely above plane, return 0 if the bs intersects the plane, diff --git a/include/osg/Polytope b/include/osg/Polytope index 570add156..310cc1275 100644 --- a/include/osg/Polytope +++ b/include/osg/Polytope @@ -120,6 +120,29 @@ class SG_EXPORT Polytope return true; } + /** Check whether any part of vertex list is contained with clipping set.*/ + inline const bool contains(const std::vector& vertices) + { + if (!_maskStack.back()) return true; + + _resultMask = _maskStack.back(); + ClippingMask selector_mask = 0x1; + + for(PlaneList::const_iterator itr=_planeList.begin(); + itr!=_planeList.end(); + ++itr) + { + if (_resultMask&selector_mask) + { + int res=itr->intersect(vertices); + if (res<0) return false; // outside clipping set. + else if (res>0) _resultMask ^= selector_mask; // subsequent checks against this plane not required. + } + selector_mask <<= 1; + } + return true; + } + /** Check whether any part of a bounding sphere is contained within clipping set. Using a mask to determine which planes should be used for the check, and modifying the mask to turn off planes which wouldn't contribute to clipping @@ -174,6 +197,29 @@ class SG_EXPORT Polytope return true; } + /** Check whether all of vertex list is contained with clipping set.*/ + inline const bool containsAllOf(const std::vector& vertices) + { + if (!_maskStack.back()) return false; + + _resultMask = _maskStack.back(); + ClippingMask selector_mask = 0x1; + + for(PlaneList::const_iterator itr=_planeList.begin(); + itr!=_planeList.end(); + ++itr) + { + if (_resultMask&selector_mask) + { + int res=itr->intersect(vertices); + if (res<1) return false; // intersects, or is below plane. + _resultMask ^= selector_mask; // subsequent checks against this plane not required. + } + selector_mask <<= 1; + } + return true; + } + /** Check whether the entire bounding sphere is contained within clipping set.*/ inline const bool containsAllOf(const osg::BoundingSphere& bs) { diff --git a/include/osg/ShadowOccluderVolume b/include/osg/ShadowVolumeOccluder similarity index 94% rename from include/osg/ShadowOccluderVolume rename to include/osg/ShadowVolumeOccluder index 0f2e813ca..f6ab846ed 100644 --- a/include/osg/ShadowOccluderVolume +++ b/include/osg/ShadowVolumeOccluder @@ -49,6 +49,10 @@ class SG_EXPORT ShadowVolumeOccluder float quality() { return _quality; } + /** return true if the specified vertex list is contaned entirely + * within this shadow occluder volume.*/ + bool contains(const std::vector& vertices); + /** return true if the specified bounding sphere is contaned entirely * within this shadow occluder volume.*/ bool contains(const BoundingSphere& bound); diff --git a/src/osg/CollectOccludersVisitor.cpp b/src/osg/CollectOccludersVisitor.cpp index a640061fe..816b3b8dc 100644 --- a/src/osg/CollectOccludersVisitor.cpp +++ b/src/osg/CollectOccludersVisitor.cpp @@ -100,14 +100,23 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node) // list, if so disable the appropriate ShadowOccluderVolume disableOccluder(_nodePath); - std::cout<<"CollectOccludersVisitor:: We have found an Occlusion node in frustum"<<&node<getOccluder().getVertexList())) + { + + // need to test occluder against view frustum. + std::cout << " adding in Occluder"<& vertices) +{ + if (_occluderVolume.containsAllOf(vertices)) + { + for(HoleList::iterator itr=_holeList.begin(); + itr!=_holeList.end(); + ++itr) + { + if (itr->contains(vertices)) return false; + } + return true; + } + return false; } bool ShadowVolumeOccluder::contains(const BoundingSphere& bound)