From adba6fa5590f5af7bae6a235ce3cb276ea03c59b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 30 Apr 2005 15:16:05 +0000 Subject: [PATCH] Added RemoveLoadedProxyNodes pass to Optimizer, set on by default at present. --- include/osg/NodeVisitor | 25 +++++++------- include/osg/ProxyNode | 12 +++---- include/osgUtil/Optimizer | 40 +++++++++++++++++------ src/osgUtil/Optimizer.cpp | 68 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 117 insertions(+), 28 deletions(-) diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 1240ce5a5..6fc136eb2 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -20,24 +20,25 @@ namespace osg { -class Geode; class Billboard; -class LightSource; +class ClearNode; class ClipNode; -class TexGenNode; +class CoordinateSystemNode; +class Geode; class Group; -class Transform; +class Impostor; +class LightSource; +class LOD; class MatrixTransform; +class OccluderNode; +class PagedLOD; class PositionAttitudeTransform; class Projection; -class LOD; -class PagedLOD; -class Switch; -class Impostor; -class ClearNode; -class OccluderNode; +class ProxyNode; class Sequence; -class CoordinateSystemNode; +class Switch; +class TexGenNode; +class Transform; /** Visitor for type safe operations on osg::Nodes. Based on GOF's Visitor pattern. The NodeVisitor @@ -222,6 +223,8 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced virtual void apply(Group& node) { apply((Node&)node); } + virtual void apply(ProxyNode& node) { apply((Group&)node); } + virtual void apply(Projection& node) { apply((Group&)node); } virtual void apply(CoordinateSystemNode& node) { apply((Group&)node); } diff --git a/include/osg/ProxyNode b/include/osg/ProxyNode index 931c3c2c3..c3808ad96 100644 --- a/include/osg/ProxyNode +++ b/include/osg/ProxyNode @@ -61,19 +61,19 @@ class OSG_EXPORT ProxyNode : public Group /** Get how the center of object should be determined when computed which child is active.*/ CenterMode getCenterMode() const { return _centerMode; } - /** Sets the object-space point which defines the center of the osg::LOD. - center is affected by any transforms in the hierarchy above the osg::LOD.*/ + /** Sets the object-space point which defines the center of the osg::ProxyNode. + center is affected by any transforms in the hierarchy above the osg::ProxyNode.*/ inline void setCenter(const Vec3& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } - /** return the LOD center point. */ + /** return the ProxyNode center point. */ inline const Vec3& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } - /** Set the object-space reference radius of the volume enclosed by the LOD. - * Used to detmine the bounding sphere of the LOD in the absense of any children.*/ + /** Set the object-space reference radius of the volume enclosed by the ProxyNode. + * Used to detmine the bounding sphere of the ProxyNode in the absense of any children.*/ inline void setRadius(float radius) { _radius = radius; } - /** Get the object-space radius of the volume enclosed by the LOD.*/ + /** Get the object-space radius of the volume enclosed by the ProxyNode.*/ inline float getRadius() const { return _radius; } protected : diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index a263aa015..44618b9a2 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -41,17 +41,19 @@ class OSGUTIL_EXPORT Optimizer { FLATTEN_STATIC_TRANSFORMS = 0x001, REMOVE_REDUNDANT_NODES = 0x002, - COMBINE_ADJACENT_LODS = 0x004, - SHARE_DUPLICATE_STATE = 0x008, - MERGE_GEOMETRY = 0x010, - CHECK_GEOMETRY = 0x020, - SPATIALIZE_GROUPS = 0x040, - COPY_SHARED_NODES = 0x080, - TRISTRIP_GEOMETRY = 0x100, - TESSELATE_GEOMETRY = 0x200, - OPTIMIZE_TEXTURE_SETTINGS = 0x400, + REMOVE_LOADED_PROXY_NODES = 0x004, + COMBINE_ADJACENT_LODS = 0x008, + SHARE_DUPLICATE_STATE = 0x010, + MERGE_GEOMETRY = 0x020, + CHECK_GEOMETRY = 0x040, + SPATIALIZE_GROUPS = 0x080, + COPY_SHARED_NODES = 0x100, + TRISTRIP_GEOMETRY = 0x200, + TESSELATE_GEOMETRY = 0x400, + OPTIMIZE_TEXTURE_SETTINGS = 0x800, DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | + REMOVE_LOADED_PROXY_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | @@ -59,6 +61,7 @@ class OSGUTIL_EXPORT Optimizer OPTIMIZE_TEXTURE_SETTINGS, ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | + REMOVE_LOADED_PROXY_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | @@ -315,7 +318,7 @@ class OSGUTIL_EXPORT Optimizer }; - /** Remove rendundant nodes, such as groups with one single child.*/ + /** Remove redundant nodes, such as groups with one single child.*/ class OSGUTIL_EXPORT RemoveRedundantNodesVisitor : public BaseOptimizerVisitor { public: @@ -333,6 +336,23 @@ class OSGUTIL_EXPORT Optimizer }; + /** Remove loaded proxy nodes.*/ + class OSGUTIL_EXPORT RemoveLoadedProxyNodesVisitor : public BaseOptimizerVisitor + { + public: + + typedef std::set NodeList; + NodeList _redundantNodeList; + + RemoveLoadedProxyNodesVisitor(Optimizer* optimizer=0): + BaseOptimizerVisitor(optimizer, REMOVE_LOADED_PROXY_NODES) {} + + virtual void apply(osg::ProxyNode& group); + + void removeRedundantNodes(); + + }; + /** Tesselate all geodes, to remove POLYGONS.*/ class OSGUTIL_EXPORT TesselateVisitor : public BaseOptimizerVisitor { diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 96ea54554..1f9b5d517 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -43,7 +44,7 @@ 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"); +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"); void Optimizer::optimize(osg::Node* node) { @@ -66,6 +67,9 @@ void Optimizer::optimize(osg::Node* node) if(str.find("~REMOVE_REDUNDANT_NODES")!=std::string::npos) options ^= REMOVE_REDUNDANT_NODES; else if(str.find("REMOVE_REDUNDANT_NODES")!=std::string::npos) options |= REMOVE_REDUNDANT_NODES; + if(str.find("~REMOVE_LOADED_PROXY_NODES")!=std::string::npos) options ^= REMOVE_LOADED_PROXY_NODES; + else if(str.find("REMOVE_LOADED_PROXY_NODES")!=std::string::npos) options |= REMOVE_LOADED_PROXY_NODES; + if(str.find("~COMBINE_ADJACENT_LODS")!=std::string::npos) options ^= COMBINE_ADJACENT_LODS; else if(str.find("COMBINE_ADJACENT_LODS")!=std::string::npos) options |= COMBINE_ADJACENT_LODS; @@ -112,6 +116,16 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) node->accept(tsv); } + if (options & REMOVE_LOADED_PROXY_NODES) + { + osg::notify(osg::INFO)<<"Optimizer::optimize() doing REMOVE_LOADED_PROXY_NODES"<accept(rlpnv); + rlpnv.removeRedundantNodes(); + + } + if (options & COMBINE_ADJACENT_LODS) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing COMBINE_ADJACENT_LODS"<0 && proxyNode.getNumFileNames()==proxyNode.getNumChildren()) + { + if (isOperationPermissibleForObject(&proxyNode)) + { + _redundantNodeList.insert(&proxyNode); + } + } + traverse(proxyNode); +} + +void Optimizer::RemoveLoadedProxyNodesVisitor::removeRedundantNodes() +{ + + for(NodeList::iterator itr=_redundantNodeList.begin(); + itr!=_redundantNodeList.end(); + ++itr) + { + osg::ref_ptr group = dynamic_cast(*itr); + if (group.valid()) + { + // take a copy of parents list since subsequent removes will modify the original one. + osg::Node::ParentList parents = group->getParents(); + + for(unsigned int i=0;igetNumChildren();++i) + { + osg::Node* child = group->getChild(i); + for(osg::Node::ParentList::iterator pitr=parents.begin(); + pitr!=parents.end(); + ++pitr) + { + (*pitr)->replaceChild(group.get(),child); + } + + } + + } + else + { + osg::notify(osg::WARN)<<"Optimizer::RemoveLoadedProxyNodesVisitor::removeRedundantNodes() - failed dynamic_cast"<