int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::CompositeViewer viewer(arguments); viewer.setThreadingModel( osgViewer::CompositeViewer::SingleThreaded ); // query the screen size. osg::GraphicsContext::ScreenIdentifier si; si.readDISPLAY(); if ( si.displayNum < 0 ) si.displayNum = 0; osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); unsigned width, height; wsi->getScreenResolution( si, width, height ); unsigned b = 50; osgViewer::View* mainView = new osgViewer::View(); mainView->getCamera()->setNearFarRatio(0.00002); EarthManipulator* em = new EarthManipulator(); em->getSettings()->setMinMaxPitch(-90, 0); mainView->setCameraManipulator( em ); //mainView->setUpViewInWindow( 50, 50, 600, 600 ); mainView->setUpViewInWindow( b, b, (width/2)-b*2, (height-b*4) ); viewer.addView( mainView ); osgViewer::View* overlayView = new osgViewer::View(); overlayView->getCamera()->setNearFarRatio(0.00002); EarthManipulator* overlayEM = new EarthManipulator(); overlayEM->getSettings()->setCameraProjection(overlayEM->PROJ_ORTHOGRAPHIC); overlayView->setCameraManipulator( overlayEM ); //overlayView->setUpViewInWindow( 700, 50, 600, 600 ); overlayView->setUpViewInWindow( (width/2), b, (width/2)-b*2, (height-b*4) ); overlayView->addEventHandler(new osgGA::StateSetManipulator(overlayView->getCamera()->getOrCreateStateSet())); viewer.addView( overlayView ); std::string pathfile; double animationSpeed = 1.0; if (arguments.read("-p", pathfile)) { mainView->setCameraManipulator( new osgGA::AnimationPathManipulator(pathfile) ); } osg::Node* node = MapNodeHelper().load( arguments, mainView ); if ( node ) { mainView->setSceneData( node ); osg::Group* group = new osg::Group(); group->addChild( MapNode::get(node) ); overlayView->setSceneData( group ); setupOverlayView( overlayView, group, MapNode::get(node) ); return viewer.run(); } else return -1; }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); // help? if ( arguments.read("--help") ) return usage(argv[0]); osgViewer::Viewer viewer(arguments); EarthManipulator* em = new EarthManipulator(); viewer.setCameraManipulator( em ); // load an earth file, and support all or our example command-line options // and earth file <external> tags osg::Node* earth = MapNodeHelper().load( arguments, &viewer ); MapNode* mapNode = MapNode::get(earth); if (!mapNode) return usage(argv[0]); // load the model file into the local coordinate frame, which will be // +X=east, +Y=north, +Z=up. osg::Node* model = osgDB::readNodeFile("cessna.osgt.1,-1,1.scale"); if ( !model ) return usage(argv[0]); osg::Group* root = new osg::Group(); root->addChild( earth ); App app; app.srs = mapNode->getMapSRS(); app.geo = new GeoTransform(); app.geo->setTerrain( mapNode->getTerrain() ); app.pat = new osg::PositionAttitudeTransform(); app.pat->addChild( model ); app.geo->addChild( app.pat ); root->addChild( app.geo ); viewer.setSceneData( root ); viewer.getCamera()->setNearFarRatio(0.00002); viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); ui::ControlCanvas::getOrCreate(&viewer)->addControl( makeUI(app) ); app.apply(); em->setTetherNode( app.geo ); osgEarth::Viewpoint vp; vp.setNode( app.geo ); vp.heading()->set( -45.0, Units::DEGREES ); vp.pitch()->set( -20.0, Units::DEGREES ); vp.range()->set( model->getBound().radius()*10.0, Units::METERS ); em->setViewpoint( vp ); return viewer.run(); }
void MapNodeHelper::parse(MapNode* mapNode, osg::ArgumentParser& args, osgViewer::View* view, osg::Group* root, Control* userControl ) const { if ( !root ) root = mapNode; // options to use for the load osg::ref_ptr<osgDB::Options> dbOptions = Registry::instance()->cloneOrCreateOptions(); // parse out custom example arguments first: bool useSky = args.read("--sky"); bool useOcean = args.read("--ocean"); bool useMGRS = args.read("--mgrs"); bool useDMS = args.read("--dms"); bool useDD = args.read("--dd"); bool useCoords = args.read("--coords") || useMGRS || useDMS || useDD; bool useOrtho = args.read("--ortho"); bool useAutoClip = args.read("--autoclip"); bool useShadows = args.read("--shadows"); bool animateSky = args.read("--animate-sky"); bool showActivity = args.read("--activity"); bool useLogDepth = args.read("--logdepth"); bool useLogDepth2 = args.read("--logdepth2"); bool kmlUI = args.read("--kmlui"); if (args.read("--verbose")) osgEarth::setNotifyLevel(osg::INFO); if (args.read("--quiet")) osgEarth::setNotifyLevel(osg::FATAL); float ambientBrightness = 0.2f; args.read("--ambientBrightness", ambientBrightness); std::string kmlFile; args.read( "--kml", kmlFile ); std::string imageFolder; args.read( "--images", imageFolder ); std::string imageExtensions; args.read("--image-extensions", imageExtensions); // animation path: std::string animpath; if ( args.read("--path", animpath) ) { view->setCameraManipulator( new osgGA::AnimationPathManipulator(animpath) ); } // Install a new Canvas for our UI controls, or use one that already exists. ControlCanvas* canvas = ControlCanvas::getOrCreate( view ); Container* mainContainer = canvas->addControl( new VBox() ); mainContainer->setAbsorbEvents( true ); mainContainer->setBackColor( Color(Color::Black, 0.8) ); mainContainer->setHorizAlign( Control::ALIGN_LEFT ); mainContainer->setVertAlign( Control::ALIGN_BOTTOM ); // install the user control: if ( userControl ) mainContainer->addControl( userControl ); // look for external data in the map node: const Config& externals = mapNode->externalConfig(); const Config& skyConf = externals.child("sky"); const Config& oceanConf = externals.child("ocean"); const Config& annoConf = externals.child("annotations"); const Config& declutterConf = externals.child("decluttering"); // some terrain effects. // TODO: Most of these are likely to move into extensions. const Config& lodBlendingConf = externals.child("lod_blending"); const Config& vertScaleConf = externals.child("vertical_scale"); const Config& contourMapConf = externals.child("contour_map"); // Adding a sky model: if ( useSky || !skyConf.empty() ) { SkyOptions options(skyConf); if ( options.getDriver().empty() ) { if ( mapNode->getMapSRS()->isGeographic() ) options.setDriver("simple"); else options.setDriver("gl"); } SkyNode* sky = SkyNode::create(options, mapNode); if ( sky ) { sky->attach( view, 0 ); if ( mapNode->getNumParents() > 0 ) { osgEarth::insertGroup(sky, mapNode->getParent(0)); } else { sky->addChild( mapNode ); root = sky; } Control* c = SkyControlFactory().create(sky, view); if ( c ) mainContainer->addControl( c ); if (animateSky) { sky->setUpdateCallback( new AnimateSkyUpdateCallback() ); } } } // Adding an ocean model: if ( useOcean || !oceanConf.empty() ) { OceanNode* ocean = OceanNode::create(OceanOptions(oceanConf), mapNode); if ( ocean ) { // if there's a sky, we want to ocean under it osg::Group* parent = osgEarth::findTopMostNodeOfType<SkyNode>(root); if ( !parent ) parent = root; parent->addChild( ocean ); Control* c = OceanControlFactory().create(ocean); if ( c ) mainContainer->addControl(c); } } // Shadowing. if ( useShadows ) { ShadowCaster* caster = new ShadowCaster(); caster->setLight( view->getLight() ); caster->getShadowCastingGroup()->addChild( mapNode->getModelLayerGroup() ); if ( mapNode->getNumParents() > 0 ) { insertGroup(caster, mapNode->getParent(0)); } else { caster->addChild(mapNode); root = caster; } } // Loading KML from the command line: if ( !kmlFile.empty() ) { KMLOptions kml_options; kml_options.declutter() = true; // set up a default icon for point placemarks: IconSymbol* defaultIcon = new IconSymbol(); defaultIcon->url()->setLiteral(KML_PUSHPIN_URL); kml_options.defaultIconSymbol() = defaultIcon; osg::Node* kml = KML::load( URI(kmlFile), mapNode, kml_options ); if ( kml ) { if (kmlUI) { Control* c = AnnotationGraphControlFactory().create(kml, view); if ( c ) { c->setVertAlign( Control::ALIGN_TOP ); canvas->addControl( c ); } } root->addChild( kml ); } else { OE_NOTICE << "Failed to load " << kmlFile << std::endl; } } // Annotations in the map node externals: if ( !annoConf.empty() ) { osg::Group* annotations = 0L; AnnotationRegistry::instance()->create( mapNode, annoConf, dbOptions.get(), annotations ); if ( annotations ) { root->addChild( annotations ); } } // Configure the de-cluttering engine for labels and annotations: if ( !declutterConf.empty() ) { Decluttering::setOptions( DeclutteringOptions(declutterConf) ); } // Configure the mouse coordinate readout: if ( useCoords ) { LabelControl* readout = new LabelControl(); readout->setBackColor( Color(Color::Black, 0.8) ); readout->setHorizAlign( Control::ALIGN_RIGHT ); readout->setVertAlign( Control::ALIGN_BOTTOM ); Formatter* formatter = useMGRS ? (Formatter*)new MGRSFormatter(MGRSFormatter::PRECISION_1M, 0L, MGRSFormatter::USE_SPACES) : useDMS ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DEGREES_MINUTES_SECONDS) : useDD ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DECIMAL_DEGREES) : 0L; MouseCoordsTool* mcTool = new MouseCoordsTool( mapNode ); mcTool->addCallback( new MouseCoordsLabelCallback(readout, formatter) ); view->addEventHandler( mcTool ); canvas->addControl( readout ); } // Configure for an ortho camera: if ( useOrtho ) { EarthManipulator* manip = dynamic_cast<EarthManipulator*>(view->getCameraManipulator()); if ( manip ) { manip->getSettings()->setCameraProjection( EarthManipulator::PROJ_ORTHOGRAPHIC ); } } // activity monitor (debugging) if ( showActivity ) { VBox* vbox = new VBox(); vbox->setBackColor( Color(Color::Black, 0.8) ); vbox->setHorizAlign( Control::ALIGN_RIGHT ); vbox->setVertAlign( Control::ALIGN_BOTTOM ); view->addEventHandler( new ActivityMonitorTool(vbox) ); canvas->addControl( vbox ); } // Install an auto clip plane clamper if ( useAutoClip ) { mapNode->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); } // Install logarithmic depth buffer on main camera if ( useLogDepth ) { OE_INFO << LC << "Activating logarithmic depth buffer on main camera" << std::endl; osgEarth::Util::LogarithmicDepthBuffer logDepth; logDepth.setUseFragDepth( true ); logDepth.install( view->getCamera() ); } else if ( useLogDepth2 ) { OE_INFO << LC << "Activating logarithmic depth buffer (vertex-only) on main camera" << std::endl; osgEarth::Util::LogarithmicDepthBuffer logDepth; logDepth.setUseFragDepth( false ); logDepth.install( view->getCamera() ); } // Scan for images if necessary. if ( !imageFolder.empty() ) { std::vector<std::string> extensions; if ( !imageExtensions.empty() ) StringTokenizer( imageExtensions, extensions, ",;", "", false, true ); if ( extensions.empty() ) extensions.push_back( "tif" ); OE_INFO << LC << "Loading images from " << imageFolder << "..." << std::endl; ImageLayerVector imageLayers; DataScanner scanner; scanner.findImageLayers( imageFolder, extensions, imageLayers ); if ( imageLayers.size() > 0 ) { mapNode->getMap()->beginUpdate(); for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i ) { mapNode->getMap()->addImageLayer( i->get() ); } mapNode->getMap()->endUpdate(); } OE_INFO << LC << "...found " << imageLayers.size() << " image layers." << std::endl; } // Install elevation morphing if ( !lodBlendingConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new LODBlending(lodBlendingConf) ); } // Install vertical scaler if ( !vertScaleConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new VerticalScale(vertScaleConf) ); } // Install a contour map effect. if ( !contourMapConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new ContourMap(contourMapConf) ); } // Generic named value uniform with min/max. VBox* uniformBox = 0L; while( args.find( "--uniform" ) >= 0 ) { std::string name; float minval, maxval; if ( args.read( "--uniform", name, minval, maxval ) ) { if ( uniformBox == 0L ) { uniformBox = new VBox(); uniformBox->setBackColor(0,0,0,0.5); uniformBox->setAbsorbEvents( true ); canvas->addControl( uniformBox ); } osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT, name); uniform->set( minval ); root->getOrCreateStateSet()->addUniform( uniform, osg::StateAttribute::OVERRIDE ); HBox* box = new HBox(); box->addControl( new LabelControl(name) ); HSliderControl* hs = box->addControl( new HSliderControl(minval, maxval, minval, new ApplyValueUniform(uniform))); hs->setHorizFill(true, 200); box->addControl( new LabelControl(hs) ); uniformBox->addControl( box ); OE_INFO << LC << "Installed uniform controller for " << name << std::endl; } } // Process extensions. for(std::vector<osg::ref_ptr<Extension> >::const_iterator eiter = mapNode->getExtensions().begin(); eiter != mapNode->getExtensions().end(); ++eiter) { Extension* e = eiter->get(); // Check for a View interface: ExtensionInterface<osg::View>* viewIF = ExtensionInterface<osg::View>::get( e ); if ( viewIF ) viewIF->connect( view ); // Check for a Control interface: ExtensionInterface<Control>* controlIF = ExtensionInterface<Control>::get( e ); if ( controlIF ) controlIF->connect( mainContainer ); } root->addChild( canvas ); }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); if (arguments.read("--help") || argc==1) { OE_WARN << "Usage: " << argv[0] << " [earthFile] [--model modelToLoad]" << std::endl; return 0; } osgViewer::Viewer viewer(arguments); // install the programmable manipulator. EarthManipulator* manip = new EarthManipulator(); viewer.setCameraManipulator( manip ); // UI: Container* help = createHelp(&viewer); osg::Node* earthNode = MapNodeHelper().load( arguments, &viewer, help ); if (!earthNode) { OE_WARN << "Unable to load earth model." << std::endl; return -1; } osg::Group* root = new osg::Group(); root->addChild( earthNode ); osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode ); // user model? osg::ref_ptr<osg::Node> model; std::string modelFile; if (arguments.read("--model", modelFile)) model = osgDB::readRefNodeFile(modelFile + ".osgearth_shadergen"); osg::Group* sims = new osg::Group(); root->addChild( sims ); const SpatialReference* wgs84 = SpatialReference::get("wgs84"); // Simulator for tethering: Simulator* sim1 = new Simulator(sims, manip, mapNode, model.get(), "Thing 1", '8'); sim1->_start = GeoPoint(wgs84, 45.0, 55.0, 10000); sim1->_end = GeoPoint(wgs84, -45, -55.0, 10000); viewer.addEventHandler(sim1); Simulator* sim2 = new Simulator(sims, manip, mapNode, model.get(), "Thing 2", '9'); sim2->_name = "Thing 2"; sim2->_start = GeoPoint(wgs84, 45.0, 54.0, 10000); sim2->_end = GeoPoint(wgs84, -44.0, -54.0, 10000); viewer.addEventHandler(sim2); manip->getSettings()->getBreakTetherActions().push_back( EarthManipulator::ACTION_GOTO ); // Set the minimum distance to something larger than the default manip->getSettings()->setMinMaxDistance(10.0, manip->getSettings()->getMaxDistance()); // Sets the maximum focal point offsets (usually for tethering) manip->getSettings()->setMaxOffset(5000.0, 5000.0); // Pitch limits. manip->getSettings()->setMinMaxPitch(-90, 90); viewer.setSceneData( root ); manip->getSettings()->bindMouse( EarthManipulator::ACTION_EARTH_DRAG, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON, osgGA::GUIEventAdapter::MODKEY_SHIFT ); manip->getSettings()->bindMouseClick( EarthManipulator::ACTION_GOTO, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON, osgGA::GUIEventAdapter::MODKEY_SHIFT); manip->getSettings()->setArcViewpointTransitions( true ); manip->setTetherCallback( new TetherCB() ); //viewer.addEventHandler(new FlyToViewpointHandler( manip )); viewer.addEventHandler(new LockAzimuthHandler('u', manip)); viewer.addEventHandler(new ToggleArcViewpointTransitionsHandler('a', manip)); viewer.addEventHandler(new ToggleThrowingHandler('q', manip)); viewer.addEventHandler(new ToggleCollisionHandler('k', manip)); viewer.addEventHandler(new ToggleProjMatrix('o', manip)); viewer.addEventHandler(new BreakTetherHandler('b', manip)); viewer.addEventHandler(new CycleTetherMode('t', manip)); viewer.addEventHandler(new SetPositionOffset(manip)); viewer.addEventHandler(new ToggleLDB('L')); viewer.addEventHandler(new ToggleSSL(sims, ')')); viewer.addEventHandler(new FitViewToPoints('j', manip, mapNode->getMapSRS())); CalculateWindowCoords* calc = new CalculateWindowCoords('W', manip, sim1); viewer.addEventHandler(calc); manip->setUpdateCameraCallback(new CameraUpdater(calc)); viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); while(!viewer.done()) { viewer.frame(); // simulate slow frame rate //OpenThreads::Thread::microSleep(1000*1000); } return 0; }
void MapNodeHelper::parse(MapNode* mapNode, osg::ArgumentParser& args, osgViewer::View* view, osg::Group* root, Control* userControl ) const { // this is a dubious move. if ( !root ) root = mapNode; // options to use for the load osg::ref_ptr<osgDB::Options> dbOptions = Registry::instance()->cloneOrCreateOptions(); // parse out custom example arguments first: bool useSky = args.read("--sky"); bool useOcean = args.read("--ocean"); bool useMGRS = args.read("--mgrs"); bool useDMS = args.read("--dms"); bool useDD = args.read("--dd"); bool useCoords = args.read("--coords") || useMGRS || useDMS || useDD; bool useOrtho = args.read("--ortho"); bool useAutoClip = args.read("--autoclip"); float ambientBrightness = 0.2f; args.read("--ambientBrightness", ambientBrightness); std::string kmlFile; args.read( "--kml", kmlFile ); std::string imageFolder; args.read( "--images", imageFolder ); std::string imageExtensions; args.read("--image-extensions", imageExtensions); // install a canvas for any UI controls we plan to create: ControlCanvas* canvas = ControlCanvas::get(view, false); Container* mainContainer = canvas->addControl( new VBox() ); mainContainer->setAbsorbEvents( true ); mainContainer->setBackColor( Color(Color::Black, 0.8) ); mainContainer->setHorizAlign( Control::ALIGN_LEFT ); mainContainer->setVertAlign( Control::ALIGN_BOTTOM ); // install the user control: if ( userControl ) mainContainer->addControl( userControl ); // look for external data in the map node: const Config& externals = mapNode->externalConfig(); const Config& skyConf = externals.child("sky"); const Config& oceanConf = externals.child("ocean"); const Config& annoConf = externals.child("annotations"); const Config& declutterConf = externals.child("decluttering"); Config viewpointsConf = externals.child("viewpoints"); // some terrain effects. const Config& normalMapConf = externals.child("normal_map"); const Config& detailTexConf = externals.child("detail_texture"); const Config& lodBlendingConf = externals.child("lod_blending"); const Config& vertScaleConf = externals.child("vertical_scale"); const Config& contourMapConf = externals.child("contour_map"); // backwards-compatibility: read viewpoints at the top level: const ConfigSet& old_viewpoints = externals.children("viewpoint"); for( ConfigSet::const_iterator i = old_viewpoints.begin(); i != old_viewpoints.end(); ++i ) viewpointsConf.add( *i ); // Loading a viewpoint list from the earth file: if ( !viewpointsConf.empty() ) { std::vector<Viewpoint> viewpoints; const ConfigSet& children = viewpointsConf.children(); if ( children.size() > 0 ) { for( ConfigSet::const_iterator i = children.begin(); i != children.end(); ++i ) { viewpoints.push_back( Viewpoint(*i) ); } } if ( viewpoints.size() > 0 ) { Control* c = ViewpointControlFactory().create(viewpoints, view); if ( c ) mainContainer->addControl( c ); } } // Adding a sky model: if ( useSky || !skyConf.empty() ) { double hours = skyConf.value( "hours", 12.0 ); SkyNode* sky = new SkyNode( mapNode->getMap() ); sky->setAmbientBrightness( ambientBrightness ); sky->setDateTime( DateTime(2011, 3, 6, hours) ); sky->attach( view ); root->addChild( sky ); Control* c = SkyControlFactory().create(sky, view); if ( c ) mainContainer->addControl( c ); } // Adding an ocean model: if ( useOcean || !oceanConf.empty() ) { OceanSurfaceNode* ocean = new OceanSurfaceNode( mapNode, oceanConf ); if ( ocean ) { root->addChild( ocean ); Control* c = OceanControlFactory().create(ocean, view); if ( c ) mainContainer->addControl(c); } } // Loading KML from the command line: if ( !kmlFile.empty() ) { KMLOptions kml_options; kml_options.declutter() = true; // set up a default icon for point placemarks: IconSymbol* defaultIcon = new IconSymbol(); defaultIcon->url()->setLiteral(KML_PUSHPIN_URL); kml_options.defaultIconSymbol() = defaultIcon; osg::Node* kml = KML::load( URI(kmlFile), mapNode, kml_options ); if ( kml ) { Control* c = AnnotationGraphControlFactory().create(kml, view); if ( c ) { c->setVertAlign( Control::ALIGN_TOP ); canvas->addControl( c ); } root->addChild( kml ); } } // Annotations in the map node externals: if ( !annoConf.empty() ) { osg::Group* annotations = 0L; AnnotationRegistry::instance()->create( mapNode, annoConf, dbOptions.get(), annotations ); if ( annotations ) { root->addChild( annotations ); } } // Configure the de-cluttering engine for labels and annotations: if ( !declutterConf.empty() ) { Decluttering::setOptions( DeclutteringOptions(declutterConf) ); } // Configure the mouse coordinate readout: if ( useCoords ) { LabelControl* readout = new LabelControl(); readout->setBackColor( Color(Color::Black, 0.8) ); readout->setHorizAlign( Control::ALIGN_RIGHT ); readout->setVertAlign( Control::ALIGN_BOTTOM ); Formatter* formatter = useMGRS ? (Formatter*)new MGRSFormatter(MGRSFormatter::PRECISION_1M, 0L, MGRSFormatter::USE_SPACES) : useDMS ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DEGREES_MINUTES_SECONDS) : useDD ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DECIMAL_DEGREES) : 0L; MouseCoordsTool* mcTool = new MouseCoordsTool( mapNode ); mcTool->addCallback( new MouseCoordsLabelCallback(readout, formatter) ); view->addEventHandler( mcTool ); canvas->addControl( readout ); } // Configure for an ortho camera: if ( useOrtho ) { EarthManipulator* manip = dynamic_cast<EarthManipulator*>(view->getCameraManipulator()); if ( manip ) { manip->getSettings()->setCameraProjection( EarthManipulator::PROJ_ORTHOGRAPHIC ); } } // Install an auto clip plane clamper if ( useAutoClip ) { mapNode->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); } // Scan for images if necessary. if ( !imageFolder.empty() ) { std::vector<std::string> extensions; if ( !imageExtensions.empty() ) StringTokenizer( imageExtensions, extensions, ",;", "", false, true ); if ( extensions.empty() ) extensions.push_back( "tif" ); OE_INFO << LC << "Loading images from " << imageFolder << "..." << std::endl; ImageLayerVector imageLayers; DataScanner scanner; scanner.findImageLayers( imageFolder, extensions, imageLayers ); if ( imageLayers.size() > 0 ) { mapNode->getMap()->beginUpdate(); for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i ) { mapNode->getMap()->addImageLayer( i->get() ); } mapNode->getMap()->endUpdate(); } OE_INFO << LC << "...found " << imageLayers.size() << " image layers." << std::endl; } // Install a normal map layer. if ( !normalMapConf.empty() ) { osg::ref_ptr<NormalMap> effect = new NormalMap(normalMapConf, mapNode->getMap()); if ( effect->getNormalMapLayer() ) { mapNode->getTerrainEngine()->addEffect( effect.get() ); } } // Install a detail texturer if ( !detailTexConf.empty() ) { osg::ref_ptr<DetailTexture> effect = new DetailTexture(detailTexConf); if ( effect->getImage() ) { mapNode->getTerrainEngine()->addEffect( effect.get() ); } } // Install elevation morphing if ( !lodBlendingConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new LODBlending(lodBlendingConf) ); } // Install vertical scaler if ( !vertScaleConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new VerticalScale(vertScaleConf) ); } // Install a contour map effect. if ( !contourMapConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new ContourMap(contourMapConf) ); } // Generic named value uniform with min/max. VBox* uniformBox = 0L; while( args.find( "--uniform" ) >= 0 ) { std::string name; float minval, maxval; if ( args.read( "--uniform", name, minval, maxval ) ) { if ( uniformBox == 0L ) { uniformBox = new VBox(); uniformBox->setBackColor(0,0,0,0.5); uniformBox->setAbsorbEvents( true ); canvas->addControl( uniformBox ); } osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT, name); uniform->set( minval ); root->getOrCreateStateSet()->addUniform( uniform, osg::StateAttribute::OVERRIDE ); HBox* box = new HBox(); box->addControl( new LabelControl(name) ); HSliderControl* hs = box->addControl( new HSliderControl(minval, maxval, minval, new ApplyValueUniform(uniform))); hs->setHorizFill(true, 200); box->addControl( new LabelControl(hs) ); uniformBox->addControl( box ); OE_INFO << LC << "Installed uniform controller for " << name << std::endl; } } root->addChild( canvas ); }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); if (arguments.read("--help") || argc==1) { OE_WARN << "Usage: " << argv[0] << " [earthFile] [--model modelToLoad]" << std::endl; return 0; } osgViewer::Viewer viewer(arguments); // install the programmable manipulator. EarthManipulator* manip = new EarthManipulator(); viewer.setCameraManipulator( manip ); // UI: Control* help = createHelp(&viewer); osg::Node* earthNode = MapNodeHelper().load( arguments, &viewer, help ); if (!earthNode) { OE_WARN << "Unable to load earth model." << std::endl; return -1; } osg::Group* root = new osg::Group(); root->addChild( earthNode ); osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode ); if ( mapNode ) { if ( mapNode ) manip->setNode( mapNode->getTerrainEngine() ); if ( mapNode->getMap()->isGeocentric() ) { manip->setHomeViewpoint( Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 5e7 ) ); } } // user model? osg::Node* model = 0L; std::string modelFile; if (arguments.read("--model", modelFile)) model = osgDB::readNodeFile(modelFile); // Simulator for tethering: viewer.addEventHandler( new Simulator(root, manip, mapNode, model) ); manip->getSettings()->getBreakTetherActions().push_back( EarthManipulator::ACTION_PAN ); manip->getSettings()->getBreakTetherActions().push_back( EarthManipulator::ACTION_GOTO ); viewer.setSceneData( root ); manip->getSettings()->bindMouse( EarthManipulator::ACTION_EARTH_DRAG, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON, osgGA::GUIEventAdapter::MODKEY_SHIFT ); manip->getSettings()->setArcViewpointTransitions( true ); viewer.addEventHandler(new FlyToViewpointHandler( manip )); viewer.addEventHandler(new LockAzimuthHandler('u', manip)); viewer.addEventHandler(new ToggleProjectionHandler('c', manip)); viewer.addEventHandler(new ToggleArcViewpointTransitionsHandler('a', manip)); viewer.addEventHandler(new ToggleThrowingHandler('z', manip)); while(!viewer.done()) { viewer.frame(); // simulate slow frame rate //OpenThreads::Thread::microSleep(1000*1000); } return 0; }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); // help? if ( arguments.read("--help") ) return usage(argv[0]); osg::Node* model = 0L; std::string filename; if (arguments.read("--model", filename)) { model = osgDB::readRefNodeFile(filename).release(); Registry::shaderGenerator().run(model); } // create a viewer: osgViewer::Viewer viewer(arguments); // Tell the database pager to not modify the unref settings viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy( false, false ); // install our default manipulator (do this before calling load) EarthManipulator* manip = new EarthManipulator(); viewer.setCameraManipulator(manip); // load an earth file, and support all or our example command-line options // and earth file <external> tags osg::Group* node = osgEarth::Util::MapNodeHelper().load(arguments, &viewer, createUI()); if ( node ) { viewer.getCamera()->setNearFarRatio(0.00002); viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f); viewer.setSceneData( node ); s_app.map = MapNode::get( node )->getMap(); s_app.addTriton(); s_app.addBuoyancyTest(model); // Zoom the camera to our area of interest: Viewpoint vp; vp.heading() = 25.0f; vp.pitch() = -25; vp.range() = 400.0; vp.focalPoint() = s_app.anchor; manip->setViewpoint(vp); while(!viewer.done()) { viewer.frame(); s_app.updateBuoyancyTest(); } } else { return usage(argv[0]); } }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osg::DisplaySettings::instance()->setMinimumNumStencilBits( 8 ); // install the programmable manipulator. EarthManipulator* manip = new EarthManipulator(); osg::Node* earthNode = osgDB::readNodeFiles( arguments ); if (!earthNode) { OE_WARN << "Unable to load earth model." << std::endl; return -1; } osgViewer::Viewer viewer(arguments); osg::Group* root = new osg::Group(); root->addChild( earthNode ); root->addChild( createHelp(&viewer) ); osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode ); if ( mapNode ) { if ( mapNode ) manip->setNode( mapNode->getTerrainEngine() ); if ( mapNode->getMap()->isGeocentric() ) { manip->setHomeViewpoint( Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 5e7 ) ); // add a handler that will automatically calculate good clipping planes viewer.addEventHandler( new AutoClipPlaneHandler() ); } } viewer.setSceneData( root ); viewer.setCameraManipulator( manip ); manip->getSettings()->bindMouse( EarthManipulator::ACTION_EARTH_DRAG, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON, osgGA::GUIEventAdapter::MODKEY_SHIFT ); manip->getSettings()->setArcViewpointTransitions( true ); viewer.addEventHandler(new FlyToViewpointHandler( manip )); viewer.addEventHandler(new LockAzimuthHandler('u', manip)); // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgViewer::ThreadingHandler()); viewer.addEventHandler(new osgViewer::LODScaleHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage())); //viewer.addEventHandler(new osgViewer::RecordCameraPathHandler()); return viewer.run(); }
void MapNodeHelper::parse(MapNode* mapNode, osg::ArgumentParser& args, osgViewer::View* view, osg::Group* root, Control* userControl ) const { // this is a dubious move. if ( !root ) root = mapNode; // options to use for the load osg::ref_ptr<osgDB::Options> dbOptions = Registry::instance()->cloneOrCreateOptions(); // parse out custom example arguments first: bool useSky = args.read("--sky"); bool useOcean = args.read("--ocean"); bool useMGRS = args.read("--mgrs"); bool useDMS = args.read("--dms"); bool useDD = args.read("--dd"); bool useCoords = args.read("--coords") || useMGRS || useDMS || useDD; bool useOrtho = args.read("--ortho"); bool useAutoClip = args.read("--autoclip"); float ambientBrightness = 0.4f; args.read("--ambientBrightness", ambientBrightness); std::string kmlFile; args.read( "--kml", kmlFile ); // install a canvas for any UI controls we plan to create: ControlCanvas* canvas = ControlCanvas::get(view, false); Container* mainContainer = canvas->addControl( new VBox() ); mainContainer->setBackColor( Color(Color::Black, 0.8) ); mainContainer->setHorizAlign( Control::ALIGN_LEFT ); mainContainer->setVertAlign( Control::ALIGN_BOTTOM ); // install the user control: if ( userControl ) mainContainer->addControl( userControl ); // look for external data in the map node: const Config& externals = mapNode->externalConfig(); const Config& skyConf = externals.child("sky"); const Config& oceanConf = externals.child("ocean"); const Config& annoConf = externals.child("annotations"); const Config& declutterConf = externals.child("decluttering"); Config viewpointsConf = externals.child("viewpoints"); // backwards-compatibility: read viewpoints at the top level: const ConfigSet& old_viewpoints = externals.children("viewpoint"); for( ConfigSet::const_iterator i = old_viewpoints.begin(); i != old_viewpoints.end(); ++i ) viewpointsConf.add( *i ); // Loading a viewpoint list from the earth file: if ( !viewpointsConf.empty() ) { std::vector<Viewpoint> viewpoints; const ConfigSet& children = viewpointsConf.children(); if ( children.size() > 0 ) { for( ConfigSet::const_iterator i = children.begin(); i != children.end(); ++i ) { viewpoints.push_back( Viewpoint(*i) ); } } if ( viewpoints.size() > 0 ) { Control* c = ViewpointControlFactory().create(viewpoints, view); if ( c ) mainContainer->addControl( c ); } } // Adding a sky model: if ( useSky || !skyConf.empty() ) { double hours = skyConf.value( "hours", 12.0 ); SkyNode* sky = new SkyNode( mapNode->getMap() ); sky->setAmbientBrightness( ambientBrightness ); sky->setDateTime( 2011, 3, 6, hours ); sky->attach( view ); root->addChild( sky ); Control* c = SkyControlFactory().create(sky, view); if ( c ) mainContainer->addControl( c ); } // Adding an ocean model: if ( useOcean || !oceanConf.empty() ) { OceanSurfaceNode* ocean = new OceanSurfaceNode( mapNode, oceanConf ); if ( ocean ) { root->addChild( ocean ); Control* c = OceanControlFactory().create(ocean, view); if ( c ) mainContainer->addControl(c); } } // Loading KML from the command line: if ( !kmlFile.empty() ) { KMLOptions kml_options; kml_options.declutter() = true; // set up a default icon for point placemarks: IconSymbol* defaultIcon = new IconSymbol(); defaultIcon->url()->setLiteral(KML_PUSHPIN_URL); kml_options.defaultIconSymbol() = defaultIcon; osg::Node* kml = KML::load( URI(kmlFile), mapNode, kml_options ); if ( kml ) { Control* c = AnnotationGraphControlFactory().create(kml, view); if ( c ) { c->setVertAlign( Control::ALIGN_TOP ); canvas->addControl( c ); } root->addChild( kml ); } } // Annotations in the map node externals: if ( !annoConf.empty() ) { osg::Group* annotations = 0L; AnnotationRegistry::instance()->create( mapNode, annoConf, dbOptions.get(), annotations ); if ( annotations ) { root->addChild( annotations ); } } // Configure the de-cluttering engine for labels and annotations: if ( !declutterConf.empty() ) { Decluttering::setOptions( DeclutteringOptions(declutterConf) ); } // Configure the mouse coordinate readout: if ( useCoords ) { LabelControl* readout = new LabelControl(); readout->setBackColor( Color(Color::Black, 0.8) ); readout->setHorizAlign( Control::ALIGN_RIGHT ); readout->setVertAlign( Control::ALIGN_BOTTOM ); Formatter* formatter = useMGRS ? (Formatter*)new MGRSFormatter(MGRSFormatter::PRECISION_1M, 0L, MGRSFormatter::USE_SPACES) : useDMS ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DEGREES_MINUTES_SECONDS) : useDD ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DECIMAL_DEGREES) : 0L; MouseCoordsTool* mcTool = new MouseCoordsTool( mapNode ); mcTool->addCallback( new MouseCoordsLabelCallback(readout, formatter) ); view->addEventHandler( mcTool ); canvas->addControl( readout ); } // Configure for an ortho camera: if ( useOrtho ) { EarthManipulator* manip = dynamic_cast<EarthManipulator*>(view->getCameraManipulator()); if ( manip ) { manip->getSettings()->setCameraProjection( EarthManipulator::PROJ_ORTHOGRAPHIC ); } } // Install an auto clip plane clamper if ( useAutoClip ) { #if 0 HorizonClipNode* hcn = new HorizonClipNode( mapNode ); if ( mapNode->getNumParents() == 1 ) { osg::Group* parent = mapNode->getParent(0); hcn->addChild( mapNode ); parent->replaceChild( mapNode, hcn ); } #else mapNode->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); #endif } root->addChild( canvas ); }
void MapNodeHelper::parse(MapNode* mapNode, osg::ArgumentParser& args, osgViewer::View* view, osg::Group* root, Container* userContainer ) const { if ( !root ) root = mapNode; // options to use for the load osg::ref_ptr<osgDB::Options> dbOptions = Registry::instance()->cloneOrCreateOptions(); // parse out custom example arguments first: bool useMGRS = args.read("--mgrs"); bool useDMS = args.read("--dms"); bool useDD = args.read("--dd"); bool useCoords = args.read("--coords") || useMGRS || useDMS || useDD; bool useAutoClip = args.read("--autoclip"); bool showActivity = args.read("--activity"); bool useLogDepth = args.read("--logdepth"); bool useLogDepth2 = args.read("--logdepth2"); bool kmlUI = args.read("--kmlui"); std::string kmlFile; args.read( "--kml", kmlFile ); std::string imageFolder; args.read( "--images", imageFolder ); std::string imageExtensions; args.read("--image-extensions", imageExtensions); // animation path: std::string animpath; if ( args.read("--path", animpath) ) { view->setCameraManipulator( new osgGA::AnimationPathManipulator(animpath) ); } // vertical field of view: float vfov = -1.0f; if (args.read("--vfov", vfov) && vfov > 0.0f) { double fov, ar, n, f; view->getCamera()->getProjectionMatrixAsPerspective(fov, ar, n, f); view->getCamera()->setProjectionMatrixAsPerspective(vfov, ar, n, f); } // Install a new Canvas for our UI controls, or use one that already exists. ControlCanvas* canvas = ControlCanvas::getOrCreate( view ); Container* mainContainer; if ( userContainer ) { mainContainer = userContainer; } else { mainContainer = new VBox(); mainContainer->setAbsorbEvents( true ); mainContainer->setBackColor( Color(Color::Black, 0.8) ); mainContainer->setHorizAlign( Control::ALIGN_LEFT ); mainContainer->setVertAlign( Control::ALIGN_BOTTOM ); } canvas->addControl( mainContainer ); // Add an event handler to toggle the canvas with a key press; view->addEventHandler(new ToggleCanvasEventHandler(canvas, 'y')); // look for external data in the map node: const Config& externals = mapNode->externalConfig(); // some terrain effects. // TODO: Most of these are likely to move into extensions. const Config& vertScaleConf = externals.child("vertical_scale"); // Loading KML from the command line: if ( !kmlFile.empty() ) { KMLOptions kml_options; kml_options.declutter() = true; // set up a default icon for point placemarks: IconSymbol* defaultIcon = new IconSymbol(); defaultIcon->url()->setLiteral(KML_PUSHPIN_URL); kml_options.defaultIconSymbol() = defaultIcon; TextSymbol* defaultText = new TextSymbol(); defaultText->halo() = Stroke(0.3,0.3,0.3,1.0); kml_options.defaultTextSymbol() = defaultText; osg::Node* kml = KML::load( URI(kmlFile), mapNode, kml_options ); if ( kml ) { if (kmlUI) { Control* c = AnnotationGraphControlFactory().create(kml, view); if ( c ) { c->setVertAlign( Control::ALIGN_TOP ); canvas->addControl( c ); } } mapNode->addChild( kml ); } else { OE_NOTICE << "Failed to load " << kmlFile << std::endl; } } // Configure the mouse coordinate readout: if ( useCoords ) { LabelControl* readout = new LabelControl(); readout->setBackColor( Color(Color::Black, 0.8) ); readout->setHorizAlign( Control::ALIGN_RIGHT ); readout->setVertAlign( Control::ALIGN_BOTTOM ); Formatter* formatter = useMGRS ? (Formatter*)new MGRSFormatter(MGRSFormatter::PRECISION_1M, 0L, MGRSFormatter::USE_SPACES) : useDMS ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DEGREES_MINUTES_SECONDS) : useDD ? (Formatter*)new LatLongFormatter(LatLongFormatter::FORMAT_DECIMAL_DEGREES) : 0L; MouseCoordsTool* mcTool = new MouseCoordsTool( mapNode ); mcTool->addCallback( new MouseCoordsLabelCallback(readout, formatter) ); view->addEventHandler( mcTool ); canvas->addControl( readout ); } // Configure for an ortho camera: if ( args.read("--ortho") ) { EarthManipulator* em = dynamic_cast<EarthManipulator*>(view->getCameraManipulator()); if (em) { double V, A, N, F; view->getCamera()->getProjectionMatrixAsPerspective(V, A, N, F); em->setInitialVFOV( V ); } view->getCamera()->setProjectionMatrixAsOrtho(-1, 1, -1, 1, 0, 1); } // activity monitor (debugging) if ( showActivity ) { VBox* vbox = new VBox(); vbox->setBackColor( Color(Color::Black, 0.8) ); vbox->setHorizAlign( Control::ALIGN_RIGHT ); vbox->setVertAlign( Control::ALIGN_BOTTOM ); view->addEventHandler( new ActivityMonitorTool(vbox) ); canvas->addControl( vbox ); } // Install an auto clip plane clamper if ( useAutoClip ) { mapNode->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); } // Install logarithmic depth buffer on main camera if ( useLogDepth ) { OE_INFO << LC << "Activating logarithmic depth buffer (vertex-only) on main camera" << std::endl; osgEarth::Util::LogarithmicDepthBuffer logDepth; logDepth.setUseFragDepth( false ); logDepth.install( view->getCamera() ); } else if ( useLogDepth2 ) { OE_INFO << LC << "Activating logarithmic depth buffer (precise) on main camera" << std::endl; osgEarth::Util::LogarithmicDepthBuffer logDepth; logDepth.setUseFragDepth( true ); logDepth.install( view->getCamera() ); } // Scan for images if necessary. if ( !imageFolder.empty() ) { std::vector<std::string> extensions; if ( !imageExtensions.empty() ) StringTokenizer( imageExtensions, extensions, ",;", "", false, true ); if ( extensions.empty() ) extensions.push_back( "tif" ); OE_INFO << LC << "Loading images from " << imageFolder << "..." << std::endl; ImageLayerVector imageLayers; DataScanner scanner; scanner.findImageLayers( imageFolder, extensions, imageLayers ); if ( imageLayers.size() > 0 ) { mapNode->getMap()->beginUpdate(); for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i ) { mapNode->getMap()->addLayer( i->get() ); } mapNode->getMap()->endUpdate(); } OE_INFO << LC << "...found " << imageLayers.size() << " image layers." << std::endl; } // Install vertical scaler. // TODO: deprecate this, or move it to an extension. if ( !vertScaleConf.empty() ) { mapNode->getTerrainEngine()->addEffect( new VerticalScale(vertScaleConf) ); } // Generic named value uniform with min/max. VBox* uniformBox = 0L; while( args.find( "--uniform" ) >= 0 ) { std::string name; float minval, maxval; if ( args.read( "--uniform", name, minval, maxval ) ) { if ( uniformBox == 0L ) { uniformBox = new VBox(); uniformBox->setBackColor(0,0,0,0.5); uniformBox->setAbsorbEvents( true ); canvas->addControl( uniformBox ); } osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT, name); uniform->set( minval ); root->getOrCreateStateSet()->addUniform( uniform, osg::StateAttribute::OVERRIDE ); HBox* box = new HBox(); box->addControl( new LabelControl(name) ); HSliderControl* hs = box->addControl( new HSliderControl(minval, maxval, minval, new ApplyValueUniform(uniform))); hs->setHorizFill(true, 200); box->addControl( new LabelControl(hs) ); uniformBox->addControl( box ); OE_INFO << LC << "Installed uniform controller for " << name << std::endl; } } while (args.find("--define") >= 0) { std::string name; if (args.read("--define", name)) { mapNode->getOrCreateStateSet()->setDefine(name); } } // Map inspector: if (args.read("--inspect")) { mapNode->addExtension( Extension::create("mapinspector", ConfigOptions()) ); } // Memory monitor: if (args.read("--monitor")) { mapNode->addExtension(Extension::create("monitor", ConfigOptions()) ); } // Simple sky model: if (args.read("--sky")) { std::string ext = mapNode->getMap()->isGeocentric() ? "sky_simple" : "sky_gl"; mapNode->addExtension(Extension::create(ext, ConfigOptions()) ); } // Simple ocean model: if (args.read("--ocean")) { mapNode->addExtension(Extension::create("ocean_simple", ConfigOptions())); } // Arbitrary extension: std::string extname; if (args.read("--extension", extname)) { Extension* ext = Extension::create(extname, ConfigOptions()); if (ext) mapNode->addExtension(ext); } // Hook up the extensions! for(std::vector<osg::ref_ptr<Extension> >::const_iterator eiter = mapNode->getExtensions().begin(); eiter != mapNode->getExtensions().end(); ++eiter) { Extension* e = eiter->get(); // Check for a View interface: ExtensionInterface<osg::View>* viewIF = ExtensionInterface<osg::View>::get( e ); if ( viewIF ) viewIF->connect( view ); // Check for a Control interface: ExtensionInterface<Control>* controlIF = ExtensionInterface<Control>::get( e ); if ( controlIF ) controlIF->connect( mainContainer ); } // Shadowing. This is last because it needs access to a light which may be provided // by one of the Sky extensions. if (args.read("--shadows")) { int unit; if ( mapNode->getTerrainEngine()->getResources()->reserveTextureImageUnit(unit, "ShadowCaster") ) { ShadowCaster* caster = new ShadowCaster(); caster->setTextureImageUnit( unit ); caster->setLight( view->getLight() ); caster->getShadowCastingGroup()->addChild( mapNode->getLayerNodeGroup() ); caster->getShadowCastingGroup()->addChild(mapNode->getTerrainEngine()); if ( mapNode->getNumParents() > 0 ) { osgEarth::insertGroup(caster, mapNode->getParent(0)); } else { caster->addChild(mapNode); root = caster; } } } root->addChild( canvas ); }
/** * This code example effectively duplicates the "boston.earth" sample, * demonstrating how to create a 3D city model in osgEarth. * * Run this from the tests folder. */ int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); // create the map. Map* map = new Map(); // add a TMS imagery layer: TMSOptions imagery; imagery.url() = "http://readymap.org/readymap/tiles/1.0.0/22/"; map->addImageLayer( new ImageLayer("ReadyMap imagery", imagery) ); // create a feature source to load the building footprint shapefile. OGRFeatureOptions feature_opt; feature_opt.name() = "buildings"; feature_opt.url() = "../data/boston_buildings_utm19.shp"; feature_opt.buildSpatialIndex() = true; // a style for the building data: Style buildingStyle; buildingStyle.setName( "default" ); ExtrusionSymbol* extrusion = buildingStyle.getOrCreate<ExtrusionSymbol>(); extrusion->heightExpression() = NumericExpression( "3.5 * max( [story_ht_], 1 )" ); extrusion->flatten() = true; extrusion->wallStyleName() = "building-wall"; extrusion->roofStyleName() = "building-roof"; // a style for the wall textures: Style wallStyle; wallStyle.setName( "building-wall" ); SkinSymbol* wallSkin = wallStyle.getOrCreate<SkinSymbol>(); wallSkin->libraryName() = "us_resources"; wallSkin->addTag( "building" ); wallSkin->randomSeed() = 1; // a style for the rooftop textures: Style roofStyle; roofStyle.setName( "building-roof" ); SkinSymbol* roofSkin = roofStyle.getOrCreate<SkinSymbol>(); roofSkin->libraryName() = "us_resources"; roofSkin->addTag( "rooftop" ); roofSkin->randomSeed() = 1; roofSkin->isTiled() = true; // assemble a stylesheet and add our styles to it: StyleSheet* styleSheet = new StyleSheet(); styleSheet->addStyle( buildingStyle ); styleSheet->addStyle( wallStyle ); styleSheet->addStyle( roofStyle ); // load a resource library that contains the building textures. ResourceLibrary* reslib = new ResourceLibrary( "us_resources", "../data/resources/textures_us/catalog.xml" ); styleSheet->addResourceLibrary( reslib ); // set up a paging layout for incremental loading. FeatureDisplayLayout layout; layout.tileSizeFactor() = 45.0; layout.addLevel( FeatureLevel(0.0f, 20000.0f) ); // create a model layer that will render the buildings according to our style sheet. FeatureGeomModelOptions fgm_opt; fgm_opt.featureOptions() = feature_opt; fgm_opt.styles() = styleSheet; fgm_opt.layout() = layout; map->addModelLayer( new ModelLayer( "buildings", fgm_opt ) ); // initialize a viewer: osgViewer::Viewer viewer(arguments); EarthManipulator* manip = new EarthManipulator(); viewer.setCameraManipulator( manip ); // make the map scene graph: osg::Group* root = new osg::Group(); viewer.setSceneData( root ); MapNode* mapNode = new MapNode( map ); root->addChild( mapNode ); // Process cmdline args MapNodeHelper helper; helper.configureView( &viewer ); helper.parse(mapNode, arguments, &viewer, root, new LabelControl("City Demo")); // zoom to a good startup position manip->setViewpoint( Viewpoint(-71.0763, 42.34425, 0, 24.261, -21.6, 3450.0), 5.0 ); viewer.getDatabasePager()->setDoPreCompile( true ); viewer.getCamera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode) ); return viewer.run(); }