Added code for combining adjacent static MatrixTransforms

This commit is contained in:
Robert Osfield
2003-12-05 14:39:32 +00:00
parent 1046c73731
commit 3f14b9a653
2 changed files with 102 additions and 19 deletions

View File

@@ -105,12 +105,27 @@ class OSGUTIL_EXPORT Optimizer
DrawableSet _drawableSet;
BillboardSet _billboardSet;
TransformSet _transformSet;
};
/** Combine Static Trasform nodes that sit above on another.*/
class OSGUTIL_EXPORT CombineStaticTransformsVisitor : public osg::NodeVisitor
{
public:
CombineStaticTransformsVisitor():
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::MatrixTransform& transform);
bool removeTransforms(osg::Node* nodeWeCannotRemove);
protected:
typedef std::set<osg::MatrixTransform*> TransformSet;
TransformSet _transformSet;
};
/** Remove rendundant nodes, such as groups with one single child.*/
class OSGUTIL_EXPORT RemoveEmptyNodesVisitor : public osg::NodeVisitor
{

View File

@@ -116,22 +116,6 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
osv.optimize();
}
if (options & CHECK_GEOMETRY)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing CHECK_GEOMETRY"<<std::endl;
CheckGeometryVisitor mgv;
node->accept(mgv);
}
if (options & MERGE_GEOMETRY)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEOMETRY"<<std::endl;
MergeGeometryVisitor mgv;
node->accept(mgv);
}
if (options & COPY_SHARED_NODES)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing COPY_SHARED_NODES"<<std::endl;
@@ -156,6 +140,11 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
++i;
} while (result);
// no combine any adjacent static transforms.
CombineStaticTransformsVisitor cstv;
node->accept(cstv);
cstv.removeTransforms(node);
}
@@ -182,6 +171,14 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
sv.divide();
}
if (options & CHECK_GEOMETRY)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing CHECK_GEOMETRY"<<std::endl;
CheckGeometryVisitor mgv;
node->accept(mgv);
}
if (options & TRISTRIP_GEOMETRY)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing TRISTRIP_GEOMETRY"<<std::endl;
@@ -191,6 +188,14 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
tsv.stripify();
}
if (options & MERGE_GEOMETRY)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEOMETRY"<<std::endl;
MergeGeometryVisitor mgv;
node->accept(mgv);
}
}
@@ -868,6 +873,69 @@ bool Optimizer::FlattenStaticTransformsVisitor::removeTransforms(osg::Node* node
return cltv.removeTransforms(nodeWeCannotRemove);
}
////////////////////////////////////////////////////////////////////////////
// RemoveEmptyNodes.
////////////////////////////////////////////////////////////////////////////
void Optimizer::CombineStaticTransformsVisitor::apply(osg::MatrixTransform& transform)
{
if (transform.getDataVariance()==osg::Object::STATIC &&
transform.getNumChildren()==1 &&
transform.getChild(0)->asTransform()!=0 &&
transform.getChild(0)->asTransform()->asMatrixTransform()!=0 &&
transform.getChild(0)->asTransform()->getDataVariance()==osg::Object::STATIC)
{
_transformSet.insert(&transform);
}
traverse(transform);
}
bool Optimizer::CombineStaticTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRemove)
{
if (nodeWeCannotRemove && nodeWeCannotRemove->asTransform()!=0 && nodeWeCannotRemove->asTransform()->asMatrixTransform()!=0)
{
// remove topmost node if it exists in the transform set.
TransformSet::iterator itr = _transformSet.find(nodeWeCannotRemove->asTransform()->asMatrixTransform());
if (itr!=_transformSet.end()) _transformSet.erase(itr);
}
std::cout<<"Have found "<<_transformSet.size()<<" static Transform pairs to flatten"<<std::endl;
bool transformRemoved = false;
while (!_transformSet.empty())
{
// get the first available transform to combine.
osg::ref_ptr<osg::MatrixTransform> transform = *_transformSet.begin();
_transformSet.erase(_transformSet.begin());
if (transform->getNumChildren()==1 &&
transform->getChild(0)->asTransform()!=0 &&
transform->getChild(0)->asTransform()->asMatrixTransform()!=0 &&
transform->getChild(0)->asTransform()->getDataVariance()==osg::Object::STATIC)
{
// now combine with its child.
osg::MatrixTransform* child = transform->getChild(0)->asTransform()->asMatrixTransform();
osg::Matrix newMatrix = child->getMatrix()*transform->getMatrix();
child->setMatrix(newMatrix);
transformRemoved = true;
osg::Node::ParentList parents = transform->getParents();
for(osg::Node::ParentList::iterator pitr=parents.begin();
pitr!=parents.end();
++pitr)
{
(*pitr)->replaceChild(transform.get(),child);
}
}
}
return transformRemoved;
}
////////////////////////////////////////////////////////////////////////////
// RemoveEmptyNodes.