From Brede Johansen, added MergeGeode visitor to osgUtil::Optimizer.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user