diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 3c3238daf..fdf74cbd6 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -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 TransformSet; + TransformSet _transformSet; + }; + /** Remove rendundant nodes, such as groups with one single child.*/ class OSGUTIL_EXPORT RemoveEmptyNodesVisitor : public osg::NodeVisitor { diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 2dd983185..556e18256 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -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"<accept(mgv); - } - - if (options & MERGE_GEOMETRY) - { - osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEOMETRY"<accept(mgv); - } - if (options & COPY_SHARED_NODES) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing COPY_SHARED_NODES"<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"<accept(mgv); + } + if (options & TRISTRIP_GEOMETRY) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing TRISTRIP_GEOMETRY"<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"< 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.