A solution perhaps?
In desperation to fix the problem, I went into the
SoSeparator code, and change part of SoSeparator::getBoundingBox().
In the section where the code decides it needs to create
a new bounding box cache, I moved the
SoGroup::getBoundingBox(action);
so that it is executed BEFORE the bounding box cache is created.
The order apparent matters, but I'm not sure which is correct.
I'm glad that it fixed my immediate problem, but will it cause
other unforeseen bugs?
Chester
Original...
(starting at around line 418)
state->push();
// Set the local bbox matrix to identity, so shapes' bounding
// boxes will be transformed into our local space
SoLocalBBoxMatrixElement::makeIdentity(state);
// Build cache. We've already tested for a valid cache, so the
// only other possibility is for a NULL cache or an invalid one
if (bboxCache != NULL)
bboxCache->unref();
// Create a new cache:
bboxCache = new SoBoundingBoxCache(state);
bboxCache->ref();
SoCacheElement::set(state, bboxCache);
// Traverse the kids
SoGroup::getBoundingBox(action);
// This has to be done before the extendBy
state->pop();
Changed...
state->push();
// Set the local bbox matrix to identity, so shapes' bounding
// boxes will be transformed into our local space
SoLocalBBoxMatrixElement::makeIdentity(state);
// Traverse the kids
SoGroup::getBoundingBox(action);
// Build cache. We've already tested for a valid cache, so the
// only other possibility is for a NULL cache or an invalid one
if (bboxCache != NULL)
bboxCache->unref();
// Create a new cache:
bboxCache = new SoBoundingBoxCache(state);
bboxCache->ref();
SoCacheElement::set(state, bboxCache);
// This has to be done before the extendBy
state->pop();
Chester Liu wrote:
>
> I see!
> That explains it. Is there a way to look at an
> element without creating a cache dependency?
> Like a <peek>.
>
> I performed the following experiment. SoCache has
> a method called isValid(). Basically it checks whether
> the elements in the cache are consistent with the state.
> I put in a bit of code which prints the dependent elements.
>
> Interestingly, if I don't include the SoViewVolumeElement::get(...),
> then the cache reports that there are 0 cache dependencies.
> However, if I put in the viewvolume statement, then
> it reports the following dependencies:
>
> the element is: SoOverrideElement
> the element is: SoShapeStyleElement
> the element is: SoViewVolumeElement
>
> CACHE DEBUG: cache(0x109a2b20) not valid because element
> SoViewVolumeElement does not match:
> ------
> Element in state:
> ------
> Element in cache:
>
> So, to answer Gavin's question,
> without the offending code, I can move the camera around
> and the bounding box cache doesn't break. (It shouldn't break,
> because the stuff beneath the separator doesn't change, only
> the camera above it.)
>
> My simplified scenegraph is like this:
>
> camera
> |
> separator (render culling turned ON)
> |
> shape
>
> The shape needs to know what the viewvolume is, and only
> change itself (rarely) if certain criteria are met. Most
> of the time it's static and this should NOT break the separator's
> cache. For example, a level-of-detail node needs to know
> the viewvolume, but it only switches its children infrequently.
>
> Thanks for more insights!
>
> Chester
>
> Thanks,
> Chester
>
> Paul Strauss wrote:
> >
> > Gavin Andresen wrote:
> >
> > >
> > > > const SbViewVolume & viewVol =
> > > > SoViewVolumeElement::get(action->getState());
> > > >
> > > > const SbMatrix & viewMat =
> > > >SoViewingMatrixElement::get(action->getState());
> > > >
> > > >
> > > >The separator reports that the bounding box cache (used for
> > > >render culling) is being invalidated. If I comment out these
> > > >lines of code, it's fine.
> > > >
> > > >Why?
> > >
> > > The ViewingMatrix and ViewVolume change whenever the camera moves, so if
> > > your GetBoundingBox method relies on them, then the bbox cache SHOULD be
> > > invalidated.
> >
> > One of the keys to answering Chester's question is that calling the
> > "get()" methods on the elements results in a cache dependency being
> > created on those elements. So, yes, just looking at the values of the
> > elements (during cache construction) will change the behavior of the
> > cache.
> >
|