void setupOverlayView( osgViewer::View* view, osg::Group* parent, MapNode* mapNode ) { ControlCanvas* canvas = ControlCanvas::getOrCreate(view); VBox* v = canvas->addControl(new VBox()); v->setBackColor( Color(Color::Black,0.75) ); { HBox* camBox = v->addControl(new HBox()); { camBox->addControl(s_cameraCheck = new CheckBoxControl(true, new Toggle(parent,"camera"))); camBox->addControl(new LabelControl("Camera", Color("#00ff00"))); } //HBox* overlayBox = v->addControl(new HBox()); //{ // overlayBox->addControl(s_overlayCheck = new CheckBoxControl(false, new Toggle(parent,"overlay"))); // overlayBox->addControl(new LabelControl("Overlay", Color("#00ffff"))); //} HBox* isectBox = v->addControl(new HBox()); { isectBox->addControl(s_intersectionCheck = new CheckBoxControl(true, new Toggle(parent,"intersection"))); isectBox->addControl(new LabelControl("Intersection",Color("#ff7f00"))); } HBox* rttBox = v->addControl(new HBox()); { rttBox->addControl(s_rttCheck = new CheckBoxControl(true, new Toggle(parent,"rtt"))); rttBox->addControl(new LabelControl("RTT", Color("#ffff00"))); } } view->addEventHandler( new PHDumper(mapNode, parent) ); }
Container* createControlPanel(osgViewer::View* view) { ControlCanvas* canvas = ControlCanvas::getOrCreate(view); VBox* vbox = canvas->addControl(new VBox()); vbox->setChildSpacing(10); return vbox; }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); s_mapNode = MapNode::load(arguments); if ( !s_mapNode ) { OE_WARN << "Unable to load earth file." << std::endl; return -1; } osg::Group* root = new osg::Group(); viewer.setSceneData( root ); // install the programmable manipulator. viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); // The MapNode will render the Map object in the scene graph. root->addChild( s_mapNode ); // Make the readout: Grid* grid = new Grid(); grid->setControl(0,0,new LabelControl("Coords (Lat, Long):")); grid->setControl(0,1,new LabelControl("Vertical Datum:")); grid->setControl(0,2,new LabelControl("Height (MSL):")); grid->setControl(0,3,new LabelControl("Height (HAE):")); grid->setControl(0,4,new LabelControl("Isect (HAE):")); grid->setControl(0,5,new LabelControl("Resolution:")); s_posLabel = grid->setControl(1,0,new LabelControl("")); s_vdaLabel = grid->setControl(1,1,new LabelControl("")); s_mslLabel = grid->setControl(1,2,new LabelControl("")); s_haeLabel = grid->setControl(1,3,new LabelControl("")); s_mapLabel = grid->setControl(1,4,new LabelControl("")); s_resLabel = grid->setControl(1,5,new LabelControl("")); const SpatialReference* mapSRS = s_mapNode->getMapSRS(); s_vdaLabel->setText( mapSRS->getVerticalDatum() ? mapSRS->getVerticalDatum()->getName() : Stringify() << "geodetic (" << mapSRS->getEllipsoid()->getName() << ")" ); ControlCanvas* canvas = new ControlCanvas(); root->addChild(canvas); canvas->addControl( grid ); // An event handler that will respond to mouse clicks: viewer.addEventHandler( new QueryElevationHandler() ); // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); return viewer.run(); }
void createControlPanel( osgViewer::View* view ) { ControlCanvas* canvas = ControlCanvas::getOrCreate( view ); s_masterGrid = new Grid(); s_masterGrid->setBackColor(0,0,0,0.5); s_masterGrid->setMargin( 10 ); s_masterGrid->setPadding( 10 ); s_masterGrid->setChildSpacing( 10 ); s_masterGrid->setChildVertAlign( Control::ALIGN_CENTER ); s_masterGrid->setAbsorbEvents( true ); s_masterGrid->setVertAlign( Control::ALIGN_TOP ); //The image layers s_imageBox = new Grid(); s_imageBox->setBackColor(0,0,0,0.5); s_imageBox->setMargin( 10 ); s_imageBox->setPadding( 10 ); s_imageBox->setChildSpacing( 10 ); s_imageBox->setChildVertAlign( Control::ALIGN_CENTER ); s_imageBox->setAbsorbEvents( true ); s_imageBox->setVertAlign( Control::ALIGN_TOP ); s_masterGrid->setControl( 0, 0, s_imageBox ); //the elevation layers s_elevationBox = new Grid(); s_elevationBox->setBackColor(0,0,0,0.5); s_elevationBox->setMargin( 10 ); s_elevationBox->setPadding( 10 ); s_elevationBox->setChildSpacing( 10 ); s_elevationBox->setChildVertAlign( Control::ALIGN_CENTER ); s_elevationBox->setAbsorbEvents( true ); s_elevationBox->setVertAlign( Control::ALIGN_TOP ); s_masterGrid->setControl( 1, 0, s_elevationBox ); //The image layers s_modelBox = new Grid(); s_modelBox->setBackColor(0,0,0,0.5); s_modelBox->setMargin( 10 ); s_modelBox->setPadding( 10 ); s_modelBox->setChildSpacing( 10 ); s_modelBox->setChildVertAlign( Control::ALIGN_CENTER ); s_modelBox->setAbsorbEvents( true ); s_modelBox->setVertAlign( Control::ALIGN_TOP ); s_masterGrid->setControl( 2, 0, s_modelBox ); canvas->addControl( s_masterGrid ); }
osg::Node* createControlPanel( osgViewer::View* view ) { ControlCanvas* canvas = ControlCanvas::get( view ); // the outer container: s_layerBox = new Grid(); s_layerBox->setBackColor(0,0,0,0.5); s_layerBox->setMargin( 10 ); s_layerBox->setPadding( 10 ); s_layerBox->setChildSpacing( 10 ); s_layerBox->setChildVertAlign( Control::ALIGN_CENTER ); s_layerBox->setAbsorbEvents( true ); s_layerBox->setVertAlign( Control::ALIGN_BOTTOM ); canvas->addControl( s_layerBox ); return canvas; }
void createControlPanel( osgViewer::View* view ) { ControlCanvas* canvas = ControlCanvas::getOrCreate( view ); s_masterGrid = new Grid(); s_masterGrid->setMargin( 5 ); s_masterGrid->setPadding( 5 ); s_masterGrid->setChildSpacing( 10 ); s_masterGrid->setChildVertAlign( Control::ALIGN_CENTER ); s_masterGrid->setAbsorbEvents( true ); s_masterGrid->setVertAlign( Control::ALIGN_TOP ); //The Map layers s_activeBox = new Grid(); s_activeBox->setBackColor(0,0,0,0.5); s_activeBox->setMargin( 10 ); s_activeBox->setPadding( 10 ); s_activeBox->setChildSpacing( 10 ); s_activeBox->setChildVertAlign( Control::ALIGN_CENTER ); s_activeBox->setAbsorbEvents( true ); s_activeBox->setVertAlign( Control::ALIGN_TOP ); s_masterGrid->setControl( 0, 0, s_activeBox ); //the removed layers s_inactiveBox = new Grid(); s_inactiveBox->setBackColor(0,0,0,0.5); s_inactiveBox->setMargin( 10 ); s_inactiveBox->setPadding( 10 ); s_inactiveBox->setChildSpacing( 10 ); s_inactiveBox->setChildVertAlign( Control::ALIGN_CENTER ); s_inactiveBox->setAbsorbEvents( true ); s_inactiveBox->setVertAlign( Control::ALIGN_TOP ); s_masterGrid->setControl( 0, 1, s_inactiveBox ); canvas->addControl( s_masterGrid ); }
// // NOTE: run this sample from the repo/tests directory. // int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); s_viewer = &viewer; // Start by creating the map: s_mapNode = MapNode::load(arguments); if ( !s_mapNode ) { Map* map = new Map(); // Start with a basemap imagery layer; we'll be using the GDAL driver // to load a local GeoTIFF file: GDALOptions basemapOpt; basemapOpt.url() = "../data/world.tif"; map->addImageLayer( new ImageLayer( ImageLayerOptions("basemap", basemapOpt) ) ); // That's it, the map is ready; now create a MapNode to render the Map: MapNodeOptions mapNodeOptions; mapNodeOptions.enableLighting() = false; s_mapNode = new MapNode( map, mapNodeOptions ); } s_mapNode->setNodeMask( 0x01 ); // Define a style for the feature data. Style style = buildStyle( Color::Yellow, 2.0f ); //LineString* line = new LineString(); Geometry* geom = GeometryUtils::geometryFromWKT("POLYGON((191.026667 87.63333,114.75 78,89.5 77.333336,81.833336 75.333336,70.683334 74.5,70.916664 73.666664,68.666664 73.666664,66.291664 71.505,57.65 71.166664,58 73.9,48.616665 73,49.198334 71.43,49.5 70.5,43.266666 68.666664,32.083332 71.5,32.083332 74,35 74,35 81,32 81,32 90,191.026667 87.63333))"); OE_NOTICE << "Geometry " << GeometryUtils::geometryToWKT(geom) << std::endl; Feature* feature = new Feature(geom, s_mapNode->getMapSRS(), Style(), s_fid++); s_featureNode = new FeatureNode( s_mapNode, feature ); s_featureNode->setStyle( style ); s_editorsRoot = new osg::Group; s_root = new osg::Group; s_root->addChild( s_mapNode.get() ); s_root->addChild( s_featureNode.get() ); s_root->addChild( s_editorsRoot.get() ); //Setup the controls ControlCanvas* canvas = ControlCanvas::getOrCreate( &viewer ); s_root->addChild( canvas ); Grid *toolbar = createToolBar( ); canvas->addControl( toolbar ); canvas->setNodeMask( 0x1 << 1 ); int col = 0; LabelControl* addVerts = new LabelControl("Add Verts"); toolbar->setControl(col++, 0, addVerts ); addVerts->addEventHandler( new AddVertsModeHandler()); LabelControl* edit = new LabelControl("Edit"); toolbar->setControl(col++, 0, edit ); edit->addEventHandler(new EditModeHandler()); unsigned int row = 0; Grid *styleBar = createToolBar( ); styleBar->setPosition(0, 50); canvas->addControl( styleBar ); //Make a list of styles styleBar->setControl(0, row++, new LabelControl("Styles") ); unsigned int numStyles = 8; for (unsigned int i = 0; i < numStyles; ++i) { float w = 50; osg::Vec4 color = randomColor(); float widths[3] = {2, 4, 8}; unsigned int r = row++; for (unsigned int j = 0; j < 3; j++) { Control* l = new Control(); l->setBackColor( color ); l->addEventHandler(new ChangeStyleHandler(buildStyle( color, widths[j] ) )); l->setSize(w,5 * widths[j]); styleBar->setControl(j, r, l); } } viewer.setSceneData( s_root.get() ); viewer.setCameraManipulator( new EarthManipulator() ); if ( s_mapNode ) viewer.getCamera()->addCullCallback( new osgEarth::Util::AutoClipPlaneCullCallback(s_mapNode) ); // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); 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.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 ); }
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 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; 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) ); // look for external data in the map node: const Config& externals = mapNode->externalConfig(); //const Config& screenSpaceLayoutConf = // externals.hasChild("screen_space_layout") ? externals.child("screen_space_layout") : // externals.child("decluttering"); // backwards-compatibility // 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"); // Shadowing. 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 ); 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; 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 ); } } root->addChild( kml ); } else { OE_NOTICE << "Failed to load " << kmlFile << std::endl; } } //// Configure the de-cluttering engine for labels and annotations: //if ( !screenSpaceLayoutConf.empty() ) //{ // ScreenSpaceLayout::setOptions( ScreenSpaceLayoutOptions(screenSpaceLayoutConf) ); //} // 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") ) { 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()->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 (args.read("--contourmap")) { mapNode->addExtension(Extension::create("contourmap", ConfigOptions())); // with the cmdline switch, hids all the image layer so we can see the contour map. for (unsigned i = 0; i < mapNode->getMap()->getNumImageLayers(); ++i) { mapNode->getMap()->getImageLayerAt(i)->setVisible(false); } } // 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; } } // 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")) { mapNode->addExtension(Extension::create("sky_simple", ConfigOptions()) ); } // Simple ocean model: if (args.read("--ocean")) { mapNode->addExtension(Extension::create("ocean_simple", ConfigOptions())); } // 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 ); } root->addChild( canvas ); }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osg::DisplaySettings::instance()->setMinimumNumStencilBits( 8 ); osgViewer::Viewer viewer(arguments); // load the .earth file from the command line. osg::Node* earthNode = MapNodeHelper().load( arguments, &viewer ); if (!earthNode) { OE_NOTICE << "Unable to load earth model." << std::endl; return 1; } MapNode* mapNode = MapNode::findMapNode( earthNode ); if ( !mapNode ) { OE_NOTICE << "Input file was not a .earth file" << std::endl; return 1; } earthNode->setNodeMask( 0x1 ); osgEarth::Util::EarthManipulator* earthManip = new EarthManipulator(); viewer.setCameraManipulator( earthManip ); osg::Group* root = new osg::Group(); root->addChild( earthNode ); //Create the MeasureToolHandler MeasureToolHandler* measureTool = new MeasureToolHandler(root, mapNode); measureTool->setIntersectionMask( 0x1 ); viewer.addEventHandler( measureTool ); //Create some controls to interact with the measuretool ControlCanvas* canvas = new ControlCanvas( &viewer ); root->addChild( canvas ); canvas->setNodeMask( 0x1 << 1 ); Grid* grid = new Grid(); grid->setBackColor(0,0,0,0.5); grid->setMargin( 10 ); grid->setPadding( 10 ); grid->setChildSpacing( 10 ); grid->setChildVertAlign( Control::ALIGN_CENTER ); grid->setAbsorbEvents( true ); grid->setVertAlign( Control::ALIGN_BOTTOM ); canvas->addControl( grid ); //Add a label to display the distance // Add a text label: grid->setControl( 0, 0, new LabelControl("Distance:") ); LabelControl* label = new LabelControl(); label->setFont( osgEarth::Registry::instance()->getDefaultFont() ); label->setFontSize( 24.0f ); label->setHorizAlign( Control::ALIGN_LEFT ); label->setText("click to measure"); grid->setControl( 1, 0, label ); //Add a callback to update the label when the distance changes measureTool->addEventHandler( new MyMeasureToolCallback(label) ); Style style = measureTool->getLineStyle(); style.getOrCreate<LineSymbol>()->stroke()->color() = Color::Red; style.getOrCreate<LineSymbol>()->stroke()->width() = 4.0f; measureTool->setLineStyle(style); //Add a checkbox to control if we are doing path based measurement or just point to point grid->setControl( 0, 1, new LabelControl("Path")); CheckBoxControl* checkBox = new CheckBoxControl(false); checkBox->setHorizAlign(Control::ALIGN_LEFT); checkBox->addEventHandler( new TogglePathHandler(measureTool)); grid->setControl( 1, 1, checkBox); //Add a toggle to set the mode of the measuring tool grid->setControl( 0, 2, new LabelControl("Great Circle")); CheckBoxControl* mode = new CheckBoxControl(true); mode->setHorizAlign(Control::ALIGN_LEFT); mode->addEventHandler( new ToggleModeHandler(measureTool)); grid->setControl( 1, 2, mode); //Add a mouse coords readout: LabelControl* mouseLabel = new LabelControl(); grid->setControl( 0, 3, new LabelControl("Mouse:")); grid->setControl( 1, 3, mouseLabel ); viewer.addEventHandler(new MouseCoordsTool(mapNode, mouseLabel) ); viewer.setSceneData( root ); // 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())); return viewer.run(); }
void MapNodeHelper::parse(MapNode* mapNode, osg::ArgumentParser& args, osgViewer::View* view, osg::Group* root, Control* userControl ) const { if ( !root ) root = mapNode; // 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; 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->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; kml_options.defaultIconImage() = URI( KML_PUSHPIN_URL ).getImage(); 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, 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 ); } root->addChild( canvas ); }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); bool test1 = arguments.read("--test1"); bool test2 = arguments.read("--test2"); bool test3 = arguments.read("--test3"); bool test4 = arguments.read("--test4"); bool test5 = arguments.read("--test5"); bool ok = test1 || test2 || test3 || test4 || test5; if ( !ok ) { return usage(""); } osg::Group* root = new osg::Group(); viewer.setSceneData( root ); // add a canvas: ControlCanvas* canvas = new ControlCanvas(); root->addChild( canvas ); // and a label: LabelControl* label = new LabelControl(); canvas->addControl(label); if ( !test5 ) { osg::Node* earthNode = osgDB::readNodeFile( "http://osgearth.org/demo.earth" ); if (!earthNode) { return usage( "Unable to load earth model." ); } if ( test1 ) { root->addChild( TEST_1::run(earthNode) ); label->setText( "Function injection test: the map appears hazy at high altitude." ); } else if ( test2 ) { root->addChild( TEST_2::run(earthNode) ); label->setText( "Accept callback test: the map turns red when viewport width > 1000" ); } else if ( test3 ) { root->addChild( TEST_3::run(earthNode) ); label->setText( "Shader LOD test: the map turns red between 500K and 1M meters altitude" ); } else if ( test4 ) { root->addChild( TEST_4::run(earthNode) ); label->setText("Memory management test; monitor memory for stability"); } viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); } else // if ( test5 ) { root->addChild( TEST_5::run() ); label->setText( "Leakage test: red tri on the left, blue on the right." ); } // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgViewer::ThreadingHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); 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 ); }
/** creates some UI controls for adjusting the decluttering parameters. */ void createControls( osgViewer::View* view ) { ControlCanvas* canvas = ControlCanvas::getOrCreate(view); // title bar VBox* vbox = canvas->addControl(new VBox(Control::ALIGN_NONE, Control::ALIGN_BOTTOM, 2, 1 )); vbox->setBackColor( Color(Color::Black, 0.5) ); vbox->addControl( new LabelControl("osgEarth Tracks Demo", Color::Yellow) ); // checkbox that toggles decluttering of tracks struct ToggleDecluttering : public ControlEventHandler { void onValueChanged( Control* c, bool on ) { Decluttering::setEnabled( on ); } }; HBox* dcToggle = vbox->addControl( new HBox() ); dcToggle->addControl( new CheckBoxControl(true, new ToggleDecluttering()) ); dcToggle->addControl( new LabelControl("Declutter") ); // checkbox that toggles the coordinate display struct ToggleCoords : public ControlEventHandler { void onValueChanged( Control* c, bool on ) { g_showCoords = on; } }; HBox* coordsToggle = vbox->addControl( new HBox() ); coordsToggle->addControl( new CheckBoxControl(true, new ToggleCoords()) ); coordsToggle->addControl( new LabelControl("Show locations") ); // grid for the slider controls so they look nice Grid* grid = vbox->addControl( new Grid() ); grid->setHorizFill( true ); grid->setChildHorizAlign( Control::ALIGN_LEFT ); grid->setChildSpacing( 6 ); unsigned r=0; // event handler for changing decluttering options struct ChangeFloatOption : public ControlEventHandler { optional<float>& _param; LabelControl* _label; ChangeFloatOption( optional<float>& param, LabelControl* label ) : _param(param), _label(label) { } void onValueChanged( Control* c, float value ) { _param = value; _label->setText( Stringify() << std::fixed << std::setprecision(1) << value ); Decluttering::setOptions( g_dcOptions ); } }; grid->setControl( 0, r, new LabelControl("Sim loop duration:") ); LabelControl* speedLabel = grid->setControl( 2, r, new LabelControl(Stringify() << std::fixed << std::setprecision(1) << *g_duration) ); HSliderControl* speedSlider = grid->setControl( 1, r, new HSliderControl( 600.0, 30.0, *g_duration, new ChangeFloatOption(g_duration, speedLabel) ) ); speedSlider->setHorizFill( true, 200 ); grid->setControl( 0, ++r, new LabelControl("Min scale:") ); LabelControl* minAnimationScaleLabel = grid->setControl( 2, r, new LabelControl(Stringify() << std::fixed << std::setprecision(1) << *g_dcOptions.minAnimationScale()) ); grid->setControl( 1, r, new HSliderControl( 0.0, 1.0, *g_dcOptions.minAnimationScale(), new ChangeFloatOption(g_dcOptions.minAnimationScale(), minAnimationScaleLabel) ) ); grid->setControl( 0, ++r, new LabelControl("Min alpha:") ); LabelControl* alphaLabel = grid->setControl( 2, r, new LabelControl(Stringify() << std::fixed << std::setprecision(1) << *g_dcOptions.minAnimationAlpha()) ); grid->setControl( 1, r, new HSliderControl( 0.0, 1.0, *g_dcOptions.minAnimationAlpha(), new ChangeFloatOption(g_dcOptions.minAnimationAlpha(), alphaLabel) ) ); grid->setControl( 0, ++r, new LabelControl("Activate time (s):") ); LabelControl* actLabel = grid->setControl( 2, r, new LabelControl(Stringify() << std::fixed << std::setprecision(1) << *g_dcOptions.inAnimationTime()) ); grid->setControl( 1, r, new HSliderControl( 0.0, 2.0, *g_dcOptions.inAnimationTime(), new ChangeFloatOption(g_dcOptions.inAnimationTime(), actLabel) ) ); grid->setControl( 0, ++r, new LabelControl("Deactivate time (s):") ); LabelControl* deactLabel = grid->setControl( 2, r, new LabelControl(Stringify() << std::fixed << std::setprecision(1) << *g_dcOptions.outAnimationTime()) ); grid->setControl( 1, r, new HSliderControl( 0.0, 2.0, *g_dcOptions.outAnimationTime(), new ChangeFloatOption(g_dcOptions.outAnimationTime(), deactLabel) ) ); }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); bool test1 = arguments.read("--test1"); bool test2 = arguments.read("--test2"); bool test3 = arguments.read("--test3"); bool test4 = arguments.read("--test4"); bool test5 = arguments.read("--test5"); bool test6 = arguments.read("--test6"); bool test7 = arguments.read("--test7"); bool test8 = arguments.read("--test8"); bool test9 = arguments.read("--test9"); bool ok = test1 || test2 || test3 || test4 || test5 || test6 || test7 || test8||test9; bool ui = !arguments.read("--noui"); if ( !ok ) { return usage(""); } osg::Group* root = new osg::Group(); viewer.setSceneData( root ); LabelControl* label = new LabelControl(); if ( ui ) { // add a canvas: ControlCanvas* canvas = new ControlCanvas(); root->addChild( canvas ); // and a label: canvas->addControl(label); } if ( test1 || test2 || test3 || test4 || test6 ) { osg::Node* earthNode = osgDB::readNodeFile( "gdal_tiff.earth" ); if (!earthNode) { return usage( "Unable to load earth model." ); } if ( test1 ) { root->addChild( TEST_1::run(earthNode) ); if (ui) label->setText( "Function injection test: the map appears hazy at high altitude." ); } else if ( test2 ) { root->addChild( TEST_2::run(earthNode) ); if (ui) label->setText( "Accept callback test: the map turns red when viewport width > 1000" ); } else if ( test3 ) { root->addChild( TEST_3::run(earthNode) ); if (ui) label->setText( "Shader LOD test: the map turns red between 500K and 1M meters altitude" ); } else if ( test4 ) { root->addChild( TEST_4::run(earthNode) ); if (ui) label->setText("Memory management test; monitor memory for stability"); } else if ( test6 ) { root->addChild( TEST_6::run(earthNode) ); if (ui) label->setText("State Memory Stack test; top row, both=blue. bottom left=red, bottom right=normal."); } viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); } else if ( test5 ) { osgEarth::Registry::instance()->getCapabilities(); root->addChild( TEST_5::run() ); if (ui) label->setText( "Leakage test: red tri on the left, blue on the right." ); } else if ( test7 ) { root->addChild( TEST_7::run( osgDB::readNodeFiles(arguments) ) ); if (ui) label->setText("Geometry Shader Injection Test."); } else if (test8) { root->addChild( TEST_8::run() ); if (ui) label->setText("Serialization test"); } else if (test9) { osg::Node* earthNode = osgDB::readNodeFile( "readymap.earth" ); if (!earthNode) { return usage( "Unable to load earth model." ); } root->addChild(TEST_9::run(earthNode)); if (ui) label->setText("DP Shader Test - see code comments"); viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); } // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgViewer::ThreadingHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); return viewer.run(); }
// // NOTE: run this sample from the repo/tests directory. // int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); s_viewer = &viewer; // Start by creating the map: s_mapNode = MapNode::load(arguments); if ( !s_mapNode ) { Map* map = new Map(); // Start with a basemap imagery layer; we'll be using the GDAL driver // to load a local GeoTIFF file: GDALOptions basemapOpt; basemapOpt.url() = "../data/world.tif"; map->addImageLayer( new ImageLayer( ImageLayerOptions("basemap", basemapOpt) ) ); // That's it, the map is ready; now create a MapNode to render the Map: MapNodeOptions mapNodeOptions; mapNodeOptions.enableLighting() = false; s_mapNode = new MapNode( map, mapNodeOptions ); } s_mapNode->setNodeMask( 0x01 ); // Define a style for the feature data. Since we are going to render the // vectors as lines, configure the line symbolizer: StyleSheet* styleSheet = buildStyleSheet( Color::Yellow, 2.0f ); s_source = new FeatureListSource(); LineString* line = new LineString(); line->push_back( osg::Vec3d(-60, 20, 0) ); line->push_back( osg::Vec3d(-120, 20, 0) ); line->push_back( osg::Vec3d(-120, 60, 0) ); line->push_back( osg::Vec3d(-60, 60, 0) ); Feature *feature = new Feature(line, s_mapNode->getMapSRS(), Style(), s_fid++); s_source->insertFeature( feature ); s_activeFeature = feature; s_root = new osg::Group; s_root->addChild( s_mapNode.get() ); Session* session = new Session(s_mapNode->getMap(), styleSheet, s_source.get()); FeatureModelGraph* graph = new FeatureModelGraph( session, FeatureModelSourceOptions(), new GeomFeatureNodeFactory() ); graph->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); graph->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); s_root->addChild( graph ); //Setup the controls ControlCanvas* canvas = ControlCanvas::get( &viewer ); s_root->addChild( canvas ); Grid *toolbar = createToolBar( ); canvas->addControl( toolbar ); canvas->setNodeMask( 0x1 << 1 ); int col = 0; LabelControl* addVerts = new LabelControl("Add Verts"); toolbar->setControl(col++, 0, addVerts ); addVerts->addEventHandler( new AddVertsModeHandler( graph )); LabelControl* edit = new LabelControl("Edit"); toolbar->setControl(col++, 0, edit ); edit->addEventHandler(new EditModeHandler( graph )); unsigned int row = 0; Grid *styleBar = createToolBar( ); styleBar->setPosition(0, 50); canvas->addControl( styleBar ); //Make a list of styles styleBar->setControl(0, row++, new LabelControl("Styles") ); unsigned int numStyles = 8; for (unsigned int i = 0; i < numStyles; ++i) { float w = 50; osg::Vec4 color = randomColor(); float widths[3] = {2, 4, 8}; unsigned int r = row++; for (unsigned int j = 0; j < 3; j++) { Control* l = new Control(); l->setBackColor( color ); l->addEventHandler(new ChangeStyleHandler(graph, buildStyleSheet( color, widths[j] ) )); l->setSize(w,5 * widths[j]); styleBar->setControl(j, r, l); } } viewer.setSceneData( s_root.get() ); viewer.setCameraManipulator( new EarthManipulator() ); if ( s_mapNode ) viewer.getCamera()->addCullCallback( new osgEarth::Util::AutoClipPlaneCullCallback(s_mapNode) ); // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); return viewer.run(); }
int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc,argv); osgViewer::Viewer viewer(arguments); s_mapNode = 0L; osg::Node* earthFile = MapNodeHelper().load(arguments, &viewer); if (earthFile) s_mapNode = MapNode::get(earthFile); if ( !s_mapNode ) { OE_WARN << "Unable to load earth file." << std::endl; return -1; } osg::Group* root = new osg::Group(); viewer.setSceneData( root ); // install the programmable manipulator. viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); // The MapNode will render the Map object in the scene graph. root->addChild( earthFile ); // Make the readout: Grid* grid = new Grid(); grid->setBackColor(osg::Vec4(0,0,0,0.5)); int r=0; grid->setControl(0,r++,new LabelControl("Double-click to sample elevation", osg::Vec4(1,1,0,1))); grid->setControl(0,r++,new LabelControl("Coords (Lat, Long):")); grid->setControl(0,r++,new LabelControl("Map vertical datum:")); grid->setControl(0,r++,new LabelControl("Height above geoid:")); grid->setControl(0,r++,new LabelControl("Height above ellipsoid:")); grid->setControl(0,r++,new LabelControl("Scene graph intersection:")); grid->setControl(0,r++,new LabelControl("EGM96 elevation:")); grid->setControl(0,r++,new LabelControl("Query resolution:")); grid->setControl(0, r++, new ButtonControl("Click to remove all elevation data", new ClickToRemoveElevation())); r = 1; s_posLabel = grid->setControl(1,r++,new LabelControl("")); s_vdaLabel = grid->setControl(1,r++,new LabelControl("")); s_mslLabel = grid->setControl(1,r++,new LabelControl("")); s_haeLabel = grid->setControl(1,r++,new LabelControl("")); s_mapLabel = grid->setControl(1,r++,new LabelControl("")); s_egm96Label = grid->setControl(1,r++,new LabelControl("")); s_resLabel = grid->setControl(1,r++,new LabelControl("")); s_marker = new PlaceNode(); s_marker->setMapNode( s_mapNode ); s_marker->setIconImage(osgDB::readImageFile("../data/placemark32.png")); s_marker->setDynamic(true); root->addChild( s_marker ); const SpatialReference* mapSRS = s_mapNode->getMapSRS(); s_vdaLabel->setText( mapSRS->getVerticalDatum() ? mapSRS->getVerticalDatum()->getName() : Stringify() << "geodetic (" << mapSRS->getEllipsoid()->getName() << ")" ); ControlCanvas* canvas = ControlCanvas::get(&viewer); canvas->addControl( grid ); // An event handler that will respond to mouse clicks: viewer.addEventHandler( new QueryElevationHandler() ); // add some stock OSG handlers: viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); 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); osgViewer::Viewer viewer(arguments); // parse command line: bool isUTM = arguments.read("--utm"); bool isMGRS = arguments.read("--mgrs"); bool isGeodetic = arguments.read("--geodetic"); bool isGARS = arguments.read("--gars"); // load the .earth file from the command line. MapNode* mapNode = MapNode::load( arguments ); if ( !mapNode ) return usage( "Failed to load a map from the .earth file" ); // install our manipulator: viewer.setCameraManipulator( new EarthManipulator() ); // root scene graph: osg::Group* root = new osg::Group(); root->addChild( mapNode ); Formatter* formatter = 0L; if ( isUTM ) { UTMGraticule* gr = new UTMGraticule(); mapNode->getMap()->addLayer(gr); formatter = new MGRSFormatter(); } else if ( isMGRS ) { MGRSGraticule* gr = new MGRSGraticule(); mapNode->getMap()->addLayer(gr); formatter = new MGRSFormatter(); } else if ( isGARS ) { GARSGraticule* gr = new GARSGraticule(); mapNode->getMap()->addLayer(gr); formatter = new LatLongFormatter(); } else // if ( isGeodetic ) { GeodeticGraticule* gr = new GeodeticGraticule(); mapNode->getMap()->addLayer(gr); formatter = new LatLongFormatter(); } // mouse coordinate readout: ControlCanvas* canvas = new ControlCanvas(); root->addChild( canvas ); VBox* vbox = new VBox(); canvas->addControl( vbox ); LabelControl* readout = new LabelControl(); vbox->addControl( readout ); MouseCoordsTool* tool = new MouseCoordsTool( mapNode ); tool->addCallback( new MouseCoordsLabelCallback(readout, formatter) ); viewer.addEventHandler( tool ); // finalize setup and run. viewer.setSceneData( root ); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgViewer::ThreadingHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); return viewer.run(); }