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