From a918306a99fa1d41acd01d280427908b532f247d Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 24 Feb 2017 01:00:49 +0100 Subject: [PATCH 1/5] Use asDrawable()/asNode() over dynamic_cast in the Optimizer --- src/osgUtil/Optimizer.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index b3ae72f07..beb38209c 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -757,12 +757,15 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor inline bool isOperationPermissibleForObject(const osg::Object* object) const { - const osg::Drawable* drawable = dynamic_cast(object); - if (drawable) return isOperationPermissibleForObject(drawable); - - const osg::Node* node = dynamic_cast(object); - if (node) return isOperationPermissibleForObject(node); - + const osg::Node* node = object->asNode(); + if (node) + { + const osg::Drawable* drawable = node->asDrawable(); + if (drawable) + return isOperationPermissibleForObject(drawable); + else + return isOperationPermissibleForObject(node); + } return true; } @@ -872,7 +875,10 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& matrix) { - osg::Drawable* drawable = dynamic_cast(obj); + osg::Node* node = obj->asNode(); + if (!node) + return; + osg::Drawable* drawable = node->asDrawable(); if (drawable) { osgUtil::TransformAttributeFunctor tf(matrix); @@ -1072,11 +1078,11 @@ bool CollectLowestTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRem } else { - osg::MatrixTransform* mt = dynamic_cast(titr->first); + osg::MatrixTransform* mt = titr->first->asMatrixTransform(); if (mt) mt->setMatrix(osg::Matrix::identity()); else { - osg::PositionAttitudeTransform* pat = dynamic_cast(titr->first); + osg::PositionAttitudeTransform* pat = titr->first->asPositionAttitudeTransform(); if (pat) { pat->setPosition(osg::Vec3(0.0f,0.0f,0.0f)); @@ -1279,7 +1285,7 @@ void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group) { // only remove empty groups, but not empty occluders. if (group.getNumChildren()==0 && isOperationPermissibleForObject(&group) && - (typeid(group)==typeid(osg::Group) || (dynamic_cast(&group) && !dynamic_cast(&group))) && + (typeid(group)==typeid(osg::Group) || (group.asTransform() && !dynamic_cast(&group))) && (group.getNumChildrenRequiringUpdateTraversal()==0 && group.getNumChildrenRequiringEventTraversal()==0) ) { _redundantNodeList.insert(&group); @@ -1380,7 +1386,7 @@ void Optimizer::RemoveRedundantNodesVisitor::removeRedundantNodes() itr!=_redundantNodeList.end(); ++itr) { - osg::ref_ptr group = dynamic_cast(*itr); + osg::ref_ptr group = (*itr)->asGroup(); if (group.valid()) { // take a copy of parents list since subsequent removes will modify the original one. @@ -2038,7 +2044,7 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) unsigned int i; for(i=0;i(geode.getDrawable(i)); + osg::Geometry* geom = geode.getDrawable(i)->asGeometry(); if (geom) { osg::Geometry::PrimitiveSetList& primitives = geom->getPrimitiveSetList(); @@ -2065,7 +2071,7 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) // now merge any compatible primitives. for(i=0;i(geode.getDrawable(i)); + osg::Geometry* geom = geode.getDrawable(i)->asGeometry(); if (geom) { if (geom->getNumPrimitiveSets()>0 && From e0f7d3241af56751fa8e70922c1a17511aeb16cc Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 24 Feb 2017 01:05:57 +0100 Subject: [PATCH 2/5] Fix MergeGeometryVisitor to work with a Group instead of Geode --- include/osgUtil/Optimizer | 4 +-- src/osgUtil/Optimizer.cpp | 55 ++++++++++++--------------------------- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 6a6f09305..a4c52ccd2 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -532,10 +532,10 @@ class OSGUTIL_EXPORT Optimizer return _targetMaximumNumberOfVertices; } - virtual void apply(osg::Geode& geode) { mergeGeode(geode); } + virtual void apply(osg::Group& group) { mergeGroup(group); traverse(group); } virtual void apply(osg::Billboard&) { /* don't do anything*/ } - bool mergeGeode(osg::Geode& geode); + bool mergeGroup(osg::Group& group); static bool geometryContainsSharedArrays(osg::Geometry& geom); diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index beb38209c..f4ea29fde 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1782,15 +1782,13 @@ bool isAbleToMerge(const osg::Geometry& g1, const osg::Geometry& g2) return true; } -bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) +bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group) { - if (!isOperationPermissibleForObject(&geode)) return false; + if (!isOperationPermissibleForObject(&group)) return false; - if (geode.getNumDrawables()>=2) + if (group.getNumChildren()>=2) { - // OSG_NOTICE<<"Before "< DuplicateList; typedef std::vector< osg::ref_ptr > DrawableList; typedef std::map GeometryDuplicateMap; @@ -1801,9 +1799,9 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) DrawableList standardDrawables; unsigned int i; - for(i=0;iasDrawable(); if (drawable) { osg::Geometry* geom = drawable->asGeometry(); @@ -1945,26 +1943,6 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) if (needToDoMerge) { - // first take a reference to all the drawables to prevent them being deleted prematurely - DrawableList keepDrawables; - keepDrawables.resize(geode.getNumDrawables()); - for(i=0; iget()); - } - // now do the merging of geometries for(MergeList::iterator mitr = mergeList.begin(); mitr != mergeList.end(); @@ -1974,18 +1952,15 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) if (duplicateList.size()>1) { osg::Geometry* lhs = duplicateList.front(); - geode.addDrawable(lhs); for(DuplicateList::iterator ditr = duplicateList.begin()+1; ditr != duplicateList.end(); ++ditr) { mergeGeometry(*lhs,**ditr); + + group.removeChild(*ditr); } } - else if (duplicateList.size()>0) - { - geode.addDrawable(duplicateList.front()); - } } } @@ -2035,16 +2010,17 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) } #endif - // OSG_NOTICE<<"After "<asGeometry(); + osg::Drawable* drawable = group.getChild(i)->asDrawable(); + if (!drawable) + continue; + osg::Geometry* geom = drawable->asGeometry(); if (geom) { osg::Geometry::PrimitiveSetList& primitives = geom->getPrimitiveSetList(); @@ -2069,9 +2045,12 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) } // now merge any compatible primitives. - for(i=0;iasGeometry(); + osg::Drawable* drawable = group.getChild(i)->asDrawable(); + if (!drawable) + continue; + osg::Geometry* geom = drawable->asGeometry(); if (geom) { if (geom->getNumPrimitiveSets()>0 && From ef431eec29b1fe03ca7c8ef50ace74fdb6e40a2f Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 24 Feb 2017 01:07:24 +0100 Subject: [PATCH 3/5] Fix unused parameter warning --- src/osgPlugins/ktx/ReaderWriterKTX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/ktx/ReaderWriterKTX.cpp b/src/osgPlugins/ktx/ReaderWriterKTX.cpp index dee4ccddd..5ca6cd705 100644 --- a/src/osgPlugins/ktx/ReaderWriterKTX.cpp +++ b/src/osgPlugins/ktx/ReaderWriterKTX.cpp @@ -337,7 +337,7 @@ osgDB::ReaderWriter::WriteResult ReaderWriterKTX::writeImage(const osg::Image &i return res; } -osgDB::ReaderWriter::WriteResult ReaderWriterKTX::writeImage(const osg::Image& image, std::ostream& fout, const Options* options) const +osgDB::ReaderWriter::WriteResult ReaderWriterKTX::writeImage(const osg::Image& image, std::ostream& fout, const Options* /*options*/) const { // bool noAutoFlipDDSWrite = options && options->getOptionString().find("ddsNoAutoFlipWrite") != std::string::npos; //maybe for ktx too? bool success = writeKTXStream(&image, fout); From 7e2436aba99555927a8932ca9461c65e9fe38287 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 24 Feb 2017 01:08:44 +0100 Subject: [PATCH 4/5] Change the order of optimizations to allow for the possibility of merging Geometries that have just become siblings after the removal of redundant nodes --- src/osgUtil/Optimizer.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index f4ea29fde..f93f6ae5f 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -274,6 +274,20 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) } + if (options & REMOVE_REDUNDANT_NODES) + { + OSG_INFO<<"Optimizer::optimize() doing REMOVE_REDUNDANT_NODES"<accept(renv); + renv.removeEmptyNodes(); + + RemoveRedundantNodesVisitor rrnv(this); + node->accept(rrnv); + rrnv.removeRedundantNodes(); + + } + if (options & MERGE_GEODES) { OSG_INFO<<"Optimizer::optimize() doing MERGE_GEODES"<accept(renv); - renv.removeEmptyNodes(); - - RemoveRedundantNodesVisitor rrnv(this); - node->accept(rrnv); - rrnv.removeRedundantNodes(); - - } - if (options & FLATTEN_BILLBOARDS) { FlattenBillboardVisitor fbv(this); From c9621ff17a33d6efb5f8701ae55add53d29540a2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 24 Feb 2017 07:41:19 +0100 Subject: [PATCH 5/5] Add missing copy of callbacks when a Transform is replaced by Group --- src/osgUtil/Optimizer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index f93f6ae5f..575a9545a 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1064,7 +1064,10 @@ bool CollectLowestTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRem group->setDataVariance(osg::Object::STATIC); group->setNodeMask(transform->getNodeMask()); group->setStateSet(transform->getStateSet()); - group->setUserData(transform->getUserData()); + group->setUpdateCallback(transform->getUpdateCallback()); + group->setEventCallback(transform->getEventCallback()); + group->setCullCallback(transform->getCullCallback()); + group->setUserDataContainer(transform->getUserDataContainer()); group->setDescriptions(transform->getDescriptions()); for(unsigned int i=0;igetNumChildren();++i) {