Пример #1
0
bool DebugShadowMap::ViewData::DebugBoundingBox
    ( const osg::BoundingBox & bb, const char * name )
{
    bool result = false;
#if defined( _DEBUG    ) || defined( DEBUG )
    if( !name ) name = "";

    osg::BoundingBox & bb_prev = _boundingBoxMap[ std::string( name ) ];

    result = bb.center() != bb_prev.center() || bb.radius() != bb_prev.radius();
    if( result )
        std::cout << "Box<" << name << "> ("
                  << ( bb._max._v[0] + bb._min._v[0] ) * 0.5 << " "
                  << ( bb._max._v[1] + bb._min._v[1] ) * 0.5 << " "
                  << ( bb._max._v[2] + bb._min._v[2] ) * 0.5 << ") ["
                  << ( bb._max._v[0] - bb._min._v[0] ) << " "
                  << ( bb._max._v[1] - bb._min._v[1] ) << " "
                  << ( bb._max._v[2] - bb._min._v[2] ) << "] "
                  << std::endl;

    bb_prev = bb;
#endif
    return result;
}
Пример #2
0
void MxCore::lookAtAndFit( const osg::BoundingBox& bb )
{
    // We'll get the view matrix to project the bounding box, so pre-configure it
    // to point at the box center. Eye position doesn't matter at this point (we
    // compute the eye position at the end of the function).
    osg::Vec3d newDir = bb.center() - _position;
    newDir.normalize();
    setDir( newDir );


    // Ttransform the bounding box vertices into eye space,
    // then determine their x and y extents. We'll compare the eye
    // space bb aspect ratio against the projection _aspect to
    // determine the critical axis to fit.

    osg::ref_ptr< osg::Vec3Array > corners = new osg::Vec3Array;
    corners->resize( 8 );
    ( *corners )[ 0 ].set( bb._min );
    ( *corners )[ 1 ].set( bb._max.x(), bb._min.y(), bb._min.z() );
    ( *corners )[ 2 ].set( bb._max.x(), bb._min.y(), bb._max.z() );
    ( *corners )[ 3 ].set( bb._min.x(), bb._min.y(), bb._max.z() );
    ( *corners )[ 4 ].set( bb._max );
    ( *corners )[ 5 ].set( bb._min.x(), bb._max.y(), bb._max.z() );
    ( *corners )[ 6 ].set( bb._min.x(), bb._max.y(), bb._min.z() );
    ( *corners )[ 7 ].set( bb._max.x(), bb._max.y(), bb._min.z() );

    osgwTools::transform( getInverseMatrix(), corners.get() );
    // The 'corners' array of bb verts are now in eye space.

    // Determine max and min values for eye space x and y
    osg::Vec2 minEC( FLT_MAX, FLT_MAX ), maxEC( FLT_MIN, FLT_MIN );
    unsigned int idx;
    for( idx=0; idx<8; idx++ )
    {
        const osg::Vec3& v( ( *corners )[ idx ] );
        minEC[ 0 ] = osg::minimum< float >( v.x(), minEC[ 0 ] );
        minEC[ 1 ] = osg::minimum< float >( v.y(), minEC[ 1 ] );
        maxEC[ 0 ] = osg::maximum< float >( v.x(), maxEC[ 0 ] );
        maxEC[ 1 ] = osg::maximum< float >( v.y(), maxEC[ 1 ] );
    }
    // aspect is width (x) over height (y).
    const double ecWidth( maxEC[ 0 ] - minEC[ 0 ] );
    const double ecHeight( maxEC[ 1 ] - minEC[ 1 ] );
    const double ecAspect = ecWidth / ecHeight;


    // We'll store half the extent of interest into a dummy bounding sphere's radius.
    // We'll store the analogous fov in bestFov.
    osg::BoundingSphere bs;
    double bestFov;
    if( ecAspect > _aspect )
    {
        // Fit eye space x to the view
        bs.radius() = ecWidth * .5;
        bestFov = _aspect * _fovy;
    }
    else
    {
        // Fit eye space y to the view
        bs.radius() = ecHeight * .5;
        bestFov = _fovy;
    }

    // The wrap-up code sets the eye position at the best distance from
    // the bb center. Extra distance is added in to account for the fact
    // that the input bound probably has a larger radius than the eye coord
    // bound that we're passing to computeInitialDistanceFromFOVY().
    const double extraDistance = bb.radius() - bs.radius();
    const double distance = extraDistance +
        osgwMx::computeInitialDistanceFromFOVY( bs, bestFov );
    setPosition( bs.center() - ( newDir * distance ) );
}