Ejemplo n.º 1
0
bool
OcclusionQueryNode::getPassed( const osg::Camera* camera, float distanceToEyePoint )
{
    if ( !_enabled )
        // Queries are not enabled. The caller should be osgUtil::CullVisitor,
        //   return true to traverse the subgraphs.
        return true;

    // In the future, we could hold a reference directly to the QueryDrawable
    //   to avoid the dynamic_cast.
    QueryGeometry* qg = dynamic_cast< QueryGeometry* >( _queryGeode->getDrawable( 0 ) );
    if (qg == NULL)
    {
        osg::notify( osg::FATAL ) <<
            "osgOQ: OcclusionQueryNode: No QueryGeometry." << std::endl;
        // Something's broke. Return true so we at least render correctly.
        return true;
    }

    // If the distance to the bounding sphere shell is positive, retrieve
    //   the results. Others (we're inside the BS shell) we are considered
    //   to have passed and don't need to retrieve the query.
    const osg::BoundingSphere& bs = getBound();
    float distance = distanceToEyePoint  - bs._radius;
    _passed = ( distance <= 0.f );
    if (!_passed)
    {
        int result = qg->getNumPixels( camera );
        _passed = ( (unsigned int)(result) > _visThreshold );
    }

    return _passed;
}
Ejemplo n.º 2
0
bool OcclusionQueryNode::getPassed( const Camera* camera, NodeVisitor& nv )
{
    if ( !_enabled )
        // Queries are not enabled. The caller should be osgUtil::CullVisitor,
        //   return true to traverse the subgraphs.
        return true;

    {
        // Two situations where we want to simply do a regular traversal:
        //  1) it's the first frame for this camera
        //  2) we haven't rendered for an abnormally long time (probably because we're an out-of-range LOD child)
        // In these cases, assume we're visible to avoid blinking.
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _frameCountMutex );
        const unsigned int& lastQueryFrame( _frameCountMap[ camera ] );
        if( ( lastQueryFrame == 0 ) ||
            ( (nv.getTraversalNumber() - lastQueryFrame) >  (_queryFrameCount + 1) ) )
            return true;
    }

    if (_queryGeode->getDrawable( 0 ) == NULL)
    {
        OSG_FATAL << "osgOQ: OcclusionQueryNode: No QueryGeometry." << std::endl;
        // Something's broke. Return true so we at least render correctly.
        return true;
    }
    QueryGeometry* qg = static_cast< QueryGeometry* >( _queryGeode->getDrawable( 0 ) );

    // Get the near plane for the upcoming distance calculation.
    float nearPlane;
    const osg::Matrix& proj( camera->getProjectionMatrix() );
    if( ( proj(3,3) != 1. ) || ( proj(2,3) != 0. ) || ( proj(1,3) != 0. ) || ( proj(0,3) != 0.) )
        nearPlane = proj(3,2) / (proj(2,2)-1.);  // frustum / perspective
    else
        nearPlane = (proj(3,2)+1.) / proj(2,2);  // ortho

    // If the distance from the near plane to the bounding sphere shell is positive, retrieve
    //   the results. Otherwise (near plane inside the BS shell) we are considered
    //   to have passed and don't need to retrieve the query.
    const osg::BoundingSphere& bs = getBound();
    float distanceToEyePoint = nv.getDistanceToEyePoint( bs._center, false );

    float distance = distanceToEyePoint - nearPlane - bs._radius;
    _passed = ( distance <= 0.f );
    if (!_passed)
    {
        int result = qg->getNumPixels( camera );
        _passed = ( (unsigned int)(result) > _visThreshold );
    }

    return _passed;
}