Show
Ignore:
Timestamp:
02/26/10 11:13:28 (3 years ago)
Author:
robert
Message:

From Paul Martz, "The changes are very similar to Magne's, except they now take the near plane into account. The changes are:

  • Change OcclusionQueryNode::getPassed to take a NodeVisitor? rather than the distance from BS center to the eye point. Change where CullVisitor? calls this method to use the new parameters.
  • getPassed now exits early and returns true to avoid blinking / blink-in of geometry for the first frame or for out-of-range LOD children coming back into view.
  • getPassed now considers the distance from the near plane to the bounding sphere (rather than eye point to bounding sphere) when determining if the viewer is "inside" the bounding sphere or not."
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osg/OcclusionQueryNode.cpp

    r10933 r11127  
    553553 
    554554bool 
    555 OcclusionQueryNode::getPassed( const osg::Camera* camera, float distanceToEyePoint ) 
     555OcclusionQueryNode::getPassed( const osg::Camera* camera, osg::NodeVisitor& nv ) 
    556556{ 
    557557    if ( !_enabled ) 
     
    560560        return true; 
    561561 
     562    { 
     563        // Two situations where we want to simply do a regular traversal: 
     564        //  1) it's the first frame for this camers 
     565        //  2) we haven't rendered for an abnormally long time (probably because we're an out-of-range LOD child) 
     566        // In these cases, assume we're visible to avoid blinking. 
     567        OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _frameCountMutex ); 
     568        const int& lastQueryFrame( _frameCountMap[ camera ] ); 
     569        if( ( lastQueryFrame == 0 ) || 
     570            ( (nv.getTraversalNumber() - lastQueryFrame) >  (_queryFrameCount + 1) ) ) 
     571            return true; 
     572    } 
     573 
    562574    if (_queryGeode->getDrawable( 0 ) == NULL) 
    563575    { 
     
    569581    QueryGeometry* qg = static_cast< QueryGeometry* >( _queryGeode->getDrawable( 0 ) ); 
    570582 
    571     // If the distance to the bounding sphere shell is positive, retrieve 
    572     //   the results. Others (we're inside the BS shell) we are considered 
     583    // Get the near plane for the upcoming distance calculation. 
     584    float nearPlane; 
     585    const osg::Matrix& proj( camera->getProjectionMatrix() ); 
     586    if( ( proj(3,3) != 1. ) || ( proj(2,3) != 0. ) || ( proj(1,3) != 0. ) || ( proj(0,3) != 0.) ) 
     587        nearPlane = proj(3,2) / (proj(2,2)-1.);  // frustum / perspective 
     588    else 
     589        nearPlane = (proj(3,2)+1.) / proj(2,2);  // ortho 
     590 
     591    // If the distance from the near plane to the bounding sphere shell is positive, retrieve 
     592    //   the results. Otherwise (near plane inside the BS shell) we are considered 
    573593    //   to have passed and don't need to retrieve the query. 
    574594    const osg::BoundingSphere& bs = getBound(); 
    575     float distance = distanceToEyePoint  - bs._radius; 
     595    float distanceToEyePoint = nv.getDistanceToEyePoint( bs._center, false ); 
     596 
     597    float distance = distanceToEyePoint - nearPlane - bs._radius; 
    576598    _passed = ( distance <= 0.f ); 
    577599    if (!_passed)