From 5044a85c9ef4b9c1267ea18023db69aa7ec5a1f6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 24 Nov 2006 17:20:01 +0000 Subject: [PATCH] Improved handling of bounding polytope --- examples/osgshadow/osgshadow.cpp | 31 +++++++++++---- include/osg/Plane | 8 ++++ src/osgShadow/OccluderGeometry.cpp | 64 ++++++++++++++++++++++++------ 3 files changed, 82 insertions(+), 21 deletions(-) diff --git a/examples/osgshadow/osgshadow.cpp b/examples/osgshadow/osgshadow.cpp index 1f17fbe94..2bd201283 100644 --- a/examples/osgshadow/osgshadow.cpp +++ b/examples/osgshadow/osgshadow.cpp @@ -22,6 +22,19 @@ public: } osg::BoundingBox& getBoundingBox() { return _bb; } + + void getPolytope(osg::Polytope& polytope, float margin=0.1) const + { + float delta = _bb.radius()*margin; + polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) ); + polytope.add( osg::Plane(0.0, 0.0, -1.0, (_bb.zMax()+delta)) ); + + polytope.add( osg::Plane(1.0, 0.0, 0.0, -(_bb.xMin()-delta)) ); + polytope.add( osg::Plane(-1.0, 0.0, 0.0, (_bb.xMax()+delta)) ); + + polytope.add( osg::Plane(0.0, 1.0, 0.0, -(_bb.yMin()-delta)) ); + polytope.add( osg::Plane(0.0, -1.0, 0.0, (_bb.yMax()+delta)) ); + } void apply(osg::Node& node) { @@ -137,24 +150,26 @@ int main(int argc, char** argv) return 1; } - ComputeBoundingBoxVisitor cbbv; - model->accept(cbbv); - const osg::BoundingBox& bb = cbbv.getBoundingBox(); - osg::Plane basePlane(0.0, 0.0, 1.0, -bb.zMin() ); osg::ref_ptr geode = new osg::Geode; osg::ref_ptr occluder = new osgShadow::OccluderGeometry; occluder->computeOccluderGeometry(model.get()); - occluder->getBoundingPolytope().add(basePlane); + + ComputeBoundingBoxVisitor cbbv; + model->accept(cbbv); + cbbv.getPolytope(occluder->getBoundingPolytope(),0.001); + osg::BoundingBox bb = cbbv.getBoundingBox(); + //geode->addDrawable(occluder.get()); osg::ref_ptr shadowVolume = new osgShadow::ShadowVolumeGeometry; -#if 0 - occluder->comptueShadowVolumeGeometry(osg::Vec4(bb.xMin(), bb.yMin(), bb.zMax() + bb.radius() ,1.0f), *shadowVolume); +#if 1 +// occluder->comptueShadowVolumeGeometry(osg::Vec4(bb.xMin()+ bb.radius(), bb.yMin()+ bb.radius(), bb.zMax() + bb.radius() ,1.0f), *shadowVolume); + occluder->comptueShadowVolumeGeometry(osg::Vec4(bb.center().x(), bb.center().y(), bb.zMax() + bb.radius() ,1.0f), *shadowVolume); #else - occluder->comptueShadowVolumeGeometry(osg::Vec4(0.5f,-.5f,-1.0f,0.0f), *shadowVolume); + occluder->comptueShadowVolumeGeometry(osg::Vec4(0.5f,.25f,0.2f,0.0f), *shadowVolume); #endif geode->addDrawable(shadowVolume.get()); diff --git a/include/osg/Plane b/include/osg/Plane index 51bdb4f36..4acaf2320 100644 --- a/include/osg/Plane +++ b/include/osg/Plane @@ -123,6 +123,14 @@ class OSG_EXPORT Plane _fv[3]; } + /** calculate the dot product of the plane normal and a point.*/ + inline float dotProductNormal(const osg::Vec3& v) const + { + return _fv[0]*v.x()+ + _fv[1]*v.y()+ + _fv[2]*v.z(); + } + /** intersection test between plane and vertex list return 1 if the bs is completely above plane, return 0 if the bs intersects the plane, diff --git a/src/osgShadow/OccluderGeometry.cpp b/src/osgShadow/OccluderGeometry.cpp index 437f935cd..a3b4a5cbe 100644 --- a/src/osgShadow/OccluderGeometry.cpp +++ b/src/osgShadow/OccluderGeometry.cpp @@ -743,15 +743,15 @@ void OccluderGeometry::comptueShadowVolumeGeometry(const osg::Vec4& lightpos, Sh ShadowVolumeGeometry::Vec3List& shadowNormals = svg.getNormals(); shadowNormals.clear(); - osg::Plane basePlane(0.0, 0.0, 1.0, 0.0); - - const osg::Polytope::PlaneList& planes = _boundingPolytope.getPlaneList(); - - if (!planes.empty()) + + // need to have some kind of handling of case when no planes exist. + if (_boundingPolytope.getPlaneList().empty()) { - basePlane = planes[0]; + osg::notify(osg::NOTICE)<<"Warning: no bounding polytope registered with OccluderGeometry."< pitr->dotProductNormal(lightdirection)) + { + basePlane = *pitr; + } + } + // compute the silhouette edge UIntList silhouetteIndices; computeLightDirectionSlihouetteEdges(lightdirection, silhouetteIndices); osg::Vec3 offset( lightdirection*5.0f ); - float directionScale = 1.0f / (basePlane.getNormal() * lightdirection); + float directionScale = 1.0f / basePlane.dotProductNormal(lightdirection); for(UIntList::iterator itr = silhouetteIndices.begin(); itr != silhouetteIndices.end(); @@ -799,10 +815,16 @@ void OccluderGeometry::comptueShadowVolumeGeometry(const osg::Vec4& lightpos, Sh // positional light osg::Vec3 lightposition( lightpos.x(), lightpos.y(), lightpos.z()); + osg::Plane basePlane(0.0, 0.0, 1.0, 0.0); + osg::notify(osg::NOTICE)<<"Positional light"<