예제 #1
0
bool
Terrain::getHeight(osg::Node*              patch,
                   const SpatialReference* srs,
                   double                  x, 
                   double                  y, 
                   double*                 out_hamsl,
                   double*                 out_hae    ) const
{
    if ( !_graph.valid() && !patch )
        return 0L;

    // convert to map coordinates:
    if ( srs && !srs->isHorizEquivalentTo(getSRS()) )
    {
        srs->transform2D(x, y, getSRS(), x, y);
    }

    // trivially reject a point that lies outside the terrain:
    if ( !getProfile()->getExtent().contains(x, y) )
        return 0L;

    const osg::EllipsoidModel* em = getSRS()->getEllipsoid();
    double r = std::min( em->getRadiusEquator(), em->getRadiusPolar() );

    // calculate the endpoints for an intersection test:
    osg::Vec3d start(x, y, r);
    osg::Vec3d end  (x, y, -r);

    if ( isGeocentric() )
    {
        const SpatialReference* ecef = getSRS()->getECEF();
        getSRS()->transform(start, ecef, start);
        getSRS()->transform(end,   ecef, end);
    }

    DPLineSegmentIntersector* lsi = new DPLineSegmentIntersector( start, end );
    lsi->setIntersectionLimit(osgUtil::Intersector::LIMIT_NEAREST);

    osgUtil::IntersectionVisitor iv( lsi );
    iv.setTraversalMask( ~_terrainOptions.secondaryTraversalMask().value() );

    if ( patch )
        patch->accept( iv );
    else
        _graph->accept( iv );

    osgUtil::LineSegmentIntersector::Intersections& results = lsi->getIntersections();
    if ( !results.empty() )
    {
        const osgUtil::LineSegmentIntersector::Intersection& firstHit = *results.begin();
        osg::Vec3d hit = firstHit.getWorldIntersectPoint();

        getSRS()->transformFromWorld(hit, hit, out_hae);
        if ( out_hamsl )
            *out_hamsl = hit.z();

        return true;
    }
    return false;
}
예제 #2
0
bool
MouseCoordsTool::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
    if (ea.getEventType() == ea.MOVE || ea.getEventType() == ea.DRAG)
    {
        osg::Vec3d world;
        if ( _mapNode->getTerrain()->getWorldCoordsUnderMouse(aa.asView(), ea.getX(), ea.getY(), world) )
        {
            GeoPoint map;
            map.fromWorld( _mapNode->getMapSRS(), world );

            for( Callbacks::iterator i = _callbacks.begin(); i != _callbacks.end(); ++i )
                i->get()->set( map, aa.asView(), _mapNode );
        }
        else
        {
            for( Callbacks::iterator i = _callbacks.begin(); i != _callbacks.end(); ++i )
                i->get()->reset( aa.asView(), _mapNode );
        }

#if 1 // testing AGL, Dist to Point
        osg::Vec3d eye, center, up;
        aa.asView()->getCamera()->getViewMatrixAsLookAt(eye, center, up);
        DPLineSegmentIntersector* lsi = new DPLineSegmentIntersector(eye, osg::Vec3d(0,0,0));
        osgUtil::IntersectionVisitor iv(lsi);
        lsi->setIntersectionLimit(lsi->LIMIT_NEAREST);
        //iv.setUserData( new Map() );
        _mapNode->accept(iv);

        if ( !lsi->getIntersections().empty() )
        {            
            double agl = (eye - lsi->getFirstIntersection().getWorldIntersectPoint()).length();
            double dtp = (eye - world).length();
            //OE_NOTICE << "AGL = " << agl << "m; DPT = " << dtp << "m" << std::endl;
            Registry::instance()->startActivity("AGL", Stringify() << agl << " m");
            Registry::instance()->startActivity("Range", Stringify() << dtp << " m");
        }
#endif
    }

    return false;
}
예제 #3
0
void OcclusionCullingCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
    if (nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
    {        
        osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv);

		static int frameNumber = -1;				
		static double remainingTime = OcclusionCullingCallback::_maxFrameTime;
		static int numCompleted = 0;
		static int numSkipped = 0;

		if (nv->getFrameStamp()->getFrameNumber() != frameNumber)
		{			
			if (numCompleted > 0 || numSkipped > 0)
			{
				OE_DEBUG << "OcclusionCullingCallback frame=" << frameNumber << " completed=" << numCompleted << " skipped=" << numSkipped << std::endl;
			}
		    frameNumber = nv->getFrameStamp()->getFrameNumber();
			numCompleted = 0;
			numSkipped = 0;
			remainingTime = OcclusionCullingCallback::_maxFrameTime;
		}

		osg::Vec3d eye = cv->getViewPoint();        

        if (_prevEye != eye || _prevWorld != _world)
        {
			if (remainingTime > 0.0)
			{
				double alt = 0.0;
				
				if ( _srs && !_srs->isProjected() )
				{
					osgEarth::GeoPoint mapPoint;
					mapPoint.fromWorld( _srs.get(), eye );
					alt = mapPoint.z();
				}
				else
				{
					alt = eye.z();
				}

				
				//Only do the intersection if we are close enough for it to matter
				if (alt <= _maxElevation && _node.valid())
				{
					//Compute the intersection from the eye to the world point
					osg::Timer_t startTick = osg::Timer::instance()->tick();
					osg::Vec3d start = eye;
					osg::Vec3d end = _world;
					DPLineSegmentIntersector* i = new DPLineSegmentIntersector( start, end );				
					i->setIntersectionLimit( osgUtil::Intersector::LIMIT_ONE );
					osgUtil::IntersectionVisitor iv;				
					iv.setIntersector( i );
					_node->accept( iv );
					osgUtil::LineSegmentIntersector::Intersections& results = i->getIntersections();
					_visible = results.empty();
					osg::Timer_t endTick = osg::Timer::instance()->tick();
					double elapsed = osg::Timer::instance()->delta_m( startTick, endTick );
					remainingTime -= elapsed;										
				}
				else
				{
					_visible = true;
				}

				numCompleted++;

				_prevEye = eye;
				_prevWorld = _world;
			}
			else
			{
				numSkipped++;
			}
        }

        if (_visible)
        {
            traverse(node, nv );
        }
    }
    else
    {
        traverse( node, nv );
    }
}
예제 #4
0
void OcclusionCullingCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
    if (nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
    {        
        osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv);

        static int frameNumber = -1;
        static double remainingTime = OcclusionCullingCallback::_maxFrameTime;
        static int numCompleted = 0;
        static int numSkipped = 0;

        if (nv->getFrameStamp()->getFrameNumber() != frameNumber)
        {
            if (numCompleted > 0 || numSkipped > 0)
            {
                OE_DEBUG << "OcclusionCullingCallback frame=" << frameNumber << " completed=" << numCompleted << " skipped=" << numSkipped << std::endl;
            }
            frameNumber = nv->getFrameStamp()->getFrameNumber();
            numCompleted = 0;
            numSkipped = 0;
            remainingTime = OcclusionCullingCallback::_maxFrameTime;
        }

        osg::Vec3d eye = cv->getViewPoint();

        if (_prevEye != eye)
        {
            if (remainingTime > 0.0)
            {
                osg::ref_ptr<GeoTransform> geo;
                if ( _xform.lock(geo) )
                {
                    double alt = 0.0;

                    osg::ref_ptr<Terrain> terrain = geo->getTerrain();
                    if ( terrain.valid() && !terrain->getSRS()->isProjected() )
                    {
                        osgEarth::GeoPoint mapPoint;
                        mapPoint.fromWorld( terrain->getSRS(), eye );
                        alt = mapPoint.z();
                    }
                    else
                    {
                        alt = eye.z();
                    }

                    //Only do the intersection if we are close enough for it to matter
                    if (alt <= _maxAltitude && terrain.valid())
                    {
                        //Compute the intersection from the eye to the world point
                        osg::Timer_t startTick = osg::Timer::instance()->tick();
                        osg::Vec3d start = eye;
                        osg::Vec3d end = osg::Vec3d(0,0,0) * geo->getMatrix();

                        // shorten the intersector by 1m to prevent flickering.
                        osg::Vec3d vec = end-start; vec.normalize();
                        end -= vec*1.0;

                        DPLineSegmentIntersector* i = new DPLineSegmentIntersector( start, end );
                        i->setIntersectionLimit( osgUtil::Intersector::LIMIT_NEAREST );
                        osgUtil::IntersectionVisitor iv;
                        iv.setIntersector( i );
                        terrain->accept( iv );
                        osgUtil::LineSegmentIntersector::Intersections& results = i->getIntersections();
                        _visible = results.empty();
                        osg::Timer_t endTick = osg::Timer::instance()->tick();
                        double elapsed = osg::Timer::instance()->delta_m( startTick, endTick );
                        remainingTime -= elapsed;
                    }
                    else
                    {
                        _visible = true;
                    }

                    numCompleted++;

                    _prevEye = eye;
                }
            }
            else
            {
                numSkipped++;
                // if we skipped some we need to request a redraw so the remianing ones get processed on the next frame.
                if ( cv->getCurrentCamera() && cv->getCurrentCamera()->getView() )
                {
                    osgGA::GUIActionAdapter* aa = dynamic_cast<osgGA::GUIActionAdapter*>(cv->getCurrentCamera()->getView());
                    if ( aa )
                    {
                        aa->requestRedraw();
                    }
                }
            }
        }

        if (_visible)
        {
            traverse(node, nv );
        }
    }
    else
    {
        traverse( node, nv );
    }
}