From 6691824244538ce096956b94668a0754ab877785 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 13 Apr 2008 19:31:09 +0000 Subject: [PATCH] Added subdivision of Goedes --- include/osgUtil/Optimizer | 4 +++ src/osgUtil/Optimizer.cpp | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 709401360..0dbd9c48a 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -504,14 +504,18 @@ class OSGUTIL_EXPORT Optimizer BaseOptimizerVisitor(optimizer, SPATIALIZE_GROUPS) {} virtual void apply(osg::Group& group); + virtual void apply(osg::Geode& geode); bool divide(unsigned int maxNumTreesPerCell=8); bool divide(osg::Group* group, unsigned int maxNumTreesPerCell); + bool divide(osg::Geode* geode, unsigned int maxNumTreesPerCell); typedef std::set GroupsToDivideList; GroupsToDivideList _groupsToDivideList; + typedef std::set GeodesToDivideList; + GeodesToDivideList _geodesToDivideList; }; /** Copy any shared subgraphs, enabling flattening of static transforms.*/ diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index ae2d0343f..375ec856b 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -2530,6 +2530,18 @@ void Optimizer::SpatializeGroupsVisitor::apply(osg::Group& group) traverse(group); } +void Optimizer::SpatializeGroupsVisitor::apply(osg::Geode& geode) +{ + if (typeid(geode)==typeid(osg::Geode)) + { + if (isOperationPermissibleForObject(&geode)) + { + _geodesToDivideList.insert(&geode); + } + } + traverse(geode); +} + bool Optimizer::SpatializeGroupsVisitor::divide(unsigned int maxNumTreesPerCell) { bool divided = false; @@ -2539,6 +2551,14 @@ bool Optimizer::SpatializeGroupsVisitor::divide(unsigned int maxNumTreesPerCell) { if (divide(*itr,maxNumTreesPerCell)) divided = true; } + + for(GeodesToDivideList::iterator geode_itr=_geodesToDivideList.begin(); + geode_itr!=_geodesToDivideList.end(); + ++geode_itr) + { + if (divide(*geode_itr,maxNumTreesPerCell)) divided = true; + } + return divided; } @@ -2709,6 +2729,62 @@ bool Optimizer::SpatializeGroupsVisitor::divide(osg::Group* group, unsigned int } +bool Optimizer::SpatializeGroupsVisitor::divide(osg::Geode* geode, unsigned int maxNumTreesPerCell) +{ + + if (geode->getNumDrawables()<=maxNumTreesPerCell) return false; + + // create the original box. + osg::BoundingBox bb; + unsigned int i; + for(i=0; igetNumDrawables(); ++i) + { + bb.expandBy(geode->getDrawable(i)->getBound().center()); + } + + float radius = bb.radius(); + float divide_distance = radius*0.7f; + bool xAxis = (bb.xMax()-bb.xMin())>divide_distance; + bool yAxis = (bb.yMax()-bb.yMin())>divide_distance; + bool zAxis = (bb.zMax()-bb.zMin())>divide_distance; + + osg::notify(osg::NOTICE)<<"INFO "<className()<<" num drawables = "<getNumDrawables()<<" xAxis="<getParents(); + if (parents.empty()) + { + osg::notify(osg::INFO)<<" Cannot perform spatialize on root Geode, add a Group above it to allow subdivision."< group = new osg::Group; + for(i=0; igetNumDrawables(); ++i) + { + osg::Geode* newGeode = new osg::Geode; + newGeode->addDrawable(geode->getDrawable(i)); + group->addChild(newGeode); + } + + divide(group.get(), maxNumTreesPerCell); + + // keep reference around to prevent it being deleted. + osg::ref_ptr keepRefGeode = geode; + + for(osg::Node::ParentList::iterator itr = parents.begin(); + itr != parents.end(); + ++itr) + { + (*itr)->replaceChild(geode, group.get()); + } + + return true; +} //////////////////////////////////////////////////////////////////////////////////////////// //