From 06691072873053d42886ccbac3c6e3ccfa09a454 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 10 Mar 2009 14:15:59 +0000 Subject: [PATCH] From Roland Smeenk, "While working on the Collada plugin I noticed that all geometry created by the dae reader result in slow path geometry. Because there already exists the option to convert slow path geometry to the fast path by computing an internal fast path alternative, I added a new optimizer option that automatically does this. To check the results I also made some changes to the statistics gathering and rendering. Somewhat unrelated, but also part of the optimizer I disabled removal of CameraView nodes during RemoveRedundantNodes optimization. As discussed on the ML, CameraViews were removed from the scenegraph. This solves that issue. Summary: -Geometry::areFastPathsUsed now also looks at internalOptimizedGeometry -Added Optimize option to make all slow path geometry compute their internal fast path alternative -Added fast geometry counter to the statistics -Disabled removel of CameraViews in optimizer " --- include/osg/Geometry | 8 +++++++- include/osgUtil/Optimizer | 37 +++++++++++++++++++++++++--------- include/osgUtil/Statistics | 2 ++ src/osgUtil/Optimizer.cpp | 32 ++++++++++++++++++++++++++++- src/osgUtil/Statistics.cpp | 39 ++++++++++++++++++++++++------------ src/osgViewer/ViewerBase.cpp | 2 +- 6 files changed, 94 insertions(+), 26 deletions(-) diff --git a/include/osg/Geometry b/include/osg/Geometry index 670f55de9..817790cfe 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -331,7 +331,13 @@ class OSG_EXPORT Geometry : public Drawable * use glBegin()/glVertex.../glEnd(). Use of per primitive bindings or per vertex indexed * arrays will drop the rendering path off the fast path. */ - inline bool areFastPathsUsed() const { return _fastPath && _fastPathHint; } + inline bool areFastPathsUsed() const + { + if (_internalOptimizedGeometry.valid()) + return _internalOptimizedGeometry->areFastPathsUsed(); + else + return _fastPath && _fastPathHint; + } bool computeFastPathsUsed(); diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 66eeb738d..4ce6ee928 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -74,22 +74,24 @@ class OSGUTIL_EXPORT Optimizer SHARE_DUPLICATE_STATE = (1 << 4), MERGE_GEOMETRY = (1 << 5), CHECK_GEOMETRY = (1 << 6), - SPATIALIZE_GROUPS = (1 << 7), - COPY_SHARED_NODES = (1 << 8), - TRISTRIP_GEOMETRY = (1 << 9), - TESSELLATE_GEOMETRY = (1 << 10), - OPTIMIZE_TEXTURE_SETTINGS = (1 << 11), - MERGE_GEODES = (1 << 12), - FLATTEN_BILLBOARDS = (1 << 13), - TEXTURE_ATLAS_BUILDER = (1 << 14), - STATIC_OBJECT_DETECTION = (1 << 15), - FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 16), + MAKE_FAST_GEOMETRY = (1 << 7), + SPATIALIZE_GROUPS = (1 << 8), + COPY_SHARED_NODES = (1 << 9), + TRISTRIP_GEOMETRY = (1 << 10), + TESSELLATE_GEOMETRY = (1 << 11), + OPTIMIZE_TEXTURE_SETTINGS = (1 << 12), + MERGE_GEODES = (1 << 13), + FLATTEN_BILLBOARDS = (1 << 14), + TEXTURE_ATLAS_BUILDER = (1 << 15), + STATIC_OBJECT_DETECTION = (1 << 16), + FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 17), DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | REMOVE_LOADED_PROXY_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | + MAKE_FAST_GEOMETRY | CHECK_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS | STATIC_OBJECT_DETECTION, @@ -100,6 +102,7 @@ class OSGUTIL_EXPORT Optimizer SHARE_DUPLICATE_STATE | MERGE_GEODES | MERGE_GEOMETRY | + MAKE_FAST_GEOMETRY | CHECK_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | @@ -506,6 +509,20 @@ class OSGUTIL_EXPORT Optimizer }; + class OSGUTIL_EXPORT MakeFastGeometryVisitor : public BaseOptimizerVisitor + { + public: + + /// default to traversing all children. + MakeFastGeometryVisitor(Optimizer* optimizer=0): + BaseOptimizerVisitor(optimizer, MAKE_FAST_GEOMETRY) {} + + virtual void apply(osg::Geode& geode) { checkGeode(geode); } + + void checkGeode(osg::Geode& geode); + + }; + class OSGUTIL_EXPORT MergeGeometryVisitor : public BaseOptimizerVisitor { public: diff --git a/include/osgUtil/Statistics b/include/osgUtil/Statistics index 8d3563067..96a84f4e4 100644 --- a/include/osgUtil/Statistics +++ b/include/osgUtil/Statistics @@ -201,6 +201,7 @@ public: unsigned int _numInstancedGeode; unsigned int _numInstancedDrawable; unsigned int _numInstancedGeometry; + unsigned int _numInstancedFastGeometry; unsigned int _numInstancedStateSet; NodeSet _groupSet; @@ -210,6 +211,7 @@ public: NodeSet _geodeSet; DrawableSet _drawableSet; DrawableSet _geometrySet; + DrawableSet _fastGeometrySet; StateSetSet _statesetSet; osgUtil::Statistics _uniqueStats; diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 286810f37..435c63ef0 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,9 @@ void Optimizer::optimize(osg::Node* node) if(str.find("~CHECK_GEOMETRY")!=std::string::npos) options ^= CHECK_GEOMETRY; else if(str.find("CHECK_GEOMETRY")!=std::string::npos) options |= CHECK_GEOMETRY; + + if(str.find("~MAKE_FAST_GEOMETRY")!=std::string::npos) options ^= MAKE_FAST_GEOMETRY; + else if(str.find("MAKE_FAST_GEOMETRY")!=std::string::npos) options |= MAKE_FAST_GEOMETRY; if(str.find("~FLATTEN_BILLBOARDS")!=std::string::npos) options ^= FLATTEN_BILLBOARDS; else if(str.find("FLATTEN_BILLBOARDS")!=std::string::npos) options |= FLATTEN_BILLBOARDS; @@ -279,6 +283,14 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) node->accept(mgv); } + if (options & MAKE_FAST_GEOMETRY) + { + osg::notify(osg::INFO)<<"Optimizer::optimize() doing MAKE_FAST_GEOMETRY"<accept(mgv); + } + if (options & MERGE_GEOMETRY) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEOMETRY"<(&group))) + (typeid(group)==typeid(osg::Group) || (dynamic_cast(&group) && !dynamic_cast(&group)))) { _redundantNodeList.insert(&group); } @@ -1785,6 +1797,24 @@ void Optimizer::CheckGeometryVisitor::checkGeode(osg::Geode& geode) } } +void Optimizer::MakeFastGeometryVisitor::checkGeode(osg::Geode& geode) +{ + if (isOperationPermissibleForObject(&geode)) + { + for(unsigned int i=0;iasGeometry(); + if (geom && isOperationPermissibleForObject(geom)) + { + if (!geom->areFastPathsUsed() && !geom->getInternalOptimizedGeometry()) + { + geom->computeInternalOptimizedGeometry(); + } + } + } + } +} + bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) { if (!isOperationPermissibleForObject(&geode)) return false; diff --git a/src/osgUtil/Statistics.cpp b/src/osgUtil/Statistics.cpp index 274cb18cd..51d47836d 100644 --- a/src/osgUtil/Statistics.cpp +++ b/src/osgUtil/Statistics.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace osgUtil; @@ -143,6 +144,7 @@ StatsVisitor::StatsVisitor(): _numInstancedGeode(0), _numInstancedDrawable(0), _numInstancedGeometry(0), + _numInstancedFastGeometry(0), _numInstancedStateSet(0) {} @@ -155,6 +157,7 @@ void StatsVisitor::reset() _numInstancedGeode = 0; _numInstancedDrawable = 0; _numInstancedGeometry = 0; + _numInstancedFastGeometry = 0; _numInstancedStateSet = 0; _groupSet.clear(); @@ -164,6 +167,7 @@ void StatsVisitor::reset() _geodeSet.clear(); _drawableSet.clear(); _geometrySet.clear(); + _fastGeometrySet.clear(); _statesetSet.clear(); _uniqueStats.reset(); @@ -264,12 +268,18 @@ void StatsVisitor::apply(osg::Drawable& drawable) drawable.accept(_instancedStats); _drawableSet.insert(&drawable); - - osg::Geometry* geometry = dynamic_cast(&drawable); + + osg::Geometry* geometry = drawable.asGeometry(); if (geometry) { ++_numInstancedGeometry; _geometrySet.insert(geometry); + + if (geometry->areFastPathsUsed()) + { + ++_numInstancedFastGeometry; + _fastGeometrySet.insert(geometry); + } } } @@ -305,16 +315,19 @@ void StatsVisitor::print(std::ostream& out) instanced_primitives += pcmitr->second; } - out<<"Object Type\t#Unique\t#Instanced"<isRealized()) { - osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizing window "<realize(); }