From Brede Johansen, added MergeGeode visitor to osgUtil::Optimizer.

This commit is contained in:
Robert Osfield
2006-04-06 14:06:22 +00:00
parent 051f2a5eb9
commit 761a3b43ac
3 changed files with 118 additions and 1 deletions

View File

@@ -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:

View File

@@ -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"<<std::endl;
MergeGeodesVisitor visitor;
node->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()<rhs->getStateSet()) return true;
return false;
}
};
bool Optimizer::MergeGeodesVisitor::mergeGeodes(osg::Group& group)
{
if (!isOperationPermissibleForObject(&group)) return false;
typedef std::vector<osg::Geode*> DuplicateList;
typedef std::map<osg::Geode*,DuplicateList,LessGeode> GeodeDuplicateMap;
GeodeDuplicateMap geodeDuplicateMap;
for (unsigned int i=0; i<group.getNumChildren(); ++i)
{
osg::Node* child = group.getChild(i);
if (typeid(*child)==typeid(osg::Geode))
{
osg::Geode* geode = (osg::Geode*)child;
geodeDuplicateMap[geode].push_back(geode);
}
}
// merge
for(GeodeDuplicateMap::iterator itr=geodeDuplicateMap.begin();
itr!=geodeDuplicateMap.end();
++itr)
{
if (itr->second.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<<std::endl;
}
}
}
}
return true;
}
bool Optimizer::MergeGeodesVisitor::mergeGeode(osg::Geode& lhs, osg::Geode& rhs)
{
for (unsigned int i=0; i<rhs.getNumDrawables(); ++i)
{
lhs.addDrawable(rhs.getDrawable(i));
}
return true;
}

View File

@@ -47,6 +47,7 @@ BEGIN_ENUM_REFLECTOR(osgUtil::Optimizer::OptimizationOptions)
I_EnumLabel(osgUtil::Optimizer::REMOVE_LOADED_PROXY_NODES);
I_EnumLabel(osgUtil::Optimizer::COMBINE_ADJACENT_LODS);
I_EnumLabel(osgUtil::Optimizer::SHARE_DUPLICATE_STATE);
I_EnumLabel(osgUtil::Optimizer::MERGE_GEODES);
I_EnumLabel(osgUtil::Optimizer::MERGE_GEOMETRY);
I_EnumLabel(osgUtil::Optimizer::CHECK_GEOMETRY);
I_EnumLabel(osgUtil::Optimizer::SPATIALIZE_GROUPS);
@@ -132,6 +133,13 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::Optimizer::IsOperationPermissibleForObjectCallba
I_Method3(bool, isOperationPermissibleForObjectImplementation, IN, const osgUtil::Optimizer *, optimizer, IN, const osg::Node *, node, IN, unsigned int, option);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgUtil::Optimizer::MergeGeodesVisitor)
I_BaseType(osgUtil::BaseOptimizerVisitor);
I_ConstructorWithDefaults1(IN, osgUtil::Optimizer *, optimizer, 0);
I_Method1(void, apply, IN, osg::Group &, group);
I_Method1(bool, mergeGeodes, IN, osg::Group &, group);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgUtil::Optimizer::MergeGeometryVisitor)
I_BaseType(osgUtil::BaseOptimizerVisitor);
I_ConstructorWithDefaults1(IN, osgUtil::Optimizer *, optimizer, 0);