osgEarth 2.1.1
Public Member Functions | Private Member Functions | Private Attributes

osgEarth::Util::ObjectPlacer Class Reference

List of all members.

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

Detailed Description

Convenience utilities for placing an object on an osgEarth terrain map using latitude/longitude coordinates.

Definition at line 34 of file ObjectPlacer.


Constructor & Destructor Documentation

ObjectPlacer::ObjectPlacer ( osg::Node *  terrain,
int  traversalMask = ~0,
bool  clamp = false,
int  maxLevel = 20 
)

Constructs a new placer.

Parameters:
terrainThe scene graph containing the osgEarth::Map node.
traversalMaskMask to use when intersecting the terrain.
clampWhether 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).
maxLevelMaximum 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 );
}

Member Function Documentation

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

Here is the caller graph for this function:

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

Here is the caller graph for this function:

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.

Parameters:
lat_degrees,lon_degreesLocation on the map for which to generate a matrix
heightHeight above the terrain (in local units)
out_resultReceives the resulting matrix; only valid if the method returns TRUE.
Returns:
True if the method succesfully created the output matrix; false if not (e.g., the input location was outside the extents of the terrain map).

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

Here is the call graph for this function:

Here is the caller graph for this function:

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.

Parameters:
nodeNode to position at the specified location
lat_degrees,lon_degreesPosition on the map at which to place the node
heightHeight above the terrain (in local units)
Returns:
A node graph representing the newly placed node. The input node will be a child in the new graph. NULL if the placement failed for some reason.

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

Here is the call graph for this function:


Member Data Documentation

Definition at line 104 of file ObjectPlacer.

osg::ref_ptr<osg::CoordinateSystemNode> osgEarth::Util::ObjectPlacer::_csn [private]

Definition at line 101 of file ObjectPlacer.

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.

Definition at line 103 of file ObjectPlacer.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines