From 3c90a5f694e65a0cb6b8fdb9bc2d78ffc000bfe0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Apr 2005 09:58:19 +0000 Subject: [PATCH] Added support notification of Drawable parents of StateSet that event/update callbacks have been called. --- include/osg/Drawable | 9 +++++ src/osg/Drawable.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++-- src/osg/StateSet.cpp | 7 ++-- 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/include/osg/Drawable b/include/osg/Drawable index 9dec4a7b5..17e7affbf 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -702,6 +702,7 @@ class OSG_EXPORT Drawable : public Object ParentList _parents; friend class Node; friend class Geode; + friend class StateSet; ref_ptr _stateset; @@ -720,7 +721,15 @@ class OSG_EXPORT Drawable : public Object mutable GLObjectList _vboList; ref_ptr _updateCallback; + unsigned int _numChildrenRequiringUpdateTraversal; + void setNumChildrenRequiringUpdateTraversal(unsigned int num); + unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; } + ref_ptr _eventCallback; + unsigned int _numChildrenRequiringEventTraversal; + void setNumChildrenRequiringEventTraversal(unsigned int num); + unsigned int getNumChildrenRequiringEventTraversal() const { return _numChildrenRequiringEventTraversal; } + ref_ptr _cullCallback; ref_ptr _drawCallback; }; diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index 082cbf772..a491046d2 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -271,6 +271,9 @@ Drawable::Drawable() _supportsVertexBufferObjects = false; _useVertexBufferObjects = false; + + _numChildrenRequiringUpdateTraversal = 0; + _numChildrenRequiringEventTraversal = 0; } Drawable::Drawable(const Drawable& drawable,const CopyOp& copyop): @@ -285,6 +288,9 @@ Drawable::Drawable(const Drawable& drawable,const CopyOp& copyop): _supportsVertexBufferObjects(drawable._supportsVertexBufferObjects), _useVertexBufferObjects(drawable._useVertexBufferObjects), _updateCallback(drawable._updateCallback), + _numChildrenRequiringUpdateTraversal(drawable._numChildrenRequiringUpdateTraversal), + _eventCallback(drawable._eventCallback), + _numChildrenRequiringEventTraversal(drawable._numChildrenRequiringEventTraversal), _cullCallback(drawable._cullCallback), _drawCallback(drawable._drawCallback) { @@ -343,7 +349,7 @@ void Drawable::setStateSet(osg::StateSet* stateset) itr!=_parents.end(); ++itr) { - (*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta_update); + (*itr)->setNumChildrenRequiringUpdateTraversal( (*itr)->getNumChildrenRequiringUpdateTraversal()+delta_update ); } } @@ -354,13 +360,82 @@ void Drawable::setStateSet(osg::StateSet* stateset) itr!=_parents.end(); ++itr) { - (*itr)->setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta_event); + (*itr)->setNumChildrenRequiringEventTraversal( (*itr)->getNumChildrenRequiringEventTraversal()+delta_event ); } } } +void Drawable::setNumChildrenRequiringUpdateTraversal(unsigned int num) +{ + // if no changes just return. + if (_numChildrenRequiringUpdateTraversal==num) return; + + // note, if _updateCallback is set then the + // parents won't be affected by any changes to + // _numChildrenRequiringUpdateTraversal so no need to inform them. + if (!_updateCallback && !_parents.empty()) + { + // need to pass on changes to parents. + int delta = 0; + if (_numChildrenRequiringUpdateTraversal>0) --delta; + if (num>0) ++delta; + if (delta!=0) + { + // the number of callbacks has changed, need to pass this + // on to parents so they know whether app traversal is + // reqired on this subgraph. + for(ParentList::iterator itr =_parents.begin(); + itr != _parents.end(); + ++itr) + { + (*itr)->setNumChildrenRequiringUpdateTraversal( (*itr)->getNumChildrenRequiringUpdateTraversal()+delta ); + } + + } + } + + // finally update this objects value. + _numChildrenRequiringUpdateTraversal=num; + +} + + +void Drawable::setNumChildrenRequiringEventTraversal(unsigned int num) +{ + // if no changes just return. + if (_numChildrenRequiringEventTraversal==num) return; + + // note, if _eventCallback is set then the + // parents won't be affected by any changes to + // _numChildrenRequiringEventTraversal so no need to inform them. + if (!_eventCallback && !_parents.empty()) + { + // need to pass on changes to parents. + int delta = 0; + if (_numChildrenRequiringEventTraversal>0) --delta; + if (num>0) ++delta; + if (delta!=0) + { + // the number of callbacks has changed, need to pass this + // on to parents so they know whether app traversal is + // reqired on this subgraph. + for(ParentList::iterator itr =_parents.begin(); + itr != _parents.end(); + ++itr) + { + (*itr)->setNumChildrenRequiringEventTraversal( (*itr)->getNumChildrenRequiringEventTraversal()+delta ); + } + + } + } + + // finally Event this objects value. + _numChildrenRequiringEventTraversal=num; + +} + osg::StateSet* Drawable::getOrCreateStateSet() { if (!_stateset) setStateSet(new StateSet); @@ -568,7 +643,7 @@ void Drawable::setEventCallback(EventCallback* ac) itr!=_parents.end(); ++itr) { - (*itr)->setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta); + (*itr)->setNumChildrenRequiringEventTraversal( (*itr)->getNumChildrenRequiringEventTraversal()+delta ); } } } diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index aba5b9742..b2de97c81 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -147,7 +147,10 @@ StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop) _binNum = rhs._binNum; _binName = rhs._binName; + _updateCallback = rhs._updateCallback; _numChildrenRequiringUpdateTraversal = rhs._numChildrenRequiringUpdateTraversal; + + _eventCallback = rhs._eventCallback; _numChildrenRequiringEventTraversal = rhs._numChildrenRequiringEventTraversal; } @@ -1537,7 +1540,7 @@ void StateSet::setNumChildrenRequiringUpdateTraversal(unsigned int num) osg::Drawable* drawable = dynamic_cast(*itr); if (drawable) { - //drawable->setNumChildrenRequiringUpdateTraversal(drawable->getNumChildrenRequiringUpdateTraversal()+delta); + drawable->setNumChildrenRequiringUpdateTraversal(drawable->getNumChildrenRequiringUpdateTraversal()+delta); } else { @@ -1582,7 +1585,7 @@ void StateSet::setNumChildrenRequiringEventTraversal(unsigned int num) osg::Drawable* drawable = dynamic_cast(*itr); if (drawable) { - //drawable->setNumChildrenRequiringEventTraversal(drawable->getNumChildrenRequiringEventTraversal()+delta); + drawable->setNumChildrenRequiringEventTraversal(drawable->getNumChildrenRequiringEventTraversal()+delta); } else {