void ComputeBoundsVisitor::getPolytope(osg::Polytope& polytope, float margin) const
{
    float delta = _bb.radius()*margin;
    polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) );
    polytope.add( osg::Plane(0.0, 0.0, -1.0, (_bb.zMax()+delta)) );

    polytope.add( osg::Plane(1.0, 0.0, 0.0, -(_bb.xMin()-delta)) );
    polytope.add( osg::Plane(-1.0, 0.0, 0.0, (_bb.xMax()+delta)) );

    polytope.add( osg::Plane(0.0, 1.0, 0.0, -(_bb.yMin()-delta)) );
    polytope.add( osg::Plane(0.0, -1.0, 0.0, (_bb.yMax()+delta)) );
}
Beispiel #2
0
bool
Feature::getWorldBoundingPolytope(const SpatialReference* srs,
                                  osg::Polytope&          out_polytope) const
{
    osg::BoundingSphered bs;
    if ( getWorldBound(srs, bs) && bs.valid() )
    {
        out_polytope.clear();

        // add planes for the four sides of the BS. Normals point inwards.
        out_polytope.add( osg::Plane(osg::Vec3d( 1, 0,0), osg::Vec3d(-bs.radius(),0,0)) );
        out_polytope.add( osg::Plane(osg::Vec3d(-1, 0,0), osg::Vec3d( bs.radius(),0,0)) );
        out_polytope.add( osg::Plane(osg::Vec3d( 0, 1,0), osg::Vec3d(0, -bs.radius(),0)) );
        out_polytope.add( osg::Plane(osg::Vec3d( 0,-1,0), osg::Vec3d(0,  bs.radius(),0)) );

        // for a projected feature, we're done. For a geocentric one, transform the polytope
        // into world (ECEF) space.
        if ( srs->isGeographic() && !srs->isPlateCarre() )
        {
            const osg::EllipsoidModel* e = srs->getEllipsoid();

            // add a bottom cap, unless the bounds are sufficiently large.
            double minRad = std::min(e->getRadiusPolar(), e->getRadiusEquator());
            double maxRad = std::max(e->getRadiusPolar(), e->getRadiusEquator());
            double zeroOffset = bs.center().length();
            if ( zeroOffset > minRad * 0.1 )
            {
                out_polytope.add( osg::Plane(osg::Vec3d(0,0,1), osg::Vec3d(0,0,-maxRad+zeroOffset)) );
            }
        }

        // transform the clipping planes ito ECEF space
        GeoPoint refPoint;
        refPoint.fromWorld( srs, bs.center() );

        osg::Matrix local2world;
        refPoint.createLocalToWorld( local2world );

        out_polytope.transform( local2world );

        return true;
    }
    return false;
}
void ComputeBoundsVisitor::getBase(osg::Polytope& polytope, float margin) const
{
    float delta = _bb.radius()*margin;
    polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) );
}