From 63e4587a8806418dabd2aaf26969fb568827ccb1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 24 Oct 2004 13:51:44 +0000 Subject: [PATCH] Added s/getEventCallback support into osg::Node, and an EVENT_VISITOR type into NodeVisitor. --- include/osg/Node | 18 +++++++++ include/osg/NodeVisitor | 1 + src/osg/Group.cpp | 59 +++++++++++++++++++++++++----- src/osg/Node.cpp | 81 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 10 deletions(-) diff --git a/include/osg/Node b/include/osg/Node index 3416bb32a..24f7d1b55 100644 --- a/include/osg/Node +++ b/include/osg/Node @@ -140,6 +140,20 @@ class SG_EXPORT Node : public Object inline unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; } + /** Set update node callback, called during update traversal. */ + void setEventCallback(NodeCallback* nc); + + /** Get update node callback, called during update traversal. */ + inline NodeCallback* getEventCallback() { return _eventCallback.get(); } + + /** Get const update node callback, called during update traversal. */ + inline const NodeCallback* getEventCallback() const { return _eventCallback.get(); } + + /** Get the number of Children of this node which require App traversal, + * since they have an AppCallback attached to them or their children.*/ + inline unsigned int getNumChildrenRequiringEventTraversal() const { return _numChildrenRequiringEventTraversal; } + + /** Set cull node callback, called during cull traversal. */ void setCullCallback(NodeCallback* nc) { _cullCallback = nc; } @@ -259,6 +273,10 @@ class SG_EXPORT Node : public Object unsigned int _numChildrenRequiringUpdateTraversal; void setNumChildrenRequiringUpdateTraversal(unsigned int num); + ref_ptr _eventCallback; + unsigned int _numChildrenRequiringEventTraversal; + void setNumChildrenRequiringEventTraversal(unsigned int num); + ref_ptr _cullCallback; bool _cullingActive; diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index bf5f19709..c1d254c91 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -69,6 +69,7 @@ class SG_EXPORT NodeVisitor : public virtual Referenced { NODE_VISITOR = 0, UPDATE_VISITOR, + EVENT_VISITOR, COLLECT_OCCLUDER_VISITOR, CULL_VISITOR }; diff --git a/src/osg/Group.cpp b/src/osg/Group.cpp index 4e55230c4..47faa05c1 100644 --- a/src/osg/Group.cpp +++ b/src/osg/Group.cpp @@ -111,6 +111,16 @@ bool Group::insertChild( unsigned int index, Node *child ) ); } + // could now require app traversal thanks to the new subgraph, + // so need to check and update if required. + if (child->getNumChildrenRequiringEventTraversal()>0 || + child->getEventCallback()) + { + setNumChildrenRequiringEventTraversal( + getNumChildrenRequiringEventTraversal()+1 + ); + } + // could now require disabling of culling thanks to the new subgraph, // so need to check and update if required. if (child->getNumChildrenWithCullingDisabled()>0 || @@ -151,7 +161,8 @@ bool Group::removeChild(unsigned int pos,unsigned int numChildrenToRemove) endOfRemoveRange=_children.size(); } - unsigned int appCallbackRemoved = 0; + unsigned int updateCallbackRemoved = 0; + unsigned int eventCallbackRemoved = 0; unsigned int numChildrenWithCullingDisabledRemoved = 0; unsigned int numChildrenWithOccludersRemoved = 0; @@ -161,7 +172,9 @@ bool Group::removeChild(unsigned int pos,unsigned int numChildrenToRemove) // remove this Geode from the child parent list. child->removeParent(this); - if (child->getNumChildrenRequiringUpdateTraversal()>0 || child->getUpdateCallback()) ++appCallbackRemoved; + if (child->getNumChildrenRequiringUpdateTraversal()>0 || child->getUpdateCallback()) ++updateCallbackRemoved; + + if (child->getNumChildrenRequiringEventTraversal()>0 || child->getEventCallback()) ++eventCallbackRemoved; if (child->getNumChildrenWithCullingDisabled()>0 || !child->getCullingActive()) ++numChildrenWithCullingDisabledRemoved; @@ -173,11 +186,16 @@ bool Group::removeChild(unsigned int pos,unsigned int numChildrenToRemove) childRemoved(pos,endOfRemoveRange-pos); - if (appCallbackRemoved) + if (updateCallbackRemoved) { - setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-appCallbackRemoved); + setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved); } + if (eventCallbackRemoved) + { + setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved); + } + if (numChildrenWithCullingDisabledRemoved) { setNumChildrenWithCullingDisabled(getNumChildrenWithCullingDisabled()-numChildrenWithCullingDisabledRemoved); @@ -229,24 +247,45 @@ bool Group::setChild( unsigned int i, Node* newNode ) dirtyBound(); - // could now require app traversal thanks to the new subgraph, + // could now require update traversal thanks to the new subgraph, // so need to check and update if required. - int delta_numChildrenRequiringAppTraversal = 0; + int delta_numChildrenRequiringUpdateTraversal = 0; if (origNode->getNumChildrenRequiringUpdateTraversal()>0 || origNode->getUpdateCallback()) { - --delta_numChildrenRequiringAppTraversal; + --delta_numChildrenRequiringUpdateTraversal; } if (newNode->getNumChildrenRequiringUpdateTraversal()>0 || newNode->getUpdateCallback()) { - ++delta_numChildrenRequiringAppTraversal; + ++delta_numChildrenRequiringUpdateTraversal; } - if (delta_numChildrenRequiringAppTraversal!=0) + if (delta_numChildrenRequiringUpdateTraversal!=0) { setNumChildrenRequiringUpdateTraversal( - getNumChildrenRequiringUpdateTraversal()+delta_numChildrenRequiringAppTraversal + getNumChildrenRequiringUpdateTraversal()+delta_numChildrenRequiringUpdateTraversal + ); + } + + // could now require event traversal thanks to the new subgraph, + // so need to check and Event if required. + int delta_numChildrenRequiringEventTraversal = 0; + if (origNode->getNumChildrenRequiringEventTraversal()>0 || + origNode->getEventCallback()) + { + --delta_numChildrenRequiringEventTraversal; + } + if (newNode->getNumChildrenRequiringEventTraversal()>0 || + newNode->getEventCallback()) + { + ++delta_numChildrenRequiringEventTraversal; + } + + if (delta_numChildrenRequiringEventTraversal!=0) + { + setNumChildrenRequiringEventTraversal( + getNumChildrenRequiringEventTraversal()+delta_numChildrenRequiringEventTraversal ); } diff --git a/src/osg/Node.cpp b/src/osg/Node.cpp index 50cf2231e..7983a526b 100644 --- a/src/osg/Node.cpp +++ b/src/osg/Node.cpp @@ -28,6 +28,8 @@ Node::Node() _numChildrenRequiringUpdateTraversal = 0; + _numChildrenRequiringEventTraversal = 0; + _cullingActive = true; _numChildrenWithCullingDisabled = 0; @@ -42,6 +44,7 @@ Node::Node(const Node& node,const CopyOp& copyop): _parents(), // leave empty as parentList is managed by Group. _updateCallback(node._updateCallback), _numChildrenRequiringUpdateTraversal(0), // assume no children yet. + _numChildrenRequiringEventTraversal(0), // assume no children yet. _cullCallback(node._cullCallback), _cullingActive(node._cullingActive), _numChildrenWithCullingDisabled(0), // assume no children yet. @@ -167,6 +170,84 @@ void Node::setNumChildrenRequiringUpdateTraversal(unsigned int num) } + +void Node::setEventCallback(NodeCallback* nc) +{ + // if no changes just return. + if (_eventCallback==nc) return; + + // app callback has been changed, will need to Event + // both _EventCallback and possibly the numChildrenRequiringAppTraversal + // if the number of callbacks changes. + + + // Event the parents numChildrenRequiringAppTraversal + // note, if _numChildrenRequiringEventTraversal!=0 then the + // parents won't be affected by any app callback change, + // so no need to inform them. + if (_numChildrenRequiringEventTraversal==0 && !_parents.empty()) + { + int delta = 0; + if (_eventCallback.valid()) --delta; + if (nc) ++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 ); + } + + } + } + + // set the app callback itself. + _eventCallback = nc; + +} + +void Node::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; + +} + void Node::setCullingActive(bool active) { // if no changes just return.