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; }
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; }
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 ); } }
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 ); } }