osgEarth 2.1.1
|
Public Member Functions | |
ObjectPlacer (osg::Node *terrain, int traversalMask=~0, bool clamp=false, int maxLevel=20) | |
bool | createPlacerMatrix (double lat_degrees, double lon_degrees, double height, osg::Matrixd &out_result) const |
osg::Node * | placeNode (osg::Node *node, double lat_degrees, double lon_degrees, double height) const |
Private Member Functions | |
bool | clampGeocentric (osg::CoordinateSystemNode *csn, double lat_rad, double lon_rad, osg::Vec3d &out) const |
bool | clampProjected (osg::CoordinateSystemNode *csn, double x, double y, osg::Vec3d &out) const |
Private Attributes | |
osg::ref_ptr< osgEarth::MapNode > | _mapNode |
osg::ref_ptr < osg::CoordinateSystemNode > | _csn |
osg::ref_ptr < osgUtil::IntersectionVisitor::ReadCallback > | _readCallback |
int | _traversalMask |
bool | _clamp |
Convenience utilities for placing an object on an osgEarth terrain map using latitude/longitude coordinates.
Definition at line 34 of file ObjectPlacer.
ObjectPlacer::ObjectPlacer | ( | osg::Node * | terrain, |
int | traversalMask = ~0 , |
||
bool | clamp = false , |
||
int | maxLevel = 20 |
||
) |
Constructs a new placer.
terrain | The scene graph containing the osgEarth::Map node. |
traversalMask | Mask to use when intersecting the terrain. |
clamp | Whether the class should attempt to calculate the placement position so that it sits exactly on the terrain skin. Warning: this does not yet work properly for maps that don't report a maximum resolution (like most of the commercial providers). |
maxLevel | Maximum level of detail to which to search for high resolution terrain. |
Definition at line 49 of file ObjectPlacer.cpp.
: _traversalMask( traversalMask ), _clamp( clamp ) { _mapNode = findTopMostNodeOfType<osgEarth::MapNode>( terrain ); _csn = findTopMostNodeOfType<osg::CoordinateSystemNode>( terrain ); _readCallback = new CachingReadCallback( maxLevel ); }
bool ObjectPlacer::clampGeocentric | ( | osg::CoordinateSystemNode * | csn, |
double | lat_rad, | ||
double | lon_rad, | ||
osg::Vec3d & | out | ||
) | const [private] |
Definition at line 59 of file ObjectPlacer.cpp.
{ osg::Vec3d start, end; csn->getEllipsoidModel()->convertLatLongHeightToXYZ( lat_rad, lon_rad, 50000, start.x(), start.y(), start.z() ); csn->getEllipsoidModel()->convertLatLongHeightToXYZ( lat_rad, lon_rad, -50000, end.x(), end.y(), end.z() ); osgUtil::LineSegmentIntersector* i = new osgUtil::LineSegmentIntersector( start, end ); osgUtil::IntersectionVisitor iv; iv.setIntersector( i ); static_cast<CachingReadCallback*>(_readCallback.get())->reset(); iv.setReadCallback( _readCallback.get() ); iv.setTraversalMask( _traversalMask ); _mapNode->accept( iv ); osgUtil::LineSegmentIntersector::Intersections& results = i->getIntersections(); if ( !results.empty() ) { const osgUtil::LineSegmentIntersector::Intersection& result = *results.begin(); out = result.matrix.valid() ? result.localIntersectionPoint * (*result.matrix) : result.localIntersectionPoint; return true; } return false; }
bool ObjectPlacer::clampProjected | ( | osg::CoordinateSystemNode * | csn, |
double | x, | ||
double | y, | ||
osg::Vec3d & | out | ||
) | const [private] |
Definition at line 88 of file ObjectPlacer.cpp.
{ osg::Vec3d start( x, y, 50000 ); osg::Vec3d end(x, y, -50000); osgUtil::LineSegmentIntersector* i = new osgUtil::LineSegmentIntersector( start, end ); osgUtil::IntersectionVisitor iv; iv.setIntersector( i ); static_cast<CachingReadCallback*>(_readCallback.get())->reset(); iv.setReadCallback( _readCallback.get() ); iv.setTraversalMask( _traversalMask ); _mapNode->accept( iv ); osgUtil::LineSegmentIntersector::Intersections& results = i->getIntersections(); if ( !results.empty() ) { const osgUtil::LineSegmentIntersector::Intersection& result = *results.begin(); out = result.matrix.valid() ? result.localIntersectionPoint * (*result.matrix) : result.localIntersectionPoint; return true; } return false; }
bool ObjectPlacer::createPlacerMatrix | ( | double | lat_degrees, |
double | lon_degrees, | ||
double | height, | ||
osg::Matrixd & | out_result | ||
) | const |
Creates a double-precision matrix that will transform geometry to the specified map location. In a geocentric map, the matrix will also rotate into the tangent plane.
lat_degrees,lon_degrees | Location on the map for which to generate a matrix |
height | Height above the terrain (in local units) |
out_result | Receives the resulting matrix; only valid if the method returns TRUE. |
Definition at line 115 of file ObjectPlacer.cpp.
{ if ( !_mapNode.valid() || !_csn.valid() ) { OE_WARN << "ObjectPlacer: terrain is missing either a Map or CSN node" << std::endl; return false; } // see whether this is a geocentric model: bool is_geocentric = _csn.valid() && _csn->getEllipsoidModel() != NULL; const SpatialReference* srs = _mapNode->getMap()->getProfile()->getSRS(); // now build a matrix: if ( is_geocentric ) { double lat_rad = osg::DegreesToRadians( lat_deg ); double lon_rad = osg::DegreesToRadians( lon_deg ); if ( _clamp ) { osg::Vec3d c; if ( clampGeocentric( _csn.get(), lat_rad, lon_rad, c ) ) { srs->getEllipsoid()->computeLocalToWorldTransformFromXYZ( c.x(), c.y(), c.z(), out_result ); } } else { srs->getEllipsoid()->computeLocalToWorldTransformFromLatLongHeight( lat_rad, lon_rad, height, out_result ); } } else // projected or "flat geographic" { osg::Vec3d local(0, 0, height); // first convert the input coords to the map srs: srs->getGeographicSRS()->transform2D( lon_deg, lat_deg, srs, local.x(), local.y()); if ( _clamp ) { clampProjected( _csn.get(), local.x(), local.y(), local ); local.z() += height; } out_result = osg::Matrixd::translate( local ); } return true; }
osg::Node * ObjectPlacer::placeNode | ( | osg::Node * | node, |
double | lat_degrees, | ||
double | lon_degrees, | ||
double | height | ||
) | const |
Creates a new node graph that positions the input node at a specified map location. The resulting node will contain the input node as a child.
node | Node to position at the specified location |
lat_degrees,lon_degrees | Position on the map at which to place the node |
height | Height above the terrain (in local units) |
Definition at line 166 of file ObjectPlacer.cpp.
{ osg::Node* result = NULL; osg::Matrixd matrix; if ( createPlacerMatrix( lat_deg, lon_deg, height, matrix ) ) { osg::MatrixTransform* mt = new osg::MatrixTransform( matrix ); mt->addChild( node ); result = mt; } return result; }
bool osgEarth::Util::ObjectPlacer::_clamp [private] |
Definition at line 104 of file ObjectPlacer.
osg::ref_ptr<osg::CoordinateSystemNode> osgEarth::Util::ObjectPlacer::_csn [private] |
Definition at line 101 of file ObjectPlacer.
osg::ref_ptr<osgEarth::MapNode> osgEarth::Util::ObjectPlacer::_mapNode [private] |
Definition at line 100 of file ObjectPlacer.
osg::ref_ptr<osgUtil::IntersectionVisitor::ReadCallback> osgEarth::Util::ObjectPlacer::_readCallback [private] |
Definition at line 102 of file ObjectPlacer.
int osgEarth::Util::ObjectPlacer::_traversalMask [private] |
Definition at line 103 of file ObjectPlacer.