Hi Gerrit,
thanks for your answers.
Gerrit Voss wrote:
> On Thu, 2007-07-19 at 13:29 +0200, Carsten Neumann wrote:
>> I'm currently trying to understand the details of the
>> RenderTraversalAction and a couple of questions have come up:
>>
>> 1) RTA::recurceNoNodeCallbacks looks as if it should be used from cores
>> that want to traverse the tree below the current node (it basically does
>> the same as Action::recurse but does not call callEnter/callLeave on the
>> current node). If that is the intended use then it is broken for the
>> case where _newList is used and two or more passes over the subtree are
>> required, because the first call to callNewList will destroy the
>> contents of _newList. Is this a known/intended limitation ? I think
>> this can be fixed by introducing a special variant of callNewList that
>> swaps the local nodeList with _newList before it returns. [1]
>
> that is half NI as the calling core is expected to control the
> newlist. So in one way of viewing it the calling core/element could be
> expected to take care of that.
yes, agreed. I've attached a new patch that adds access functions for
the _newList to Action.
Now the calling core can modify _newList between traversals, but by
default its contents are kept unchanged (to avoid confusion I renamed
some functions getNNodes -> getNChildren and getNode -> getChild,
because they always refer to the children of the current node).
I also removed the std::vector<NodePtr> *_actList because it was only
set to non-null values inside callNewList, so from a core's callback it
was always NULL.
What do you think about it ?
Thanks,
Carsten
diff -r ec6ec2099a07 Source/System/Action/Base/OSGAction.cpp
--- a/Source/System/Action/Base/OSGAction.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/Base/OSGAction.cpp Sat Jul 21 13:16:39 2007 +0200
@@ -320,18 +320,16 @@ ActionBase::ResultE Action::recurse(Node
if(core == NullFC)
{
- SWARNING << "recurse: core is Null, don't know what to do!"
- << std::endl;
- return Quit;
+ SWARNING << "Action::recurse: core is Null, don't know what to do!"
+ << endLog;
+ return Quit;
}
Action::ResultE result;
- _actList = NULL;
_actNode = node;
_newList.clear();
-
_useNewList = false;
result = callEnter(node);
@@ -380,6 +378,58 @@ ActionBase::ResultE Action::recurse(Node
return result;
}
+ActionBase::ResultE Action::recurseChildren(NodePtrConstArg node)
+{
+ if(node == NullFC)
+ return Continue;
+
+ if((node->getTravMask() & getTravMask()) == 0)
+ return Continue;
+
+#if OSG_1_COMPAT
+ if(node->getOcclusionMask() & 1)
+ return Continue;
+#endif
+
+ NodeCorePtr core = node->getCore();
+
+ if(core == NullFC)
+ {
+ SWARNING << "Action::recurseChildren: core is Null, don't know what to do!"
+ << endLog;
+ return Quit;
+ }
+
+ Action::ResultE result;
+
+ _actNode = node;
+
+ if(! _newList.empty())
+ {
+ result = callNewListChildren();
+ }
+ else if(! _useNewList) // new list is empty, but not used?
+ {
+ std::vector<NodePtr>::const_iterator nodeIt = node->getMFChildren()->begin();
+ std::vector<NodePtr>::const_iterator nodeEnd = node->getMFChildren()->end();
+
+ for(; nodeIt != nodeEnd; ++nodeIt)
+ {
+ result = recurse(*nodeIt);
+
+ if(result != Continue)
+ break;
+ }
+ }
+
+ _actNode = node;
+
+ if(result == Skip)
+ return Continue;
+
+ return result;
+}
+
// call the _newList objects
ActionBase::ResultE Action::callNewList(void)
{
@@ -390,14 +440,13 @@ ActionBase::ResultE Action::callNewList(
std::vector<NodePtr> nodeList;
nodeList.swap(_newList);
-
- std::vector<NodePtr>::iterator it;
-
- _actList = &nodeList;
-
- for(it = nodeList.begin(); it != nodeList.end(); ++it)
- {
- result = recurse(*it);
+
+ std::vector<NodePtr>::const_iterator nodeIt = nodeList.begin();
+ std::vector<NodePtr>::const_iterator nodeEnd = nodeList.end();
+
+ for(; nodeIt != nodeEnd; ++nodeIt)
+ {
+ result = recurse(*nodeIt);
if(result != Continue)
break;
@@ -406,6 +455,30 @@ ActionBase::ResultE Action::callNewList(
return result;
}
+ActionBase::ResultE Action::callNewListChildren(void)
+{
+ ResultE result = Continue;
+ std::vector<NodePtr> nodeList;
+
+ // copy _newList, so it can be used on the next level
+ nodeList.swap(_newList);
+
+ std::vector<NodePtr>::const_iterator nodeIt = nodeList.begin();
+ std::vector<NodePtr>::const_iterator nodeEnd = nodeList.end();
+
+ for(; nodeIt != nodeEnd; ++nodeIt)
+ {
+ result = recurse(*nodeIt);
+
+ if(result != Continue)
+ break;
+ }
+
+ // restore _newList for next pass
+ nodeList.swap(_newList);
+
+ return result;
+}
// call the start function and its results
diff -r ec6ec2099a07 Source/System/Action/Base/OSGAction.h
--- a/Source/System/Action/Base/OSGAction.h Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/Base/OSGAction.h Sat Jul 21 13:21:07 2007 +0200
@@ -97,6 +97,9 @@ class OSG_SYSTEM_DLLMAPPING Action : pub
typedef ActionBase::ResultE (NodeCore::*Callback)(Action *);
+ typedef std::vector<NodePtr> NodeStore;
+ typedef NodeStore::iterator NodeStoreIt;
+ typedef NodeStore::const_iterator NodeStoreConstIt;
//-----------------------------------------------------------------------
// types
@@ -162,26 +165,29 @@ class OSG_SYSTEM_DLLMAPPING Action : pub
/*------------------------- your_category -------------------------------*/
- // Node access:
- // the number of active nodes
-
- UInt32 getNNodes (void ) const;
-
- // you can access a single node by getNode
-
- NodePtr getNode (int index);
-
- // per default all child nodes are traversed. If addNode is called,
- // only the added nodes will be traversed.
-
- void addNode (NodePtrConstArg node);
-
- // Common case: going through the children list and picking up some of
- // them, but it's not clear if any at all. Call useNodeList() and then
- // addNode() for every node to traverse, or not at all.
-
- void useNodeList(void );
-
+ void useNodeList (void );
+ void setUseNodeList(bool val = true);
+ bool getUseNodeList(void ) const;
+
+ const NodeStore &getNodes (void ) const;
+ NodeStore &getNodes (void );
+
+ void addNode (NodePtrConstArg node );
+
+ NodeStoreConstIt beginNodes (void ) const;
+ NodeStoreIt beginNodes (void );
+
+ NodeStoreConstIt endNodes (void ) const;
+ NodeStoreIt endNodes (void );
+
+ UInt32 getNChildren (void ) const;
+ NodePtr getChild (UInt32 index );
+
+ // recurse through the node
+
+ ResultE recurse (NodePtrConstArg node);
+ ResultE recurseChildren(NodePtrConstArg node);
+
/*------------------------- assignment ----------------------------------*/
UInt32 getTravMask (void ) const;
@@ -238,13 +244,10 @@ class OSG_SYSTEM_DLLMAPPING Action : pub
virtual ResultE start(void );
virtual ResultE stop (ResultE res); // res is the exit code of the action
- // recurse through the node
-
- ResultE recurse(NodePtrConstArg node);
-
// call the _newList list of nodes
- ResultE callNewList(void);
+ ResultE callNewList (void);
+ ResultE callNewListChildren(void);
// access default functors
@@ -269,15 +272,12 @@ class OSG_SYSTEM_DLLMAPPING Action : pub
// instance variables
//-----------------------------------------------------------------------
- NodePtr _actNode; // the node being traversed right now
-
- std::vector<NodePtr> *_actList; // list of active objects for this level
- // if empty, use the actNode's children
-
- bool _useNewList;// set by clearNodeList
- std::vector<NodePtr> _newList; // list of active object for this level
-
- UInt32 _travMask;
+ NodePtr _actNode; // the node being traversed right now
+
+ bool _useNewList; // set by clearNodeList
+ NodeStore _newList; // list of active object for this level
+
+ UInt32 _travMask;
private:
diff -r ec6ec2099a07 Source/System/Action/Base/OSGAction.inl
--- a/Source/System/Action/Base/OSGAction.inl Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/Base/OSGAction.inl Sat Jul 21 13:22:08 2007 +0200
@@ -48,7 +48,6 @@ NodePtr Action::getActNode(void)
return _actNode;
}
-
inline
void Action::setActNode(NodePtrConstArg node)
{
@@ -56,16 +55,33 @@ void Action::setActNode(NodePtrConstArg
}
inline
-NodePtr Action::getNode(int index)
-{
- if(_actList == NULL)
- {
- return _actNode->getChild(index);
- }
- else
- {
- return (*_actList)[index];
- }
+void Action::useNodeList(void)
+{
+ _useNewList = true;
+}
+
+inline
+void Action::setUseNodeList(bool val)
+{
+ _useNewList = val;
+}
+
+inline
+bool Action::getUseNodeList(void) const
+{
+ return _useNewList;
+}
+
+inline
+const Action::NodeStore &Action::getNodes(void) const
+{
+ return _newList;
+}
+
+inline
+Action::NodeStore &Action::getNodes(void)
+{
+ return _newList;
}
inline
@@ -75,24 +91,40 @@ void Action::addNode(NodePtrConstArg nod
}
inline
-void Action::useNodeList(void)
-{
- _useNewList = true;
-}
-
-inline
-UInt32 Action::getNNodes(void) const
-{
- if(_actList == NULL)
- {
- return _actNode->getNChildren();
- }
- else
- {
- return (*_actList).size();
- }
-}
-
+Action::NodeStoreConstIt Action::beginNodes(void) const
+{
+ return _newList.begin();
+}
+
+inline
+Action::NodeStoreIt Action::beginNodes(void)
+{
+ return _newList.begin();
+}
+
+inline
+Action::NodeStoreConstIt Action::endNodes(void) const
+{
+ return _newList.end();
+}
+
+inline
+Action::NodeStoreIt Action::endNodes(void)
+{
+ return _newList.end();
+}
+
+inline
+UInt32 Action::getNChildren(void) const
+{
+ return _actNode->getNChildren();
+}
+
+inline
+NodePtr Action::getChild(UInt32 index)
+{
+ return _actNode->getChild(index);
+}
inline
UInt32 Action::getTravMask(void) const
diff -r ec6ec2099a07 Source/System/Action/Base/OSGDrawActionBase.cpp
--- a/Source/System/Action/Base/OSGDrawActionBase.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/Base/OSGDrawActionBase.cpp Sat Jul 21 13:30:12 2007 +0200
@@ -321,21 +321,20 @@ UInt32 DrawActionBase::selectVisibles(vo
UInt32 DrawActionBase::selectVisibles(void)
{
if(getFrustumCulling() == false)
- return getNNodes();
+ return getNChildren();
useNodeList();
Color3r col;
-
- UInt32 count = 0;
-
- for(UInt32 i = 0; i < getNNodes(); i++)
- {
- if(isVisible(getCPtr(getNode(i))))
+ UInt32 count = 0;
+
+ for(UInt32 i = 0; i < getNChildren(); ++i)
+ {
+ if(isVisible(getCPtr(getChild(i))))
{
col.setValuesRGB(0.f,1.f,0.f);
- addNode(getNode(i));
+ addNode(getChild(i));
++count;
}
@@ -346,7 +345,7 @@ UInt32 DrawActionBase::selectVisibles(vo
if(getVolumeDrawing())
{
- dropVolume(this, getNode(i), col);
+ dropVolume(this, getChild(i), col);
}
}
diff -r ec6ec2099a07 Source/System/Action/RenderTraversal/OSGRenderTraversalAction.cpp
--- a/Source/System/Action/RenderTraversal/OSGRenderTraversalAction.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/RenderTraversal/OSGRenderTraversalAction.cpp Thu Jul 19 12:59:39 2007 +0200
@@ -437,59 +437,6 @@ UInt32 RenderTraversalAction::getCurrent
return _currentBuffer;
}
-
-/*-------------------------- your_category---------------------------------*/
-
-ActionBase::ResultE RenderTraversalAction::recurceNoNodeCallbacks(
- NodePtrConstArg node)
-{
- if(node == NullFC)
- return Continue;
-
- if((node->getTravMask() & getTravMask()) == 0)
- return Continue;
-
- NodeCorePtr core = node->getCore();
-
- if(core == NullFC)
- {
- SWARNING << "recurse: core is Null, don't know what to do!"
- << std::endl;
- return Quit;
- }
-
- Action::ResultE result;
-
- _actList = NULL;
- _actNode = node;
-
-
- if(! _newList.empty())
- {
- result = callNewList();
- }
- else if(! _useNewList) // new list is empty, but not used?
- {
- std::vector<NodePtr>::const_iterator it;
-
- for( it = node->getMFChildren()->begin();
- it != node->getMFChildren()->end();
- ++it)
- {
- result = recurse(*it);
-
- if(result != Continue)
- break;
- }
- }
-
- _actNode = node;
-
- if(result == Skip)
- return Continue;
-
- return result;
-}
Action::ResultE RenderTraversalAction::start(void)
{
diff -r ec6ec2099a07 Source/System/Action/RenderTraversal/OSGRenderTraversalAction.h
--- a/Source/System/Action/RenderTraversal/OSGRenderTraversalAction.h Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/RenderTraversal/OSGRenderTraversalAction.h Thu Jul 19 12:58:45 2007 +0200
@@ -133,10 +133,6 @@ class OSG_RENDERTRAV_DLLMAPPING RenderTr
//-----------------------------------------------------------------------
virtual ~RenderTraversalAction(void);
-
- /*------------------------- your_category -------------------------------*/
-
- ResultE recurceNoNodeCallbacks(NodePtrConstArg node);
/*------------------------- your_operators ------------------------------*/
diff -r ec6ec2099a07 Source/System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp
--- a/Source/System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp Sat Jul 21 13:57:46 2007 +0200
@@ -233,14 +233,14 @@ ActionBase::ResultE SwitchRenderEnter(co
RenderTraversalAction *pAction =
dynamic_cast<RenderTraversalAction*>(action);
- if((pThis->getChoice() >= 0 ) &&
- (static_cast<UInt32>(pThis->getChoice()) < pAction->getNNodes()) )
+ if((pThis->getChoice() >= 0 ) &&
+ (static_cast<UInt32>(pThis->getChoice()) < pAction->getNChildren()) )
{
pAction->useNodeList();
- if(pAction->isVisible(getCPtr(pAction->getNode(pThis->getChoice()))))
- {
- pAction->addNode(pAction->getNode(pThis->getChoice()));
+ if(pAction->isVisible(getCPtr(pAction->getChild(pThis->getChoice()))))
+ {
+ pAction->addNode(pAction->getChild(pThis->getChoice()));
}
returnValue = GroupRenderEnter(pCore, action);
@@ -865,7 +865,7 @@ ActionBase::ResultE HDRStageRenderEnter(
NodePtr pActNode = a->getActNode();
- a->recurceNoNodeCallbacks(pActNode);
+ a->recurseChildren(pActNode);
}
a->popPartition();
diff -r ec6ec2099a07 Source/System/Action/RenderTraversal/OSGScreenLOD.cpp
--- a/Source/System/Action/RenderTraversal/OSGScreenLOD.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/Action/RenderTraversal/OSGScreenLOD.cpp Sat Jul 21 14:03:38 2007 +0200
@@ -88,7 +88,7 @@ ActionBase::ResultE ScreenLOD::renderEnt
{
RenderTraversalAction *ra = dynamic_cast<RenderTraversalAction*>(action);
- UInt32 numLevels = action->getNNodes();
+ UInt32 numLevels = action->getNChildren();
Int32 index = 0;
UInt32 numCovOverrides = getMFCoverageOverride()->size();
@@ -155,7 +155,7 @@ ActionBase::ResultE ScreenLOD::renderEnt
if (!use_overrides)
{
//Get max LOD number of triangles
- NodePtr pmax = action->getNode(0);
+ NodePtr pmax = action->getChild(0);
GeoStatsAttachmentPtr st_max = GeoStatsAttachment::get(pmax);
if(st_max == NullFC)
{
@@ -165,7 +165,7 @@ ActionBase::ResultE ScreenLOD::renderEnt
st_max->validate();
//Get min LOD number of triangles
- NodePtr pmin = action->getNode(numLevels-1);
+ NodePtr pmin = action->getChild(numLevels-1);
GeoStatsAttachmentPtr st_min = GeoStatsAttachment::get(pmin);
if(st_min == NullFC)
{
@@ -242,9 +242,9 @@ ActionBase::ResultE ScreenLOD::renderEnt
//}
ra->useNodeList();
- if(ra->isVisible(getCPtr(action->getNode(index))))
- {
- ra->addNode(action->getNode(index));
+ if(ra->isVisible(getCPtr(action->getChild(index))))
+ {
+ ra->addNode(action->getChild(index));
}
return ActionBase::Continue;
diff -r ec6ec2099a07 Source/System/NodeCores/Groups/Light/Shadow/Engines/OSGSimpleShadowMapEngine.cpp
--- a/Source/System/NodeCores/Groups/Light/Shadow/Engines/OSGSimpleShadowMapEngine.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/NodeCores/Groups/Light/Shadow/Engines/OSGSimpleShadowMapEngine.cpp Wed Jul 18 14:02:38 2007 +0200
@@ -579,7 +579,7 @@ void SimpleShadowMapEngine::doLightPass(
// lightRenderEnter(pLight, pAction);
- pAction->recurceNoNodeCallbacks(pActNode);
+ pAction->recurseChildren(pActNode);
pAction->popState();
@@ -621,7 +621,7 @@ void SimpleShadowMapEngine::doAmbientPas
<< std::endl;
}
- pAction->recurceNoNodeCallbacks(pAction->getActNode());
+ pAction->recurseChildren(pAction->getActNode());
pAction->popState();
@@ -784,7 +784,7 @@ void SimpleShadowMapEngine::doFinalPass(
lightRenderEnter(pLight, pAction);
- pAction->recurceNoNodeCallbacks(pAction->getActNode());
+ pAction->recurseChildren(pAction->getActNode());
pAction->popState();
@@ -828,22 +828,22 @@ ActionBase::ResultE SimpleShadowMapEngin
{
if(0x0000 != (bvMask & bvDiffusePassMask))
{
- pAction->recurceNoNodeCallbacks(pAction->getActNode());
+ pAction->recurseChildren(pAction->getActNode());
setupCamera (pLight, eType, pAction, pEngineData);
- doFinalPass (pLight, pAction, pEngineData);
+ doFinalPass (pLight, pAction, pEngineData);
}
if(0x0000 != (bvMask & bvAmbientPassMask))
{
- pAction->recurceNoNodeCallbacks(pAction->getActNode());
+ pAction->recurseChildren(pAction->getActNode());
setupLightChunk(pLight, eType, pAction, pEngineData);
}
if(0x0000 != (bvMask & bvLightPassMask))
{
- pAction->recurceNoNodeCallbacks(pAction->getActNode());
+ pAction->recurseChildren(pAction->getActNode());
doLightPass (pLight, pAction, pEngineData);
}
diff -r ec6ec2099a07 Source/System/NodeCores/Groups/Misc/OSGDistanceLOD.inl
--- a/Source/System/NodeCores/Groups/Misc/OSGDistanceLOD.inl Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/NodeCores/Groups/Misc/OSGDistanceLOD.inl Sat Jul 21 13:43:17 2007 +0200
@@ -41,7 +41,7 @@ ActionBase::ResultE DistanceLOD::render(
{
RenderActionT *ra = dynamic_cast<RenderActionT *>(action);
- UInt32 numLevels = action->getNNodes();
+ UInt32 numLevels = action->getNChildren();
UInt32 numRanges = getMFRange()->size();
UInt32 limit = osgMin(numLevels, numRanges);
@@ -85,9 +85,9 @@ ActionBase::ResultE DistanceLOD::render(
index = osgMin(i, limit-1);
}
- if(ra->isVisible(getCPtr(action->getNode(index))))
+ if(ra->isVisible(getCPtr(action->getChild(index))))
{
- ra->addNode(action->getNode(index));
+ ra->addNode(action->getChild(index));
}
}
diff -r ec6ec2099a07 Source/System/NodeCores/Groups/Misc/OSGSwitch.cpp
--- a/Source/System/NodeCores/Groups/Misc/OSGSwitch.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/System/NodeCores/Groups/Misc/OSGSwitch.cpp Sat Jul 21 13:48:53 2007 +0200
@@ -101,14 +101,14 @@ ActionBase::ResultE Switch::render(Actio
DrawActionBase *da = dynamic_cast<DrawActionBase *>(action);
- if((getChoice() >= 0 ) &&
- (UInt32(getChoice()) < action->getNNodes()))
+ if((getChoice() >= 0 ) &&
+ (UInt32(getChoice()) < action->getNChildren()))
{
da->useNodeList();
- if(da->isVisible(getCPtr(action->getNode(getChoice()))))
+ if(da->isVisible(getCPtr(action->getChild(getChoice()))))
{
- da->addNode(action->getNode(getChoice()));
+ da->addNode(action->getChild(getChoice()));
}
}
else if(getChoice() == ALL)
@@ -132,10 +132,10 @@ ActionBase::ResultE Switch::intersect(Ac
ActionBase::ResultE returnValue = ActionBase::Continue;
IntersectAction *da = dynamic_cast<IntersectAction *>(action);
- if((getChoice() >= 0 ) &&
- (UInt32(getChoice()) < action->getNNodes()))
+ if((getChoice() >= 0 ) &&
+ (UInt32(getChoice()) < action->getNChildren()))
{
- da->addNode(action->getNode(getChoice()));
+ da->addNode(action->getChild(getChoice()));
}
else if(getChoice() == ALL)
{
diff -r ec6ec2099a07 Source/Test/RenderTraversalLib/OSGRenderTraversalActionTestInit.cpp
--- a/Source/Test/RenderTraversalLib/OSGRenderTraversalActionTestInit.cpp Thu Jul 05 10:28:45 2007 +0200
+++ b/Source/Test/RenderTraversalLib/OSGRenderTraversalActionTestInit.cpp Wed Jul 18 14:03:22 2007 +0200
@@ -203,7 +203,7 @@ ActionBase::ResultE TestMultiPartStageRe
NodePtr pActNode = a->getActNode();
- a->recurceNoNodeCallbacks(pActNode);
+ a->recurseChildren(pActNode);
}
pStage->popPartition(a);
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core