diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 118c476f0..0f1b804c2 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -68,6 +68,7 @@ class OSGUTIL_EXPORT Optimizer REMOVE_LOADED_PROXY_NODES = 0x004, COMBINE_ADJACENT_LODS = 0x008, SHARE_DUPLICATE_STATE = 0x010, + MERGE_GEODES = 0x1000, MERGE_GEOMETRY = 0x020, CHECK_GEOMETRY = 0x040, SPATIALIZE_GROUPS = 0x080, @@ -88,6 +89,7 @@ class OSGUTIL_EXPORT Optimizer REMOVE_LOADED_PROXY_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | + MERGE_GEODES | MERGE_GEOMETRY | CHECK_GEOMETRY | SPATIALIZE_GROUPS | @@ -405,7 +407,27 @@ class OSGUTIL_EXPORT Optimizer StateSetMap _statesets; }; - + + /** Combine geodes + */ + class OSGUTIL_EXPORT MergeGeodesVisitor : public BaseOptimizerVisitor + { + public: + + /// default to traversing all children. + MergeGeodesVisitor(Optimizer* optimizer=0): + BaseOptimizerVisitor(optimizer, MERGE_GEODES) {} + + virtual void apply(osg::Group& group); + + bool mergeGeodes(osg::Group& group); + + protected: + + bool mergeGeode(osg::Geode& lhs, osg::Geode& rhs); + + }; + class OSGUTIL_EXPORT CheckGeometryVisitor : public BaseOptimizerVisitor { public: diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 982689fbd..2a72410a7 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -75,6 +75,9 @@ void Optimizer::optimize(osg::Node* node) if(str.find("~SHARE_DUPLICATE_STATE")!=std::string::npos) options ^= SHARE_DUPLICATE_STATE; else if(str.find("SHARE_DUPLICATE_STATE")!=std::string::npos) options |= SHARE_DUPLICATE_STATE; + if(str.find("~MERGE_GEODES")!=std::string::npos) options ^= MERGE_GEODES; + else if(str.find("MERGE_GEODES")!=std::string::npos) options |= MERGE_GEODES; + if(str.find("~MERGE_GEOMETRY")!=std::string::npos) options ^= MERGE_GEOMETRY; else if(str.find("MERGE_GEOMETRY")!=std::string::npos) options |= MERGE_GEOMETRY; @@ -200,6 +203,13 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) } + if (options & MERGE_GEODES) + { + osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEODES"<accept(visitor); + } if (options & CHECK_GEOMETRY) { @@ -2482,3 +2492,80 @@ void Optimizer::TextureVisitor::apply(osg::Texture& texture) } } + +//////////////////////////////////////////////////////////////////////////// +// Merge geodes +//////////////////////////////////////////////////////////////////////////// + +void Optimizer::MergeGeodesVisitor::apply(osg::Group& group) +{ + mergeGeodes(group); + traverse(group); +} + +struct LessGeode +{ + bool operator() (const osg::Geode* lhs,const osg::Geode* rhs) const + { + if (lhs->getStateSet()getStateSet()) return true; + return false; + } +}; + +bool Optimizer::MergeGeodesVisitor::mergeGeodes(osg::Group& group) +{ + if (!isOperationPermissibleForObject(&group)) return false; + + typedef std::vector DuplicateList; + typedef std::map GeodeDuplicateMap; + + GeodeDuplicateMap geodeDuplicateMap; + + for (unsigned int i=0; isecond.size()>1) + { + osg::Geode* lhs = itr->second[0]; + for(DuplicateList::iterator dupItr=itr->second.begin()+1; + dupItr!=itr->second.end(); + ++dupItr) + { + osg::Geode* rhs = *dupItr; + + if (mergeGeode(*lhs,*rhs)) + { + group.removeChild(rhs); + + static int co = 0; + osg::notify(osg::INFO)<<"merged and removed Geode "<<++co<