From ef9595e73a976ca08c6c3ef6ce4fe21f9244f8d7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 23 Nov 2006 17:29:43 +0000 Subject: [PATCH] Add compute of tight bounding box to enable better placement of the base plane. --- examples/osgshadow/osgshadow.cpp | 92 ++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/examples/osgshadow/osgshadow.cpp b/examples/osgshadow/osgshadow.cpp index b692fb57f..2c2579763 100644 --- a/examples/osgshadow/osgshadow.cpp +++ b/examples/osgshadow/osgshadow.cpp @@ -7,6 +7,90 @@ #include +class ComputeBoundingBoxVisitor : public osg::NodeVisitor +{ +public: + ComputeBoundingBoxVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) + { + } + + virtual void reset() + { + _matrixStack.clear(); + _bb.init(); + } + + osg::BoundingBox& getBoundingBox() { return _bb; } + + void apply(osg::Node& node) + { + traverse(node); + } + + void apply(osg::Transform& transform) + { + osg::Matrix matrix; + if (!_matrixStack.empty()) matrix = _matrixStack.back(); + + transform.computeLocalToWorldMatrix(matrix,this); + + pushMatrix(matrix); + + traverse(transform); + + popMatrix(); + } + + void apply(osg::Geode& geode) + { + for(unsigned int i=0; igetBound()); + else + { + osg::Matrix& matrix = _matrixStack.back(); + const osg::BoundingBox& dbb = drawable->getBound(); + if (dbb.valid()) + { + _bb.expandBy(dbb.corner(0) * matrix); + _bb.expandBy(dbb.corner(1) * matrix); + _bb.expandBy(dbb.corner(2) * matrix); + _bb.expandBy(dbb.corner(3) * matrix); + _bb.expandBy(dbb.corner(4) * matrix); + _bb.expandBy(dbb.corner(5) * matrix); + _bb.expandBy(dbb.corner(6) * matrix); + _bb.expandBy(dbb.corner(7) * matrix); + } + } + } + +protected: + + typedef std::vector MatrixStack; + + MatrixStack _matrixStack; + osg::BoundingBox _bb; +}; + + + int main(int argc, char** argv) { // use an ArgumentParser object to manage the program arguments. @@ -53,8 +137,10 @@ int main(int argc, char** argv) return 1; } - const osg::BoundingSphere& bs = model->getBound(); - osg::Plane basePlane(0.0, 0.0, 1.0, -( bs.center().z() - bs.radius() ) ); + 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; @@ -64,7 +150,7 @@ int main(int argc, char** argv) //geode->addDrawable(occluder.get()); osg::ref_ptr shadowVolume = new osgShadow::ShadowVolumeGeometry; - occluder->comptueShadowVolumeGeometry(osg::Vec4(0.0f,-.5f,-1.0f,0.0f), *shadowVolume); + occluder->comptueShadowVolumeGeometry(osg::Vec4(0.5f,-.5f,-1.0f,0.0f), *shadowVolume); geode->addDrawable(shadowVolume.get());