void ComputeBoundsVisitor::applyBoundingBox(const osg::BoundingBox& bbox)
{
    if (_matrixStack.empty()) _bb.expandBy(bbox);
    else if (bbox.valid())
    {
        const osg::Matrix& matrix = _matrixStack.back();
        _bb.expandBy(bbox.corner(0) * matrix);
        _bb.expandBy(bbox.corner(1) * matrix);
        _bb.expandBy(bbox.corner(2) * matrix);
        _bb.expandBy(bbox.corner(3) * matrix);
        _bb.expandBy(bbox.corner(4) * matrix);
        _bb.expandBy(bbox.corner(5) * matrix);
        _bb.expandBy(bbox.corner(6) * matrix);
        _bb.expandBy(bbox.corner(7) * matrix);
    }
}
Esempio n. 2
0
inline bool CheckAndMultiplyBoxIfWithinPolytope
    ( osg::BoundingBox & bb, osg::Matrix & m, osg::Polytope &p )
{
    if( !bb.valid() ) return false;

    osg::Vec3 o = bb._min * m, s[3];

    for( int i = 0; i < 3; i ++ )
        s[i] = osg::Vec3( m(i,0), m(i,1), m(i,2) ) * ( bb._max[i] - bb._min[i] );

    for( osg::Polytope::PlaneList::iterator it = p.getPlaneList().begin();
         it != p.getPlaneList().end();
         ++it )
    {
        float dist = it->distance( o ), dist_min = dist, dist_max = dist;

        for( int i = 0; i < 3; i ++ ) {
            dist = it->dotProductNormal( s[i] );
            if( dist < 0 ) dist_min += dist; else dist_max += dist;
        }

        if( dist_max < 0 )
            return false;
    }

    bb._max = bb._min = o;
#if 1
    for( int i = 0; i < 3; i ++ )
        for( int j = 0; j < 3; j ++ )
            if( s[i][j] < 0 ) bb._min[j] += s[i][j]; else bb._max[j] += s[i][j];
#else
    b.expandBy( o + s[0] );
    b.expandBy( o + s[1] );
    b.expandBy( o + s[2] );
    b.expandBy( o + s[0] + s[1] );
    b.expandBy( o + s[0] + s[2] );
    b.expandBy( o + s[1] + s[2] );
    b.expandBy( o + s[0] + s[1] + s[2] );
#endif

#if ( IGNORE_OBJECTS_LARGER_THAN_HEIGHT > 0 )
   if( bb._max[2] - bb._min[2] > IGNORE_OBJECTS_LARGER_THAN_HEIGHT ) // ignore huge objects
       return false;
#endif

    return true;
}
void MinimalShadowMap::ViewData::cutScenePolytope
    ( const osg::Matrix & transform, 
      const osg::Matrix & inverse, 
      const osg::BoundingBox & bb )
{   
    _sceneReceivingShadowPolytopePoints.clear();

    if( bb.valid() ) {
        osg::Polytope polytope;
        polytope.setToBoundingBox( bb );
        polytope.transformProvidingInverse( inverse );
        _sceneReceivingShadowPolytope.cut( polytope );        
        _sceneReceivingShadowPolytope.getPoints
                                ( _sceneReceivingShadowPolytopePoints );
    } else
        _sceneReceivingShadowPolytope.clear();
}
void MinimalShadowMap::ViewData::trimProjection
    ( osg::Matrixd & projectionMatrix, osg::BoundingBox bb, unsigned int trimMask )
{
#if 1
    if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return;
    double l = -1, r = 1, b = -1, t = 1, n = 1, f = -1;

#if 0
    // make sure bounding box does not extend beyond unit frustum clip range
    for( int i = 0; i < 3; i ++ ) {
        if( bb._min[i] < -1 ) bb._min[i] = -1;
        if( bb._max[i] >  1 ) bb._max[i] =  1;
    }
#endif

    if( trimMask & 1 ) l = bb._min[0];
    if( trimMask & 2 ) r = bb._max[0];
    if( trimMask & 4 ) b = bb._min[1];
    if( trimMask & 8 ) t = bb._max[1];
    if( trimMask & 16 ) n = -bb._min[2];
    if( trimMask & 32 ) f = -bb._max[2];

    projectionMatrix.postMult( osg::Matrix::ortho( l,r,b,t,n,f ) );
#else
    if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return;
    double l, r, t, b, n, f;
    bool ortho = projectionMatrix.getOrtho( l, r, b, t, n, f ); 
    if( !ortho && !projectionMatrix.getFrustum( l, r, b, t, n, f ) )
        return; // rotated or skewed or other crooked projection - give up

    // make sure bounding box does not extend beyond unit frustum clip range
    for( int i = 0; i < 3; i ++ ) {
        if( bb._min[i] < -1 ) bb._min[i] = -1;
        if( bb._max[i] >  1 ) bb._max[i] =  1;
    }

    osg::Matrix projectionToView = osg::Matrix::inverse( projectionMatrix );
    
    osg::Vec3 min =
        osg::Vec3( bb._min[0], bb._min[1], bb._min[2] ) * projectionToView;

    osg::Vec3 max =
        osg::Vec3( bb._max[0], bb._max[1], bb._max[2] ) * projectionToView;

    if( trimMask & 16 ) { // trim near
        if( !ortho ) { // recalc frustum corners on new near plane
            l *= -min[2] / n;
            r *= -min[2] / n;
            b *= -min[2] / n;
            t *= -min[2] / n;
        }
        n = -min[2];
    }

    if( trimMask & 32 ) // trim far
        f = -max[2];

    if( !ortho ) {
        min[0] *=  -n / min[2];
        min[1] *=  -n / min[2];
        max[0] *=  -n / max[2];
        max[1] *=  -n / max[2];
    }

    if( l < r ) { // check for inverted X range
        if( l < min[0] && ( trimMask & 1 ) ) l = min[0];
        if( r > max[0] && ( trimMask & 2 ) ) r = max[0];
    } else {
        if( l > min[0] && ( trimMask & 1 ) ) l = min[0];
        if( r < max[0] && ( trimMask & 2 ) ) r = max[0];
    }

    if( b < t ) { // check for inverted Y range
        if( b < min[1] && ( trimMask & 4 ) ) b = min[1];
        if( t > max[1] && ( trimMask & 8 ) ) t = max[1];
    } else {
        if( b > min[1] && ( trimMask & 4 ) ) b = min[1];
        if( t < max[1] && ( trimMask & 8 ) ) t = max[1];
    }

    if( ortho ) 
        projectionMatrix.makeOrtho( l, r, b, t, n, f );
    else 
        projectionMatrix.makeFrustum( l, r, b, t, n, f );
#endif
}