osgEarth 2.1.1

/home/cube/sources/osgearth/src/applications/osgearth_seamless/osgearth_seamless.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003 * Copyright 2008-2010 Pelican Mapping
00004 * http://osgearth.org
00005 *
00006 * osgEarth is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU Lesser General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU Lesser General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU Lesser General Public License
00017 * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018 */
00019 
00020 #include <osg/Notify>
00021 #include <osg/Shape>
00022 #include <osg/ShapeDrawable>
00023 #include <osg/Geode>
00024 #include <osg/PagedLOD>
00025 #include <osg/PolygonMode>
00026 #include <osg/AutoTransform>
00027 #include <osg/MatrixTransform>
00028 #include <osgText/Text>
00029 #include <osgGA/StateSetManipulator>
00030 #include <osgGA/GUIEventHandler>
00031 #include <osgViewer/Viewer>
00032 #include <osgViewer/ViewerEventHandlers>
00033 #include <osgUtil/LineSegmentIntersector>
00034 #include <osgEarth/MapNode>
00035 #include <osgEarth/FindNode>
00036 #include <osgEarthUtil/AutoClipPlaneHandler>
00037 #include <osgEarthUtil/EarthManipulator>
00038 #include <osgEarthDrivers/tms/TMSOptions>
00039 #include <osgEarthDrivers/engine_seamless/PatchInfo>
00040 #include <osgEarthDrivers/engine_seamless/SeamlessOptions>
00041 #include <sstream>
00042 
00043 // Print info about terrain rendered using the seamless engine. Copied
00044 // from osgearth_elevation.
00045 
00046 using namespace osgEarth::Drivers;
00047 
00048 static
00049 osg::MatrixTransform* createFlag()
00050 {
00051     osg::Cylinder* c = new osg::Cylinder( osg::Vec3d(0,0,0), 2.0f, 250.f );
00052     osg::Geode* g = new osg::Geode();
00053     g->addDrawable( new osg::ShapeDrawable( c ) );
00054     osgText::Text* text = new osgText::Text();
00055     text->setCharacterSizeMode( osgText::Text::SCREEN_COORDS );
00056     text->setCharacterSize( 72.f );
00057     text->setBackdropType( osgText::Text::OUTLINE );
00058     text->setText( "00000000000000" );
00059     text->setAutoRotateToScreen( true );
00060     text->setPosition( osg::Vec3d( 0, 0, 125 ) );
00061     text->setDataVariance( osg::Object::DYNAMIC );
00062     g->addDrawable( text );
00063     osg::StateSet* ss = g->getOrCreateStateSet();
00064     ss->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
00065                                           osg::PolygonMode::FILL),
00066                      osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
00067     osg::AutoTransform* at = new osg::AutoTransform();
00068     at->setAutoScaleToScreen( true );
00069     at->addChild( g );
00070     at->getOrCreateStateSet()->setMode( GL_LIGHTING, 0 );
00071     osg::MatrixTransform* xf = new osg::MatrixTransform();
00072     xf->addChild( at );
00073     xf->setDataVariance( osg::Object::DYNAMIC );
00074     return xf;
00075 }
00076 
00077 static void
00078 updateFlag(osg::MatrixTransform* xf, const osg::Matrix& mat,
00079            const osgEarth::TileKey& key)
00080 {
00081     osg::Geode* g = static_cast<osg::Geode*>( xf->getChild(0)->asGroup()->getChild(0) );
00082     std::stringstream buf;
00083     buf << key.getLevelOfDetail() << " " << key.getTileX() << " "
00084         << key.getTileY();
00085     std::string bufStr;
00086     bufStr = buf.str();
00087     static_cast<osgText::Text*>( g->getDrawable(1) )->setText( bufStr );
00088     xf->setMatrix( mat );
00089 }
00090 
00091 // An event handler that will print out the elevation at the clicked point
00092 struct QueryTileHandler : public osgGA::GUIEventHandler 
00093 {
00094     QueryTileHandler(osg::MatrixTransform* flag,
00095                      const osgEarth::SpatialReference* srs)
00096         : _mouseDown(false), _flag(flag), _srs(srs) { }
00097 
00098     void update( float x, float y, osgViewer::View* view )
00099     {
00100         using namespace osg;
00101         using namespace osgUtil;
00102         using namespace osgEarth;
00103         LineSegmentIntersector::Intersections results;
00104         TileKey key(TileKey::INVALID);
00105         if ( view->computeIntersections( x, y, results, 0x01 ) )
00106         {
00107             // find the first hit under the mouse:
00108             LineSegmentIntersector::Intersection first
00109                 = *(results.begin());
00110             for (NodePath::const_reverse_iterator itr = first.nodePath.rbegin(),
00111                      end = first.nodePath.rend();
00112                  itr != end;
00113                  ++itr)
00114             {
00115                 const PagedLOD* plod = dynamic_cast<const PagedLOD*>(*itr);
00116                 if (!plod)
00117                     continue;
00118                 const seamless::PatchInfo* popt
00119                     = dynamic_cast<const seamless::PatchInfo*>(
00120                         plod->getDatabaseOptions());
00121                 if (!popt)
00122                     continue;
00123                 key = popt->getTileKey();
00124                 break;
00125             }
00126 
00127             if (!key.valid())
00128             {
00129                 OE_WARN << "Couldn't get tile key.\n";
00130                 return;
00131             }
00132             osg::Vec3d point = first.getWorldIntersectPoint();
00133             
00134             // transform it to map coordinates:
00135             Matrixd coordFrame;
00136             _srs->getEllipsoid()->computeLocalToWorldTransformFromXYZ(
00137                 point.x(), point.y(), point.z(), coordFrame);
00138             updateFlag(_flag.get(), coordFrame, key);
00139         }
00140     }
00141 
00142     bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
00143     {
00144         if ( ea.getEventType() == osgGA::GUIEventAdapter::MOVE )
00145         {
00146             osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
00147             update( ea.getX(), ea.getY(), view );
00148         }
00149 
00150         return false;
00151     }
00152 
00153     bool _mouseDown;
00154     osg::ref_ptr<osg::MatrixTransform> _flag;
00155     osg::ref_ptr<const osgEarth::SpatialReference> _srs;
00156 };
00157 
00158 
00159 int main(int argc, char** argv)
00160 {
00161     osg::ArgumentParser arguments(&argc,argv);
00162 
00163     osgViewer::Viewer viewer(arguments);
00164 
00165     // install the programmable manipulator.
00166     osgEarth::Util::EarthManipulator* manip = new osgEarth::Util::EarthManipulator();
00167     viewer.setCameraManipulator( manip );
00168 
00169     osgEarth::MapNode* mapNode = NULL;
00170 
00171     osg::Node* loadedNode = osgDB::readNodeFiles( arguments );
00172     if (!loadedNode)
00173     {
00174         // load up a map with an elevation layer:
00175         osgEarth::Map *map = new osgEarth::Map();
00176 
00177         // Add some imagery
00178         {
00179             TMSOptions tms;
00180             tms.url() = "http://demo.pelicanmapping.com/rmweb/data/bluemarble-tms/tms.xml";
00181             map->addImageLayer( new osgEarth::ImageLayer( "BLUEMARBLE", tms ) );
00182         }
00183 
00184         // Add some elevation
00185         {
00186             TMSOptions tms;
00187             tms.url() = "http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml";
00188             map->addElevationLayer( new osgEarth::ElevationLayer( "SRTM", tms ) );
00189         }
00190 
00191         MapNodeOptions nodeOptions;
00192         nodeOptions.setTerrainOptions( osgEarth::Drivers::SeamlessOptions() );
00193 
00194         mapNode = new osgEarth::MapNode( map, nodeOptions );
00195     }
00196     else
00197     {
00198         mapNode = findTopMostNodeOfType<osgEarth::MapNode>( loadedNode );
00199     }
00200 
00201     osg::Group* root = new osg::Group();
00202 
00203     // The MapNode will render the Map object in the scene graph.
00204     mapNode->setNodeMask( 0x01 );
00205     root->addChild( mapNode );
00206 
00207     manip->setNode(mapNode->getTerrainEngine());
00208     if ( mapNode->getMap()->isGeocentric() )
00209     {
00210         manip->setHomeViewpoint( 
00211             osgEarth::Util::Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 5e7 ) );
00212 
00213         // add a handler that will automatically calculate good clipping planes
00214         viewer.addEventHandler( new osgEarth::Util::AutoClipPlaneHandler() );
00215     }
00216     // A flag so we can see where we clicked
00217     osg::MatrixTransform* flag = createFlag();
00218     flag->setNodeMask( 0x02 );
00219     root->addChild( flag );
00220 
00221     viewer.setSceneData( root );
00222 
00223     // An event handler that will respond to mouse clicks:
00224     viewer.addEventHandler(
00225         new QueryTileHandler(flag, mapNode->getMap()->getProfile()->getSRS()));
00226 
00227     // add some stock OSG handlers:
00228     viewer.addEventHandler(new osgViewer::StatsHandler());
00229     viewer.addEventHandler(new osgViewer::WindowSizeHandler());
00230     viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
00231 
00232     return viewer.run();
00233 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines