From dd32e6425e8c54257f32c731e2765358e7df30fa Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 13 Jul 2006 15:25:22 +0000 Subject: [PATCH] Added StatsVisitor to include/osg/Statistics, and usage of it in osgUtil::Optimizer. Added --optimize option to osgconv --- applications/osgconv/osgconv.cpp | 12 +++ include/osgUtil/Statistics | 169 +++++++++++++++++++++++++++++++ src/osgUtil/Optimizer.cpp | 63 ++++++++---- 3 files changed, 226 insertions(+), 18 deletions(-) diff --git a/applications/osgconv/osgconv.cpp b/applications/osgconv/osgconv.cpp index e63d62fc9..ffb28c979 100644 --- a/applications/osgconv/osgconv.cpp +++ b/applications/osgconv/osgconv.cpp @@ -450,6 +450,18 @@ int main( int argc, char **argv ) return 1; } + std::string options; + while(arguments.read("--optimizer",options)) + { + osg::notify(osg::NOTICE)<<"Setting "< #include +#include +#include +#include +#include +#include +#include #include +#include +#include namespace osgUtil { @@ -197,6 +205,167 @@ inline unsigned int Statistics::_calculate_primitives_number_by_mode(GLenum mode } } +/** StatsVisitor for collecting statistics about scene graph.*/ +class StatsVisitor : public osg::NodeVisitor +{ +public: + + typedef std::set NodeSet; + typedef std::set DrawableSet; + + StatsVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _numInstancedGroup(0), + _numInstancedSwitch(0), + _numInstancedLOD(0), + _numInstancedTransform(0), + _numInstancedGeode(0), + _numInstancedDrawable(0), + _numInstancedGeometry(0) {} + + void reset() + { + _numInstancedGroup = 0; + _numInstancedSwitch = 0; + _numInstancedLOD = 0; + _numInstancedTransform = 0; + _numInstancedGeode = 0; + _numInstancedDrawable = 0; + _numInstancedGeometry = 0; + + _groupSet.clear(); + _transformSet.clear(); + _lodSet.clear(); + _switchSet.clear(); + _geodeSet.clear(); + _drawableSet.clear(); + _geometrySet.clear(); + + _uniqueStats.reset(); + _instancedStats.reset(); + } + + void apply(osg::Group& node) + { + ++_numInstancedGroup; + _groupSet.insert(&node); + traverse(node); + } + + void apply(osg::Transform& node) + { + ++_numInstancedTransform; + _transformSet.insert(&node); + traverse(node); + } + + void apply(osg::LOD& node) + { + ++_numInstancedLOD; + _lodSet.insert(&node); + traverse(node); + } + + void apply(osg::Switch& node) + { + ++_numInstancedSwitch; + _switchSet.insert(&node); + traverse(node); + } + + void apply(osg::Geode& node) + { + ++_numInstancedGeode; + _geodeSet.insert(&node); + + for(unsigned int i=0; i(&drawable); + if (geometry) + { + ++_numInstancedGeometry; + _geometrySet.insert(geometry); + } + } + + void totalUpStats() + { + _uniqueStats.reset(); + + for(DrawableSet::iterator itr = _drawableSet.begin(); + itr != _drawableSet.end(); + ++itr) + { + (*itr)->accept(_uniqueStats); + } + } + + void print(std::ostream& out) + { + + unsigned int unique_primitives = 0; + osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr; + for(pcmitr = _uniqueStats.GetPrimitivesBegin(); + pcmitr != _uniqueStats.GetPrimitivesEnd(); + ++pcmitr) + { + unique_primitives += pcmitr->second; + } + + unsigned int instanced_primitives = 0; + for(pcmitr = _instancedStats.GetPrimitivesBegin(); + pcmitr != _instancedStats.GetPrimitivesEnd(); + ++pcmitr) + { + instanced_primitives += pcmitr->second; + } + + out<<"Object Type\t#Unique\t#Instanced"< #include #include +#include #include #include @@ -38,23 +39,22 @@ using namespace osgUtil; - void Optimizer::reset() { } -static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \" []\"","OFF | DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS | REMOVE_LOADED_PROXY_NODES | TESSELATE_GEOMETRY | CHECK_GEOMETRY"); +static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \" []\"","OFF | DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | MERGE_GEODES | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS | REMOVE_LOADED_PROXY_NODES | TESSELATE_GEOMETRY | CHECK_GEOMETRY"); void Optimizer::optimize(osg::Node* node) { unsigned int options = 0; + const char* env = getenv("OSG_OPTIMIZER"); if (env) { std::string str(env); - if(str.find("OFF")!=std::string::npos) options = 0; if(str.find("~DEFAULT")!=std::string::npos) options ^= DEFAULT_OPTIMIZATIONS; @@ -106,10 +106,21 @@ void Optimizer::optimize(osg::Node* node) } optimize(node,options); + } void Optimizer::optimize(osg::Node* node, unsigned int options) { + StatsVisitor stats; + + if (osg::getNotifyLevel()>=osg::INFO) + { + node->accept(stats); + stats.totalUpStats(); + osg::notify(osg::NOTICE)<accept(renv); - renv.removeEmptyNodes(); - - RemoveRedundantNodesVisitor rrnv(this); - node->accept(rrnv); - rrnv.removeRedundantNodes(); - - } - if (options & MERGE_GEODES) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEODES"<accept(renv); + renv.removeEmptyNodes(); + + RemoveRedundantNodesVisitor rrnv(this); + node->accept(rrnv); + rrnv.removeRedundantNodes(); + + } + + if (options & SPATIALIZE_GROUPS) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing SPATIALIZE_GROUPS"<=osg::INFO) + { + stats.reset(); + node->accept(stats); + stats.totalUpStats(); + osg::notify(osg::NOTICE)<second.size()<second.size()>1) { osg::Geode* lhs = itr->second[0]; @@ -2556,6 +2580,9 @@ bool Optimizer::MergeGeodesVisitor::mergeGeodes(osg::Group& group) } } } + else + { + } } return true;