コード例 #1
0
void
PolyhedralLineOfSightNode::recalculateExtent()
{
    // get a local2world matrix for the map position:
    GeoPoint absMapPos = _mapPosition;
    absMapPos.makeAbsolute( getMapNode()->getTerrain() );
    osg::Matrix local2world;
    absMapPos.createLocalToWorld( local2world );

    // local offsets (east and north)
    osg::Vec3d x( _distance.as(Units::METERS), 0.0, 0.0 );
    osg::Vec3d y( 0.0, _distance.as(Units::METERS), 0.0 );

    // convert these to map coords:
    GeoPoint easting, northing;
    easting.fromWorld( getMapNode()->getMapSRS(), x * local2world );
    northing.fromWorld( getMapNode()->getMapSRS(), y * local2world );

    // calculate the offsets:
    double d_easting = easting.x() - absMapPos.x();
    double d_northing = northing.y() - absMapPos.y();

    // update the extent.
    _extent = GeoExtent(
        getMapNode()->getMapSRS(),
        absMapPos.x() - d_easting, absMapPos.y() - d_northing,
        absMapPos.x() + d_easting, absMapPos.y() + d_northing );

    OE_INFO << LC << "Cached extent = " << _extent.toString() << std::endl;
}
コード例 #2
0
void
PolyhedralLineOfSightNode::updateSamples()
{
    if ( _geode->getNumDrawables() == 0 )
        rebuildGeometry();

    osg::Geometry* geom  = _geode->getDrawable(0)->asGeometry();
    osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );

    double distance = _distance.as(Units::METERS);

    // get the world coords and a l2w transform for the origin:
    osg::Vec3d  originWorld;
    osg::Matrix local2world, world2local;

    Terrain* t = getMapNode()->getTerrain();
    GeoPoint origin = getPosition();
    origin.makeAbsolute( t );
    origin.toWorld( originWorld, t );
    origin.createLocalToWorld( local2world );
    world2local.invert( local2world );

    // set up an intersector:
    osgUtil::LineSegmentIntersector* lsi = new osgUtil::LineSegmentIntersector( originWorld, originWorld );
    osgUtil::IntersectionVisitor iv( lsi );

    // intersect the verts (skip the origin point) with the map node.
    for( osg::Vec3Array::iterator v = verts->begin()+1; v != verts->end(); ++v )
    {
        osg::Vec3d unit = *v;
        unit.normalize();
        unit *= distance;

        osg::Vec3d world = unit * local2world;

        if ( osg::equivalent(unit.length(), 0.0) )
        {
            OE_WARN << "problem." << std::endl;
        }

        lsi->reset();
        lsi->setStart( originWorld );
        lsi->setEnd( world );

        OE_DEBUG << LC << "Ray: " <<
            originWorld.x() << "," << originWorld.y() << "," << originWorld.z() << " => "
            << world.x() << "," << world.y() << "," << world.z()
            << std::endl;


        getMapNode()->getTerrain()->accept( iv );

        osgUtil::LineSegmentIntersector::Intersections& hits = lsi->getIntersections();
        if ( !hits.empty() )
        {
            const osgUtil::LineSegmentIntersector::Intersection& hit = *hits.begin();
            osg::Vec3d newV = hit.getWorldIntersectPoint() * world2local;
            if ( newV.length() > 1.0 )
                *v = newV;
            else
                *v = unit;
        }
        else
        {
            *v = unit;
        }

        //OE_NOTICE << "Radial point = " << v->x() << ", " << v->y() << ", " << v->z() << std::endl;
    }

    verts->dirty();
    geom->dirtyBound();
}
コード例 #3
0
ファイル: GeoTransform.cpp プロジェクト: 469447793/osgearth
bool
GeoTransform::setPosition(const GeoPoint& position)
{
    if ( !position.isValid() )
        return false;

    _position = position;

    // relative Z or reprojection require a terrain:
    osg::ref_ptr<Terrain> terrain;
    _terrain.lock(terrain);

    // relative Z requires a terrain:
    if (position.altitudeMode() == ALTMODE_RELATIVE && !terrain.valid())
    {
        OE_TEST << LC << "setPosition failed condition 1\n";
        return false;
    }

    GeoPoint p;

    // transform into terrain SRS if neccesary:
    if (terrain.valid() && !terrain->getSRS()->isEquivalentTo(position.getSRS()))
        p = position.transform(terrain->getSRS());
    else
        p = position;

    // bail if the transformation failed:
    if ( !p.isValid() )
    {
        OE_TEST << LC << "setPosition failed condition 2\n";
        return false;
    }

    // convert to absolute height:
    if ( !p.makeAbsolute(_terrain.get()) )
    {
        OE_TEST << LC << "setPosition failed condition 3\n";
        return false;
    }

    // assemble the matrix:
    osg::Matrixd local2world;
    p.createLocalToWorld( local2world );
    this->setMatrix( local2world );

    // install auto-recompute?
    if (_autoRecompute &&
        _position.altitudeMode() == ALTMODE_RELATIVE &&
        !_autoRecomputeReady)
    {
        // by using the adapter, there's no need to remove
        // the callback then this object destructs.
        terrain->addTerrainCallback(
           new TerrainCallbackAdapter<GeoTransform>(this) );

        _autoRecomputeReady = true;
    }

    return true;
}