From 27412c27c91fb7e5ab77b8b51483921ceffa97db Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 17 Jun 2002 09:10:26 +0000 Subject: [PATCH] Fixes to the occluder culling code to properly disable occluders to prevent self occlusion. --- include/osg/CullStack | 9 ++- include/osg/CullingSet | 4 +- include/osg/Polytope | 8 ++- include/osg/ShadowVolumeOccluder | 3 + src/Demos/osgoccluder/osgoccluder.cpp | 92 +++++++++++++++------------ src/osg/CollectOccludersVisitor.cpp | 17 +++-- src/osg/CullingSet.cpp | 38 ++++++++++- src/osg/ShadowVolumeOccluder.cpp | 18 +++++- src/osgUtil/CullVisitor.cpp | 13 ++-- src/osgUtil/SceneView.cpp | 10 ++- 10 files changed, 151 insertions(+), 61 deletions(-) diff --git a/include/osg/CullStack b/include/osg/CullStack index 1ea08d5af..66697295c 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -85,9 +85,14 @@ class SG_EXPORT CullStack return pixelSize(bs.center(),bs.radius()); } - inline void disableOccluder(NodePath& nodePath) + inline void disableAndPushOccludersCurrentMask(NodePath& nodePath) { - _modelviewCullingStack.back()->disableOccluder(nodePath); + _modelviewCullingStack.back()->disableAndPushOccludersCurrentMask(nodePath); + } + + inline void popOccludersCurrentMask(NodePath& nodePath) + { + _modelviewCullingStack.back()->popOccludersCurrentMask(nodePath); } inline bool isCulled(const std::vector& vertices) diff --git a/include/osg/CullingSet b/include/osg/CullingSet index bbc220f3e..21a71151d 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -77,7 +77,6 @@ class SG_EXPORT CullingSet : public Referenced /** Compute the pixel of an bounding sphere.*/ float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); } - void disableOccluder(NodePath& nodePath); inline bool isCulled(const std::vector& vertices) { @@ -197,6 +196,9 @@ class SG_EXPORT CullingSet : public Referenced } } + void disableAndPushOccludersCurrentMask(NodePath& nodePath); + + void popOccludersCurrentMask(NodePath& nodePath); protected: diff --git a/include/osg/Polytope b/include/osg/Polytope index e601c901e..cf2c29ab3 100644 --- a/include/osg/Polytope +++ b/include/osg/Polytope @@ -19,7 +19,8 @@ class SG_EXPORT Polytope public: typedef unsigned int ClippingMask; - typedef std::vector PlaneList; + typedef std::vector PlaneList; + typedef fast_back_stack MaskStack; inline Polytope() {setupMask();} @@ -94,6 +95,9 @@ class SG_EXPORT Polytope inline ClippingMask getResultMask() const { return _resultMask; } + MaskStack& getMaskStack() { return _maskStack; } + + const MaskStack& getMaskStack() const { return _maskStack; } inline void pushCurrentMask() @@ -305,7 +309,7 @@ class SG_EXPORT Polytope protected: - fast_back_stack _maskStack; + MaskStack _maskStack; ClippingMask _resultMask; PlaneList _planeList; diff --git a/include/osg/ShadowVolumeOccluder b/include/osg/ShadowVolumeOccluder index 33266c7e5..f85c5fa39 100644 --- a/include/osg/ShadowVolumeOccluder +++ b/include/osg/ShadowVolumeOccluder @@ -103,6 +103,7 @@ typedef std::vector ShadowVolumeOccluderList; inline void ShadowVolumeOccluder::disableResultMasks() { + //std::cout<<"ShadowVolumeOccluder::disableResultMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<popCurrentMask(); } } + //std::cout<<"ShadowVolumeOccluder::popCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<setName("rootgroup"); - - - // add the loaded model into a the scene group. - scene->addChild(model); - model->setName("model"); - - - // create and occluder which will site along side the loadmodel model. + // create and occluder which will site along side the loadmodel model. osg::OccluderNode* occluderNode = osgNew osg::OccluderNode; - // get the bounding volume of the model. - const osg::BoundingSphere bs = model->getBound(); - - // create a bounding box around the sphere. - osg::BoundingBox bb; - bb.expandBy(bs); - // create the convex planer occluder osg::ConvexPlanerOccluder* cpo = osgNew osg::ConvexPlanerOccluder; @@ -84,25 +66,11 @@ osg::Node* createOccludersAroundModel(osg::Node* model) // set the occluder up for the front face of the bounding box. osg::ConvexPlanerPolygon& occluder = cpo->getOccluder(); - occluder.add(osg::Vec3(bb.xMin(),bb.yMin(),bb.zMin())); - occluder.add(osg::Vec3(bb.xMax(),bb.yMin(),bb.zMin())); - occluder.add(osg::Vec3(bb.xMax(),bb.yMin(),bb.zMax())); - occluder.add(osg::Vec3(bb.xMin(),bb.yMin(),bb.zMax())); - -// -// // create a hole in the occluder. -// osg::Vec3 center((bb.xMin()+bb.xMax())*0.5f,bb.yMin(),(bb.zMin()+bb.zMax())*0.5f); -// float dx = (bb.xMax()-bb.xMin())*0.25f; -// float dz = (bb.zMax()-bb.zMin())*0.25f; -// -// -// cpo->getHoleList().push_back(); -// osg::ConvexPlanerPolygon& hole = cpo->getHoleList().back(); -// hole.add(center+osg::Vec3(-dx,0.0,-dz)); -// hole.add(center+osg::Vec3(dx,0.0,-dz)); -// hole.add(center+osg::Vec3(dx,0.0,dz)); -// hole.add(center+osg::Vec3(-dx,0.0,dz)); - + occluder.add(v1); + occluder.add(v2); + occluder.add(v3); + occluder.add(v4); + // create a drawable for occluder. osg::GeoSet* geoset = osgNew osg::GeoSet; @@ -134,8 +102,50 @@ osg::Node* createOccludersAroundModel(osg::Node* model) // geode will never be occluder by this occluder. occluderNode->addChild(geode); - // add the occluder node into the scene. - scene->addChild(occluderNode); + return occluderNode; + + } + +osg::Node* createOccludersAroundModel(osg::Node* model) +{ + osg::Group* scene = osgNew osg::Group; + scene->setName("rootgroup"); + + + // add the loaded model into a the scene group. + scene->addChild(model); + model->setName("model"); + + // get the bounding volume of the model. + const osg::BoundingSphere bs = model->getBound(); + + // create a bounding box around the sphere. + osg::BoundingBox bb; + bb.expandBy(bs); + + // front + scene->addChild(createOccluder(bb.corner(0), + bb.corner(1), + bb.corner(5), + bb.corner(4))); + + // right side + scene->addChild(createOccluder(bb.corner(1), + bb.corner(3), + bb.corner(7), + bb.corner(5))); + + // left side + scene->addChild(createOccluder(bb.corner(2), + bb.corner(0), + bb.corner(4), + bb.corner(6))); + + // back side + scene->addChild(createOccluder(bb.corner(3), + bb.corner(2), + bb.corner(6), + bb.corner(7))); return scene; } diff --git a/src/osg/CollectOccludersVisitor.cpp b/src/osg/CollectOccludersVisitor.cpp index ece017a14..787198c38 100644 --- a/src/osg/CollectOccludersVisitor.cpp +++ b/src/osg/CollectOccludersVisitor.cpp @@ -17,7 +17,7 @@ CollectOccludersVisitor::CollectOccludersVisitor() FAR_PLANE_CULLING| SMALL_FEATURE_CULLING); - _minimumShadowOccluderVolume = 0.01f; + _minimumShadowOccluderVolume = 0.005f; _createDrawables = false; } @@ -107,10 +107,14 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node) { // need to check if occlusion node is in the occluder // list, if so disable the appropriate ShadowOccluderVolume - disableOccluder(_nodePath); + disableAndPushOccludersCurrentMask(_nodePath); - if (isCulled(node)) return; + if (isCulled(node)) + { + popOccludersCurrentMask(_nodePath); + return; + } // std::cout<<"CollectOccludersVisitor:: We have found an Occlusion node in frustum"<<&node<_minimumShadowOccluderVolume) { // need to test occluder against view frustum. - std::cout << " adding in Occluder"<getNodePath());std::cout<getNodePath()==nodePath) { - //std::cout<<" ++ disabling occluder"<disableResultMasks(); + itr->pushCurrentMask(); } } } + +void CullingSet::popOccludersCurrentMask(NodePath& nodePath) +{ + //std::cout<<" trying to pop occluder ";PrintNodePath(nodePath);std::cout<getNodePath());std::cout<getNodePath()==nodePath) + { + //std::cout<<" popping occluder "<popCurrentMask(); + } + } +} diff --git a/src/osg/ShadowVolumeOccluder.cpp b/src/osg/ShadowVolumeOccluder.cpp index 433e18a2a..5006eb451 100644 --- a/src/osg/ShadowVolumeOccluder.cpp +++ b/src/osg/ShadowVolumeOccluder.cpp @@ -396,30 +396,44 @@ bool ShadowVolumeOccluder::contains(const std::vector& vertices) bool ShadowVolumeOccluder::contains(const BoundingSphere& bound) { + //std::cout << "Sphere testing occluder "<reset(); @@ -333,7 +341,7 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil cov.popProjectionMatrix(); cov.popViewport(); - // std::cout << "finished searching for occluder"<setOccluderList(cov.getCollectedOccluderList()); }