From 3dde165f140ab5f973e50709235cf40c4862bc17 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 3 Jun 2014 09:23:24 +0000 Subject: [PATCH] Refactor osg::Geode to subclass from osg::Group and reuse the NodeList children container --- include/osg/Drawable | 2 +- include/osg/Geode | 42 +--- src/osg/Billboard.cpp | 38 ++-- src/osg/Geode.cpp | 209 +++----------------- src/osg/Group.cpp | 7 +- src/osgPlugins/pov/POVWriterNodeVisitor.cpp | 7 +- src/osgShadow/DebugShadowMap.cpp | 9 +- src/osgSim/ScalarBar.cpp | 4 +- src/osgSim/SphereSegment.cpp | 48 ++--- src/osgUtil/Optimizer.cpp | 41 ++-- 10 files changed, 120 insertions(+), 287 deletions(-) diff --git a/include/osg/Drawable b/include/osg/Drawable index 69e2a560e..d1afefef0 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -19,7 +19,7 @@ #include #include #include -#include +#include #ifndef GL_NV_occlusion_query diff --git a/include/osg/Geode b/include/osg/Geode index 0da365b8f..550adbcfc 100644 --- a/include/osg/Geode +++ b/include/osg/Geode @@ -25,12 +25,10 @@ namespace osg { * are represented by objects from the \c Drawable class, so a \c Geode is a * \c Node whose purpose is grouping Drawables. */ -class OSG_EXPORT Geode : public Node +class OSG_EXPORT Geode : public Group { public: - typedef std::vector< ref_ptr > DrawableList; - Geode(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ @@ -41,8 +39,6 @@ class OSG_EXPORT Geode : public Node virtual Geode* asGeode() { return this; } virtual const Geode* asGeode() const { return this; } - virtual void traverse(NodeVisitor& nv); - /** Add a \c Drawable to the \c Geode. * If \c drawable is not \c NULL and is not contained in the \c Geode * then increment its reference count, add it to the drawables list and @@ -92,22 +88,22 @@ class OSG_EXPORT Geode : public Node /** Return the number of Drawables currently attached to the * \c Geode. */ - inline unsigned int getNumDrawables() const { return static_cast(_drawables.size()); } + inline unsigned int getNumDrawables() const { return getNumChildren(); } /** Return the \c Drawable at position \c i.*/ - inline Drawable* getDrawable( unsigned int i ) { return _drawables[i].get(); } + inline Drawable* getDrawable( unsigned int i ) { return _children[i].valid() ? _children[i]->asDrawable() : 0; } /** Return the \c Drawable at position \c i.*/ - inline const Drawable* getDrawable( unsigned int i ) const { return _drawables[i].get(); } + inline const Drawable* getDrawable( unsigned int i ) const { return _children[i].valid() ? _children[i]->asDrawable() : 0; } /** Return \c true if a given \c Drawable is contained within \c Geode.*/ - inline bool containsDrawable(const Drawable* gset) const + inline bool containsDrawable(const Drawable* drawable) const { - for (DrawableList::const_iterator itr=_drawables.begin(); - itr!=_drawables.end(); + for (NodeList::const_iterator itr=_children.begin(); + itr!=_children.end(); ++itr) { - if (itr->get()==gset) return true; + if (itr->get() == drawable) return true; } return false; } @@ -119,16 +115,9 @@ class OSG_EXPORT Geode : public Node */ inline unsigned int getDrawableIndex( const Drawable* drawable ) const { - for (unsigned int drawableNum=0;drawableNum<_drawables.size();++drawableNum) - { - if (_drawables[drawableNum]==drawable) return drawableNum; - } - return static_cast(_drawables.size()); // drawable not found. + return getChildIndex(drawable); } - /** Get the list of drawables.*/ - const DrawableList& getDrawableList() const { return _drawables; } - /** Compile OpenGL Display List for each drawable.*/ void compileDrawables(RenderInfo& renderInfo); @@ -142,25 +131,12 @@ class OSG_EXPORT Geode : public Node virtual BoundingSphere computeBound() const; - /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ - virtual void setThreadSafeRefUnref(bool threadSafe); - - /** Resize any per context GLObject buffers to specified size. */ - virtual void resizeGLObjectBuffers(unsigned int maxSize); - - /** If State is non-zero, this function releases any associated OpenGL objects for - * the specified graphics context. Otherwise, releases OpenGL objects - * for all graphics contexts. */ - virtual void releaseGLObjects(osg::State* = 0) const; - protected: virtual ~Geode(); - mutable osg::BoundingBox _bbox; - DrawableList _drawables; }; diff --git a/src/osg/Billboard.cpp b/src/osg/Billboard.cpp index d8d8d2263..fb89fd5aa 100644 --- a/src/osg/Billboard.cpp +++ b/src/osg/Billboard.cpp @@ -107,7 +107,7 @@ bool Billboard::addDrawable(Drawable *gset) if (Geode::addDrawable(gset)) { Vec3 pos(0.0f,0.0f,0.0f); - while (_positionList.size()<_drawables.size()) + while (_positionList.size()<_children.size()) { _positionList.push_back(pos); } @@ -121,7 +121,7 @@ bool Billboard::addDrawable(Drawable *gset,const Vec3& pos) { if (Geode::addDrawable(gset)) { - while (_positionList.size()<_drawables.size()) + while (_positionList.size()<_children.size()) { _positionList.push_back(pos); } @@ -134,14 +134,14 @@ bool Billboard::addDrawable(Drawable *gset,const Vec3& pos) bool Billboard::removeDrawable( Drawable *gset ) { PositionList::iterator pitr = _positionList.begin(); - for (DrawableList::iterator itr=_drawables.begin(); - itr!=_drawables.end(); + for (NodeList::iterator itr=_children.begin(); + itr!=_children.end(); ++itr,++pitr) { if (itr->get()==gset) { // note ref_ptr<> automatically handles decrementing gset's reference count. - _drawables.erase(itr); + _children.erase(itr); _positionList.erase(pitr); dirtyBound(); return true; @@ -307,7 +307,7 @@ bool Billboard::computeMatrix(Matrix& modelview, const Vec3& eye_local, const Ve BoundingSphere Billboard::computeBound() const { int i; - int ngsets = _drawables.size(); + int ngsets = _children.size(); if( ngsets == 0 ) return BoundingSphere(); @@ -316,11 +316,14 @@ BoundingSphere Billboard::computeBound() const for( i = 0; i < ngsets; i++ ) { - const Drawable *gset = _drawables[i].get(); - const BoundingBox& bbox = gset->getBoundingBox(); + const Drawable* drawable = _children[i].valid() ? _children[i]->asDrawable() : 0; + if (drawable) + { + const BoundingBox& bbox = drawable->getBoundingBox(); - bsphere._center += bbox.center(); - bsphere._center += _positionList[i]; + bsphere._center += bbox.center(); + bsphere._center += _positionList[i]; + } } bsphere._center /= (float)(ngsets); @@ -328,13 +331,16 @@ BoundingSphere Billboard::computeBound() const float maxd = 0.0; for( i = 0; i < ngsets; ++i ) { - const Drawable *gset = _drawables[i].get(); - const BoundingBox& bbox = gset->getBoundingBox(); - Vec3 local_center = bsphere._center-_positionList[i]; - for(unsigned int c=0;c<8;++c) + const Drawable* drawable = _children[i].valid() ? _children[i]->asDrawable() : 0; + if (drawable) { - float d = (bbox.corner(c)-local_center).length2(); - if( d > maxd ) maxd = d; + const BoundingBox& bbox = drawable->getBoundingBox(); + Vec3 local_center = bsphere._center-_positionList[i]; + for(unsigned int c=0;c<8;++c) + { + float d = (bbox.corner(c)-local_center).length2(); + if( d > maxd ) maxd = d; + } } } bsphere._radius = sqrtf(maxd); diff --git a/src/osg/Geode.cpp b/src/osg/Geode.cpp index de48b835b..552e55b90 100644 --- a/src/osg/Geode.cpp +++ b/src/osg/Geode.cpp @@ -26,170 +26,38 @@ Geode::Geode() } Geode::Geode(const Geode& geode,const CopyOp& copyop): - Node(geode,copyop) + Group(geode,copyop) { - for(DrawableList::const_iterator itr=geode._drawables.begin(); - itr!=geode._drawables.end(); - ++itr) - { - Drawable* drawable = copyop(itr->get()); - if (drawable) addDrawable(drawable); - } } Geode::~Geode() { - // remove reference to this from children's parent lists. - for(DrawableList::iterator itr=_drawables.begin(); - itr!=_drawables.end(); - ++itr) - { - (*itr)->removeParent(this); - } } -void Geode::traverse(NodeVisitor& nv) +bool Geode::addDrawable( Drawable* drawable ) { - for(DrawableList::iterator itr=_drawables.begin(); - itr!=_drawables.end(); - ++itr) - { - (*itr)->accept(nv); - } -} - -bool Geode::addDrawable( Drawable *drawable ) -{ - if (drawable /* && !containsDrawable(drawable)*/) - { - // fallback for handling geometry with deprecated data - osg::Geometry* geometry = drawable->asGeometry(); - if (geometry && geometry->containsDeprecatedData()) geometry->fixDeprecatedData(); - - // note ref_ptr<> automatically handles incrementing drawable's reference count. - _drawables.push_back(drawable); - - // register as parent of drawable. - drawable->addParent(this); - - if (drawable->requiresUpdateTraversal()) - { - setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); - } - - if (drawable->requiresEventTraversal()) - { - setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+1); - } - - dirtyBound(); - - return true; - } - else return false; + return addChild(drawable); } -bool Geode::removeDrawable( Drawable *drawable ) +bool Geode::removeDrawable( Drawable* drawable ) { return removeDrawables(getDrawableIndex(drawable),1); } bool Geode::removeDrawables(unsigned int pos,unsigned int numDrawablesToRemove) { - if (pos<_drawables.size() && numDrawablesToRemove>0) - { - unsigned int endOfRemoveRange = pos+numDrawablesToRemove; - if (endOfRemoveRange>_drawables.size()) - { - OSG_DEBUG<<"Warning: Geode::removeDrawable(i,numDrawablesToRemove) has been passed an excessive number"<removeParent(this); - // update the number of app callbacks removed - if (_drawables[i]->requiresUpdateTraversal()) ++updateCallbackRemoved; - if (_drawables[i]->requiresEventTraversal()) ++eventCallbackRemoved; - } - - _drawables.erase(_drawables.begin()+pos,_drawables.begin()+endOfRemoveRange); - - if (updateCallbackRemoved) - { - setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved); - } - - if (eventCallbackRemoved) - { - setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved); - } - - dirtyBound(); - - return true; - } - else return false; + return removeChildren(pos, numDrawablesToRemove); } -bool Geode::replaceDrawable( Drawable *origDrawable, Drawable *newDrawable ) +bool Geode::replaceDrawable( Drawable* origDrawable, Drawable* newDrawable ) { - if (newDrawable==NULL || origDrawable==newDrawable) return false; - - unsigned int pos = getDrawableIndex(origDrawable); - if (pos<_drawables.size()) - { - return setDrawable(pos,newDrawable); - } - return false; + return replaceChild(origDrawable, newDrawable); } bool Geode::setDrawable( unsigned int i, Drawable* newDrawable ) { - if (i<_drawables.size() && newDrawable) - { - - Drawable* origDrawable = _drawables[i].get(); - - int deltaUpdate = 0; - if (origDrawable->requiresUpdateTraversal()) --deltaUpdate; - if (newDrawable->requiresUpdateTraversal()) ++deltaUpdate; - if (deltaUpdate!=0) - { - setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+deltaUpdate); - } - - int deltaEvent = 0; - if (origDrawable->requiresEventTraversal()) --deltaEvent; - if (newDrawable->requiresEventTraversal()) ++deltaEvent; - if (deltaEvent!=0) - { - setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+deltaEvent); - } - - - // remove from origDrawable's parent list. - origDrawable->removeParent(this); - - // note ref_ptr<> automatically handles decrementing origGset's reference count, - // and incrementing newGset's reference count. - _drawables[i] = newDrawable; - - // register as parent of child. - newDrawable->addParent(this); - - - dirtyBound(); - - return true; - } - else return false; - + return setChild(i, newDrawable); } @@ -199,12 +67,22 @@ BoundingSphere Geode::computeBound() const _bbox.init(); - DrawableList::const_iterator itr; - for(itr=_drawables.begin(); - itr!=_drawables.end(); + for(NodeList::const_iterator itr = _children.begin(); + itr!=_children.end(); ++itr) { - _bbox.expandBy((*itr)->getBoundingBox()); + if (itr->valid()) + { + const osg::Drawable* drawable = (*itr)->asDrawable(); + if (drawable) + { + _bbox.expandBy(drawable->getBoundingBox()); + } + else + { + _bbox.expandBy((*itr)->getBound()); + } + } } if (_bbox.valid()) @@ -216,46 +94,11 @@ BoundingSphere Geode::computeBound() const void Geode::compileDrawables(RenderInfo& renderInfo) { - for(DrawableList::iterator itr = _drawables.begin(); - itr!=_drawables.end(); + for(NodeList::iterator itr = _children.begin(); + itr!=_children.end(); ++itr) { - (*itr)->compileGLObjects(renderInfo); - } -} - -void Geode::setThreadSafeRefUnref(bool threadSafe) -{ - Node::setThreadSafeRefUnref(threadSafe); - - for(DrawableList::const_iterator itr=_drawables.begin(); - itr!=_drawables.end(); - ++itr) - { - (*itr)->setThreadSafeRefUnref(threadSafe); - } -} - -void Geode::resizeGLObjectBuffers(unsigned int maxSize) -{ - Node::resizeGLObjectBuffers(maxSize); - - for(DrawableList::const_iterator itr=_drawables.begin(); - itr!=_drawables.end(); - ++itr) - { - (*itr)->resizeGLObjectBuffers(maxSize); - } -} - -void Geode::releaseGLObjects(osg::State* state) const -{ - Node::releaseGLObjects(state); - - for(DrawableList::const_iterator itr=_drawables.begin(); - itr!=_drawables.end(); - ++itr) - { - (*itr)->releaseGLObjects(state); + osg::Drawable* drawable = itr->valid() ? (*itr)->asDrawable() : 0; + if (drawable) drawable->compileGLObjects(renderInfo); } } diff --git a/src/osg/Group.cpp b/src/osg/Group.cpp index 750d6e277..97813444d 100644 --- a/src/osg/Group.cpp +++ b/src/osg/Group.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -84,6 +84,11 @@ bool Group::insertChild( unsigned int index, Node *child ) if (child) { + // handle deprecated geometry configurations by calling fixDeprecatedData(). + osg::Geometry* geometry = child->asGeometry(); + if (geometry && geometry->containsDeprecatedData()) geometry->fixDeprecatedData(); + + // note ref_ptr<> automatically handles incrementing child's reference count. if (index >= _children.size()) { diff --git a/src/osgPlugins/pov/POVWriterNodeVisitor.cpp b/src/osgPlugins/pov/POVWriterNodeVisitor.cpp index 7a5662f92..db1e7f160 100644 --- a/src/osgPlugins/pov/POVWriterNodeVisitor.cpp +++ b/src/osgPlugins/pov/POVWriterNodeVisitor.cpp @@ -88,12 +88,11 @@ void POVWriterNodeVisitor::apply( Geode& node ) pushStateSet( node.getStateSet() ); // iterate through drawables - const Geode::DrawableList& dl = node.getDrawableList(); - for( Geode::DrawableList::const_iterator itr = dl.begin(); - itr != dl.end(); ++itr) + for(unsigned int i=0; iget(); + const Drawable *d = node.getDrawable(i); + if (!d) continue; // push state set const StateSet *ss = d->getStateSet(); diff --git a/src/osgShadow/DebugShadowMap.cpp b/src/osgShadow/DebugShadowMap.cpp index 19094ff3c..c962118ad 100644 --- a/src/osgShadow/DebugShadowMap.cpp +++ b/src/osgShadow/DebugShadowMap.cpp @@ -256,12 +256,9 @@ void DebugShadowMap::ViewData::setDebugPolytope pg._geometry[i]->setSupportsDisplayList( false ); } - if( _geode[i].valid() && - !_geode[i]->containsDrawable( pg._geometry[i].get() ) ) { - osg::Geode::DrawableList & dl = - const_cast< osg::Geode::DrawableList &> - ( _geode[i]->getDrawableList() ); - dl.insert( dl.begin(), pg._geometry[i].get() ); + if( _geode[i].valid() && !_geode[i]->containsDrawable( pg._geometry[i].get() ) ) + { + _geode[i]->insertChild(0, pg._geometry[i].get() ); } } } diff --git a/src/osgSim/ScalarBar.cpp b/src/osgSim/ScalarBar.cpp index b8afc99ee..4d3f3248f 100644 --- a/src/osgSim/ScalarBar.cpp +++ b/src/osgSim/ScalarBar.cpp @@ -123,8 +123,8 @@ const ScalarBar::TextProperties& ScalarBar::getTextProperties() const void ScalarBar::createDrawables() { // Remove any existing Drawables - _drawables.erase(_drawables.begin(), _drawables.end()); - + removeDrawables(0, getNumDrawables()); + if (_numColors==0) return; osg::Matrix matrix; diff --git a/src/osgSim/SphereSegment.cpp b/src/osgSim/SphereSegment.cpp index e6d6472ee..4235c7608 100644 --- a/src/osgSim/SphereSegment.cpp +++ b/src/osgSim/SphereSegment.cpp @@ -378,21 +378,19 @@ void SphereSegment::init() void SphereSegment::dirtyAllDrawableDisplayLists() { - for(DrawableList::iterator itr = _drawables.begin(); - itr != _drawables.end(); - ++itr) + for(unsigned int i=0; idirtyDisplayList(); + osg::Drawable* drawable = getDrawable(i); + if (drawable) drawable->dirtyDisplayList(); } } void SphereSegment::dirtyAllDrawableBounds() { - for(DrawableList::iterator itr = _drawables.begin(); - itr != _drawables.end(); - ++itr) + for(unsigned int i=0; idirtyBound(); + osg::Drawable* drawable = getDrawable(i); + if (drawable) drawable->dirtyBound(); } } @@ -893,17 +891,18 @@ struct ActivateTransparencyOnType { ActivateTransparencyOnType(const std::type_info& t): _t(t) {} - void operator()(osg::ref_ptr& dptr) const + void operator()(osg::ref_ptr& nptr) const { - if(typeid(*dptr)==_t) + if(typeid(*nptr)==_t) { - osg::StateSet* ss = dptr->getOrCreateStateSet(); + osg::Drawable* drawable = nptr->asDrawable(); + osg::StateSet* ss = drawable->getOrCreateStateSet(); ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); ss->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK),osg::StateAttribute::ON); ss->setMode(GL_BLEND,osg::StateAttribute::ON); - dptr->dirtyDisplayList(); + drawable->dirtyDisplayList(); } } @@ -918,14 +917,15 @@ struct DeactivateTransparencyOnType { DeactivateTransparencyOnType(const std::type_info& t): _t(t) {} - void operator()(osg::ref_ptr& dptr) const + void operator()(osg::ref_ptr& nptr) const { - if(typeid(*dptr)==_t) + if(typeid(*nptr)==_t) { - osg::StateSet* ss = dptr->getStateSet(); + osg::Drawable* drawable = nptr->asDrawable(); + osg::StateSet* ss = drawable->getOrCreateStateSet(); if(ss) ss->setRenderingHint(osg::StateSet::OPAQUE_BIN); - dptr->dirtyDisplayList(); + drawable->dirtyDisplayList(); } } @@ -940,32 +940,32 @@ void SphereSegment::setSurfaceColor(const osg::Vec4& c) { _surfaceColor=c; - if(c.w() != 1.0) std::for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(Surface))); - else std::for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(Surface))); + if(c.w() != 1.0) std::for_each(_children.begin(), _children.end(), ActivateTransparencyOnType(typeid(Surface))); + else std::for_each(_children.begin(), _children.end(), DeactivateTransparencyOnType(typeid(Surface))); } void SphereSegment::setSpokeColor(const osg::Vec4& c) { _spokeColor=c; - if(c.w() != 1.0) std::for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(Spoke))); - else std::for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(Spoke))); + if(c.w() != 1.0) std::for_each(_children.begin(), _children.end(), ActivateTransparencyOnType(typeid(Spoke))); + else std::for_each(_children.begin(), _children.end(), DeactivateTransparencyOnType(typeid(Spoke))); } void SphereSegment::setEdgeLineColor(const osg::Vec4& c) { _edgeLineColor=c; - if(c.w() != 1.0) std::for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(EdgeLine))); - else std::for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(EdgeLine))); + if(c.w() != 1.0) std::for_each(_children.begin(), _children.end(), ActivateTransparencyOnType(typeid(EdgeLine))); + else std::for_each(_children.begin(), _children.end(), DeactivateTransparencyOnType(typeid(EdgeLine))); } void SphereSegment::setSideColor(const osg::Vec4& c) { _planeColor=c; - if(c.w() != 1.0) std::for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(Side))); - else std::for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(Side))); + if(c.w() != 1.0) std::for_each(_children.begin(), _children.end(), ActivateTransparencyOnType(typeid(Side))); + else std::for_each(_children.begin(), _children.end(), DeactivateTransparencyOnType(typeid(Side))); } void SphereSegment::setAllColors(const osg::Vec4& c) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index c156ed27b..dbf9fe2fb 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1888,36 +1888,41 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) // OSG_NOTICE<<"Before "< DuplicateList; + typedef std::vector< osg::ref_ptr > DrawableList; typedef std::map GeometryDuplicateMap; typedef std::vector MergeList; GeometryDuplicateMap geometryDuplicateMap; - osg::Geode::DrawableList standardDrawables; + DrawableList standardDrawables; unsigned int i; for(i=0;iasGeometry(); - if (geom) + osg::Drawable* drawable = geode.getDrawable(i); + if (drawable) { - //geom->computeCorrectBindingsAndArraySizes(); - - if (!geometryContainsSharedArrays(*geom) && - geom->getDataVariance()!=osg::Object::DYNAMIC && - isOperationPermissibleForObject(geom)) + osg::Geometry* geom = drawable->asGeometry(); + if (geom) { - geometryDuplicateMap[geom].push_back(geom); + //geom->computeCorrectBindingsAndArraySizes(); + + if (!geometryContainsSharedArrays(*geom) && + geom->getDataVariance()!=osg::Object::DYNAMIC && + isOperationPermissibleForObject(geom)) + { + geometryDuplicateMap[geom].push_back(geom); + } + else + { + standardDrawables.push_back(drawable); + } } else { - standardDrawables.push_back(geode.getDrawable(i)); + standardDrawables.push_back(drawable); } } - else - { - standardDrawables.push_back(geode.getDrawable(i)); - } } #if 1 @@ -2037,18 +2042,20 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) if (needToDoMerge) { // first take a reference to all the drawables to prevent them being deleted prematurely - osg::Geode::DrawableList keepDrawables; + typedef std::vector< osg::ref_ptr > DrawableList; + DrawableList keepDrawables; keepDrawables.resize(geode.getNumDrawables()); for(i=0; i