osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2010 Pelican Mapping 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 #include <osgEarth/Map> 00020 #include <osgEarth/MapNode> 00021 #include <osgEarthUtil/EarthManipulator> 00022 #include <osgEarthUtil/Controls> 00023 #include <osgViewer/Viewer> 00024 #include <osgViewer/ViewerEventHandlers> 00025 #include <osgGA/StateSetManipulator> 00026 #include <osgDB/ReadFile> 00027 00028 using namespace osgEarth; 00029 using namespace osgEarth::Util::Controls; 00030 00031 osg::Node* createControlPanel( osgViewer::View* ); 00032 void updateControlPanel(); 00033 00034 static osg::ref_ptr<Map> s_activeMap; 00035 static osg::ref_ptr<Map> s_inactiveMap; 00036 static Grid* s_layerBox; 00037 static bool s_updateRequired = true; 00038 00039 //------------------------------------------------------------------------ 00040 00041 struct MyMapListener : public MapCallback 00042 { 00043 void onMapModelChanged( const MapModelChange& change ) { 00044 s_updateRequired = true; 00045 } 00046 }; 00047 00048 //------------------------------------------------------------------------ 00049 00050 int 00051 main( int argc, char** argv ) 00052 { 00053 osg::ArgumentParser arguments( &argc,argv ); 00054 00055 // load a graph from the command line 00056 osg::Node* node = osgDB::readNodeFiles( arguments ); 00057 00058 // make sure we loaded a .earth file 00059 osgEarth::MapNode* mapNode = MapNode::findMapNode( node ); 00060 if ( !mapNode ) { 00061 OE_WARN << "No osgEarth MapNode found in the loaded file(s)." << std::endl; 00062 return -1; 00063 } 00064 00065 // the displayed Map: 00066 s_activeMap = mapNode->getMap(); 00067 s_activeMap->addMapCallback( new MyMapListener() ); 00068 00069 // a Map to hold inactive layers (layers that have been removed from the displayed Map) 00070 s_inactiveMap = new Map(); 00071 s_inactiveMap->addMapCallback( new MyMapListener() ); 00072 00073 00074 // configure the viewer. 00075 osgViewer::Viewer viewer( arguments ); 00076 00077 osg::Group* root = new osg::Group(); 00078 00079 // install the control panel 00080 root->addChild( createControlPanel( &viewer ) ); 00081 root->addChild( node ); 00082 00083 // update the control panel with the two Maps: 00084 updateControlPanel(); 00085 00086 viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); 00087 viewer.addEventHandler( new osgViewer::StatsHandler() ); 00088 00089 viewer.setSceneData( root ); 00090 00091 // install a proper manipulator 00092 viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() ); 00093 00094 00095 while( !viewer.done() ) 00096 { 00097 viewer.frame(); 00098 00099 if ( s_updateRequired ) 00100 { 00101 updateControlPanel(); 00102 s_updateRequired = false; 00103 } 00104 } 00105 } 00106 00107 //------------------------------------------------------------------------ 00108 00109 struct LayerEnabledHandler : public ControlEventHandler 00110 { 00111 LayerEnabledHandler( ImageLayer* layer ) : _layer(layer) { } 00112 void onValueChanged( Control* control, bool value ) { 00113 _layer->setEnabled( value ); 00114 } 00115 ImageLayer* _layer; 00116 }; 00117 00118 struct LayerOpacityHandler : public ControlEventHandler 00119 { 00120 LayerOpacityHandler( ImageLayer* layer ) : _layer(layer) { } 00121 void onValueChanged( Control* control, float value ) { 00122 _layer->setOpacity( value ); 00123 } 00124 ImageLayer* _layer; 00125 }; 00126 00127 struct AddLayerHandler : public ControlEventHandler 00128 { 00129 AddLayerHandler( ImageLayer* layer ) : _layer(layer) { } 00130 void onClick( Control* control, int mouseButtonMask ) { 00131 s_inactiveMap->removeImageLayer( _layer.get() ); 00132 s_activeMap->addImageLayer( _layer.get() ); 00133 } 00134 osg::ref_ptr<ImageLayer> _layer; 00135 }; 00136 00137 struct RemoveLayerHandler : public ControlEventHandler 00138 { 00139 RemoveLayerHandler( ImageLayer* layer ) : _layer(layer) { } 00140 void onClick( Control* control, int mouseButtonMask ) { 00141 s_inactiveMap->addImageLayer( _layer.get() ); 00142 s_activeMap->removeImageLayer( _layer.get() ); 00143 } 00144 osg::ref_ptr<ImageLayer> _layer; 00145 }; 00146 00147 struct MoveLayerHandler : public ControlEventHandler 00148 { 00149 MoveLayerHandler( ImageLayer* layer, int newIndex ) : _layer(layer), _newIndex(newIndex) { } 00150 void onClick( Control* control, int mouseButtonMask ) { 00151 s_activeMap->moveImageLayer( _layer, _newIndex ); 00152 } 00153 ImageLayer* _layer; 00154 int _newIndex; 00155 }; 00156 00157 //------------------------------------------------------------------------ 00158 00159 00160 osg::Node* 00161 createControlPanel( osgViewer::View* view ) 00162 { 00163 ControlCanvas* canvas = ControlCanvas::get( view ); 00164 00165 // the outer container: 00166 s_layerBox = new Grid(); 00167 s_layerBox->setBackColor(0,0,0,0.5); 00168 s_layerBox->setMargin( 10 ); 00169 s_layerBox->setPadding( 10 ); 00170 s_layerBox->setChildSpacing( 10 ); 00171 s_layerBox->setChildVertAlign( Control::ALIGN_CENTER ); 00172 s_layerBox->setAbsorbEvents( true ); 00173 s_layerBox->setVertAlign( Control::ALIGN_BOTTOM ); 00174 00175 canvas->addControl( s_layerBox ); 00176 return canvas; 00177 } 00178 00179 void 00180 createLayerItem( int gridRow, int layerIndex, int numLayers, ImageLayer* layer, bool isActive ) 00181 { 00182 // a checkbox to enable/disable the layer: 00183 CheckBoxControl* enabled = new CheckBoxControl( layer->getEnabled() ); 00184 enabled->addEventHandler( new LayerEnabledHandler(layer) ); 00185 s_layerBox->setControl( 0, gridRow, enabled ); 00186 00187 // the layer name 00188 LabelControl* name = new LabelControl( layer->getName() ); 00189 s_layerBox->setControl( 1, gridRow, name ); 00190 00191 // an opacity slider 00192 HSliderControl* opacity = new HSliderControl( 0.0f, 1.0f, layer->getOpacity() ); 00193 opacity->setWidth( 125 ); 00194 opacity->setHeight( 12 ); 00195 opacity->addEventHandler( new LayerOpacityHandler(layer) ); 00196 s_layerBox->setControl( 2, gridRow, opacity ); 00197 00198 // move buttons 00199 if ( layerIndex < numLayers-1 && isActive ) 00200 { 00201 LabelControl* upButton = new LabelControl( "UP", 14 ); 00202 upButton->setBackColor( .4,.4,.4,1 ); 00203 upButton->setActiveColor( .8,0,0,1 ); 00204 upButton->addEventHandler( new MoveLayerHandler( layer, layerIndex+1 ) ); 00205 s_layerBox->setControl( 3, gridRow, upButton ); 00206 } 00207 if ( layerIndex > 0 && isActive) 00208 { 00209 LabelControl* upButton = new LabelControl( "DOWN", 14 ); 00210 upButton->setBackColor( .4,.4,.4,1 ); 00211 upButton->setActiveColor( .8,0,0,1 ); 00212 upButton->addEventHandler( new MoveLayerHandler( layer, layerIndex-1 ) ); 00213 s_layerBox->setControl( 4, gridRow, upButton ); 00214 } 00215 00216 // add/remove button: 00217 LabelControl* addRemove = new LabelControl( isActive? "REMOVE" : "ADD", 14 ); 00218 addRemove->setHorizAlign( Control::ALIGN_CENTER ); 00219 addRemove->setBackColor( .4,.4,.4,1 ); 00220 addRemove->setActiveColor( .8,0,0,1 ); 00221 if ( isActive ) 00222 addRemove->addEventHandler( new RemoveLayerHandler(layer) ); 00223 else 00224 addRemove->addEventHandler( new AddLayerHandler(layer) ); 00225 s_layerBox->setControl( 5, gridRow, addRemove ); 00226 } 00227 00228 void 00229 updateControlPanel() 00230 { 00231 // erase all child controls and just rebuild them b/c we're lazy. 00232 s_layerBox->clearControls(); 00233 00234 int row = 0; 00235 00236 LabelControl* activeLabel = new LabelControl( "Map Layers", 20, osg::Vec4f(1,1,0,1) ); 00237 s_layerBox->setControl( 1, row++, activeLabel ); 00238 00239 // the active map layers: 00240 MapFrame mapf( s_activeMap.get(), Map::IMAGE_LAYERS ); 00241 int layerNum = mapf.imageLayers().size()-1; 00242 for( ImageLayerVector::const_reverse_iterator i = mapf.imageLayers().rbegin(); i != mapf.imageLayers().rend(); ++i ) 00243 createLayerItem( row++, layerNum--, mapf.imageLayers().size(), i->get(), true ); 00244 00245 MapFrame mapf2( s_inactiveMap.get(), Map::IMAGE_LAYERS ); 00246 if ( mapf2.imageLayers().size() > 0 ) 00247 { 00248 LabelControl* inactiveLabel = new LabelControl( "Removed:", 18, osg::Vec4f(1,1,0,1) ); 00249 s_layerBox->setControl( 1, row++, inactiveLabel ); 00250 00251 for( unsigned int i=0; i<mapf2.imageLayers().size(); ++i ) 00252 { 00253 createLayerItem( row++, -1, -1, mapf2.getImageLayerAt(i), false ); 00254 } 00255 } 00256 }