John Rohlf (jrohlf++at++tubes)
Wed, 19 Apr 95 13:34:10 PDT
>
> long
> exitPortalCull(pfTraverser *trav, void *data)
> {
> pfPortalData *p = (pfPortalData *) data;
> pfChannel *chan;
> pfGroup *node;
>
> if (!globalUsePortals) /* First, are portals enabled? */
> return PFTRAV_PRUNE; /* I think this is ignored */
>
> chan = pfGetTravChan(trav); /* Get the current view frustum */
> node = (pfGroup *) pfGetTravNode(trav);
>
> if (chan == NULL) /* If this is an intersection, prune */
> return PFTRAV_PRUNE; /* I think this is ignored */
>
> pfRemoveChild(node, p->attached_cell);
> return PFTRAV_CONT; /* I think this is ignored */
> }
>
>
You have found a bug in the traversal logic.
pfGetTravNode(trav) returns the last child of the group to postCull()
rather than the group itself (preCull() is OK). You could use
node = pfGetChild(pfGetParent(pfGetTravNode(trav), 0), 0)
if you know that the portal group is always the first child.
However, I suggest you try a different approach which does
not modify the scene graph during traversal. The culling traversal does
not understand all topological changes to the scene graph during the
traversal. We could make it a little more
aware but in general changing the scene graph during a traversal
is a bit risky as well as hard to define, e.g.:
pfGroup::cull()
{
for (i=0; i<childList.getNum(); i++)
childList[i]->cull();
}
What should happen if child 0 removes itself from the graph in its
preCull callback? The act of removing child 0 shifts children 1 through n-1
to the left by one. Then i++ will increment i to 1 so that the
new child 0, which used to be child 1, will be skipped and will
not be culled.
Why not attach the callbacks to attached_cell? Then you can
call pfCullResult(PFIS_FALSE) or pfCullResult(PFIS_MAYBE | PFIS_TRUE)
in the preCull callback if the cell is not visible or visible respectively.
pfCullResult is the intended mechanism for your kind of culling.
Note that PFTRAV_PRUNE is indeed ignored in the postCull()
since you've already traversed the group's children. If you want
to aggressively terminate traversal, return PFTRAV_TERM but use
this with caution.
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:51:24 PDT