optimizer: merge groups as part of REMOVE_REDUNDANT_NODES

coverity_scan^2
scrawl 8 years ago
parent af716d4b61
commit f2a323238f

@ -109,6 +109,8 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
node->accept(rrnv); node->accept(rrnv);
rrnv.removeRedundantNodes(); rrnv.removeRedundantNodes();
MergeGroupsVisitor mgrp(this);
node->accept(mgrp);
} }
if (options & VERTEX_POSTTRANSFORM) if (options & VERTEX_POSTTRANSFORM)
@ -1807,4 +1809,55 @@ bool Optimizer::MergeGeometryVisitor::mergePrimitive(osg::DrawElementsUInt& lhs,
return true; return true;
} }
bool Optimizer::MergeGroupsVisitor::isOperationPermissible(osg::Group& node)
{
return !node.asTransform() &&
!node.getCullCallback() &&
!node.getEventCallback() &&
!node.getUpdateCallback() &&
isOperationPermissibleForObject(&node);
}
void Optimizer::MergeGroupsVisitor::apply(osg::Group &group)
{
if (group.getNumChildren() <= 1)
traverse(group);
else
{
typedef std::map<osg::StateSet*, std::set<osg::Group*> > GroupMap;
GroupMap childGroups;
for (unsigned int i=0; i<group.getNumChildren(); ++i)
{
osg::Node* child = group.getChild(i);
osg::Group* childGroup = child->asGroup();
if (childGroup && isOperationPermissible(*childGroup))
{
childGroups[childGroup->getStateSet()].insert(childGroup);
}
}
for (GroupMap::iterator it = childGroups.begin(); it != childGroups.end(); ++it)
{
const std::set<osg::Group*>& groupSet = it->second;
if (groupSet.size() <= 1)
continue;
else
{
osg::Group* first = *groupSet.begin();
for (std::set<osg::Group*>::const_iterator groupIt = ++groupSet.begin(); groupIt != groupSet.end(); ++groupIt)
{
osg::Group* toMerge = *groupIt;
for (unsigned int i=0; i<toMerge->getNumChildren(); ++i)
first->addChild(toMerge->getChild(i));
toMerge->removeChildren(0, toMerge->getNumChildren());
group.removeChild(toMerge);
}
}
}
traverse(group);
}
}
} }

@ -346,6 +346,20 @@ class Optimizer
}; };
/** Merge adjacent Groups that have the same StateSet. */
class MergeGroupsVisitor : public SceneUtil::BaseOptimizerVisitor
{
public:
MergeGroupsVisitor(SceneUtil::Optimizer* optimizer)
: BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES)
{
}
bool isOperationPermissible(osg::Group& node);
virtual void apply(osg::Group& group);
};
class MergeGeometryVisitor : public BaseOptimizerVisitor class MergeGeometryVisitor : public BaseOptimizerVisitor
{ {
public: public:

Loading…
Cancel
Save