osgEarth 2.1.1
|
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 <string> 00021 00022 #include <osg/Notify> 00023 #include <osg/Switch> 00024 #include <osgGA/StateSetManipulator> 00025 #include <osgGA/GUIEventHandler> 00026 #include <osgViewer/Viewer> 00027 #include <osgViewer/ViewerEventHandlers> 00028 #include <osgEarth/Map> 00029 #include <osgEarth/MapNode> 00030 #include <osgEarthUtil/EarthManipulator> 00031 #include <osgEarthUtil/Viewpoint> 00032 #include <osgEarthUtil/AutoClipPlaneHandler> 00033 #include <osgEarthUtil/Controls> 00034 00035 using namespace osgEarth::Util; 00036 using namespace osgEarth::Util::Controls; 00037 00038 namespace 00039 { 00040 class SwitchHandler : public osgGA::GUIEventHandler 00041 { 00042 public: 00043 SwitchHandler(char key = 0) : _key(key) {} 00044 00045 bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object* object, osg::NodeVisitor* /*nv*/) 00046 { 00047 if (ea.getHandled() || ea.getEventType() != osgGA::GUIEventAdapter::KEYDOWN ) 00048 return false; 00049 00050 if ( ea.getKey() == _key ) 00051 { 00052 ControlCanvas* canvas = ControlCanvas::get(aa.asView()); 00053 if ( canvas ) 00054 canvas->setNodeMask( canvas->getNodeMask() ^ 0xFFFFFFFF ); 00055 } 00056 return false; 00057 } 00058 00059 protected: 00060 char _key; 00061 }; 00062 00063 osg::Node* createHelp( osgViewer::View* view ) 00064 { 00065 static char s_help[] = 00066 "left mouse: pan \n" 00067 "middle mouse: tilt/slew \n" 00068 "right mouse: zoom in/out continuous \n" 00069 "double-click: zoom in \n" 00070 "scroll wheel: zoom in/out \n" 00071 "arrows: pan\n" 00072 "1-6 : fly to preset viewpoints \n" 00073 "shift-right-mouse: locked panning\n" 00074 "u : toggle azimuth locking\n" 00075 "h : toggle this help\n"; 00076 00077 VBox* v = new VBox(); 00078 v->addControl( new LabelControl( "EarthManipulator", osg::Vec4f(1,1,0,1) ) ); 00079 v->addControl( new LabelControl( s_help ) ); 00080 ControlCanvas* canvas = ControlCanvas::get( view ); 00081 canvas->addControl( v ); 00082 canvas->setEventCallback(new SwitchHandler('h')); 00083 00084 return canvas; 00085 } 00086 00087 // some preset viewpoints. 00088 static Viewpoint VPs[] = { 00089 Viewpoint( "Africa", osg::Vec3d( 0.0, 0.0, 0.0 ), 0.0, -90.0, 10e6 ), 00090 Viewpoint( "California", osg::Vec3d( -121.0, 34.0, 0.0 ), 0.0, -90.0, 6e6 ), 00091 Viewpoint( "Europe", osg::Vec3d( 0.0, 45.0, 0.0 ), 0.0, -90.0, 4e6 ), 00092 Viewpoint( "Washington DC", osg::Vec3d( -77.0, 38.0, 0.0 ), 0.0, -90.0, 1e6 ), 00093 Viewpoint( "Australia", osg::Vec3d( 135.0, -20.0, 0.0 ), 0.0, -90.0, 2e6 ), 00094 Viewpoint( "Boston", osg::Vec3d( -71.096936, 42.332771, 0 ), 0.0, -90, 1e5 ) 00095 }; 00096 00097 // a simple handler that demonstrates the "viewpoint" functionality in 00098 // osgEarthUtil::EarthManipulator. Press a number key to fly to a viewpoint. 00099 struct FlyToViewpointHandler : public osgGA::GUIEventHandler 00100 { 00101 FlyToViewpointHandler( EarthManipulator* manip ) : _manip(manip) { } 00102 00103 bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) 00104 { 00105 if ( ea.getEventType() == ea.KEYDOWN && ea.getKey() >= '1' && ea.getKey() <= '6' ) 00106 { 00107 _manip->setViewpoint( VPs[ea.getKey()-'1'], 4.0 ); 00108 } 00109 return false; 00110 } 00111 00112 osg::observer_ptr<EarthManipulator> _manip; 00113 }; 00114 00115 struct LockAzimuthHandler : public osgGA::GUIEventHandler 00116 { 00117 LockAzimuthHandler(char key, EarthManipulator* manip) 00118 : _key(key), _manip(manip) 00119 { 00120 } 00121 00122 bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) 00123 { 00124 if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key) 00125 { 00126 bool lockAzimuth 00127 = _manip->getSettings()->getLockAzimuthWhilePanning(); 00128 _manip->getSettings()->setLockAzimuthWhilePanning(!lockAzimuth); 00129 return true; 00130 } 00131 return false; 00132 } 00133 00134 void getUsage(osg::ApplicationUsage& usage) const 00135 { 00136 using namespace std; 00137 usage.addKeyboardMouseBinding(string(1, _key), 00138 string("Toggle azimuth locking")); 00139 } 00140 00141 char _key; 00142 osg::ref_ptr<EarthManipulator> _manip; 00143 00144 }; 00145 00146 } 00147 00148 00149 int main(int argc, char** argv) 00150 { 00151 osg::ArgumentParser arguments(&argc,argv); 00152 osg::DisplaySettings::instance()->setMinimumNumStencilBits( 8 ); 00153 00154 // install the programmable manipulator. 00155 EarthManipulator* manip = new EarthManipulator(); 00156 00157 osg::Node* earthNode = osgDB::readNodeFiles( arguments ); 00158 if (!earthNode) 00159 { 00160 OE_WARN << "Unable to load earth model." << std::endl; 00161 return -1; 00162 } 00163 00164 osgViewer::Viewer viewer(arguments); 00165 00166 osg::Group* root = new osg::Group(); 00167 root->addChild( earthNode ); 00168 root->addChild( createHelp(&viewer) ); 00169 00170 osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode ); 00171 if ( mapNode ) 00172 { 00173 if ( mapNode ) 00174 manip->setNode( mapNode->getTerrainEngine() ); 00175 00176 if ( mapNode->getMap()->isGeocentric() ) 00177 { 00178 manip->setHomeViewpoint( 00179 Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 5e7 ) ); 00180 00181 // add a handler that will automatically calculate good clipping planes 00182 viewer.addEventHandler( new AutoClipPlaneHandler() ); 00183 } 00184 } 00185 00186 viewer.setSceneData( root ); 00187 viewer.setCameraManipulator( manip ); 00188 00189 manip->getSettings()->bindMouse( 00190 EarthManipulator::ACTION_EARTH_DRAG, 00191 osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON, 00192 osgGA::GUIEventAdapter::MODKEY_SHIFT ); 00193 00194 manip->getSettings()->setArcViewpointTransitions( true ); 00195 00196 viewer.addEventHandler(new FlyToViewpointHandler( manip )); 00197 viewer.addEventHandler(new LockAzimuthHandler('u', manip)); 00198 00199 00200 // add some stock OSG handlers: 00201 viewer.addEventHandler(new osgViewer::StatsHandler()); 00202 viewer.addEventHandler(new osgViewer::WindowSizeHandler()); 00203 viewer.addEventHandler(new osgViewer::ThreadingHandler()); 00204 viewer.addEventHandler(new osgViewer::LODScaleHandler()); 00205 viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); 00206 viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage())); 00207 //viewer.addEventHandler(new osgViewer::RecordCameraPathHandler()); 00208 00209 return viewer.run(); 00210 }