ModelLayer* Map::getModelLayerByUID( UID layerUID ) const { Threading::ScopedReadLock( const_cast<Map*>(this)->_mapDataMutex ); for( ModelLayerVector::const_iterator i = _modelLayers.begin(); i != _modelLayers.end(); ++i ) if ( i->get()->getUID() == layerUID ) return i->get(); return 0L; }
ModelLayer* Map::getModelLayerByName( const std::string& name ) const { Threading::ScopedReadLock( const_cast<Map*>(this)->_mapDataMutex ); for( ModelLayerVector::const_iterator i = _modelLayers.begin(); i != _modelLayers.end(); ++i ) if ( i->get()->getName() == name ) return i->get(); return 0L; }
void ElevationQuery::gatherPatchLayers() { // cache a vector of terrain patch models. _patchLayers.clear(); for(ModelLayerVector::const_iterator i = _mapf.modelLayers().begin(); i != _mapf.modelLayers().end(); ++i) { if ( i->get()->isTerrainPatch() ) _patchLayers.push_back( i->get() ); } }
Config EarthFileSerializer2::serialize( MapNode* input ) const { Config mapConf("map"); mapConf.set("version", "2"); if ( !input || !input->getMap() ) return mapConf; Map* map = input->getMap(); MapFrame mapf( map, Map::ENTIRE_MODEL ); // the map and node options: Config optionsConf = map->getInitialMapOptions().getConfig(); optionsConf.merge( input->getMapNodeOptions().getConfig() ); mapConf.add( "options", optionsConf ); // the layers for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); //Config layerConf = layer->getInitialOptions().getConfig(); Config layerConf = layer->getImageLayerOptions().getConfig(); layerConf.set("name", layer->getName()); layerConf.set("driver", layer->getInitialOptions().driver()->getDriver()); mapConf.add( "image", layerConf ); } for( ElevationLayerVector::const_iterator i = mapf.elevationLayers().begin(); i != mapf.elevationLayers().end(); ++i ) { ElevationLayer* layer = i->get(); //Config layerConf = layer->getInitialOptions().getConfig(); Config layerConf = layer->getElevationLayerOptions().getConfig(); layerConf.set("name", layer->getName()); layerConf.set("driver", layer->getInitialOptions().driver()->getDriver()); mapConf.add( "elevation", layerConf ); } for( ModelLayerVector::const_iterator i = mapf.modelLayers().begin(); i != mapf.modelLayers().end(); ++i ) { ModelLayer* layer = i->get(); Config layerConf = layer->getModelLayerOptions().getConfig(); layerConf.set("name", layer->getName()); layerConf.set("driver", layer->getModelLayerOptions().driver()->getDriver()); mapConf.add( "model", layerConf ); } Config ext = input->externalConfig(); if ( !ext.empty() ) { ext.key() = "external"; mapConf.add( ext ); } return mapConf; }
Revision Map::getModelLayers( ModelLayerVector& out_list ) const { out_list.reserve( _modelLayers.size() ); Threading::ScopedReadLock lock( const_cast<Map*>(this)->_mapDataMutex ); for( ModelLayerVector::const_iterator i = _modelLayers.begin(); i != _modelLayers.end(); ++i ) out_list.push_back( i->get() ); return _dataModelRevision; }
void MapNode::init() { // Take a reference to this object so that it doesn't get inadvertently // deleting during startup. It is possible that during startup, a driver // will load that will take a reference to the MapNode (like in a // ModelSource node operation) and we don't want that deleting the MapNode // out from under us. // This is paired by an unref_nodelete() at the end of this method. this->ref(); // Protect the MapNode from the Optimizer setDataVariance(osg::Object::DYNAMIC); // initialize 0Ls _terrainEngine = 0L; _terrainEngineContainer = 0L; _overlayDecorator = 0L; setName( "osgEarth::MapNode" ); // Since we have global uniforms in the stateset, mark it dynamic so it is immune to // multi-threaded overlap // TODO: do we need this anymore? there are no more global uniforms in here.. gw getOrCreateStateSet()->setDataVariance(osg::Object::DYNAMIC); _modelLayerCallback = new MapModelLayerCallback(this); _maskLayerNode = 0L; _lastNumBlacklistedFilenames = 0; // Set the global proxy settings // TODO: this should probably happen elsewhere, like in the registry? if ( _mapNodeOptions.proxySettings().isSet() ) { HTTPClient::setProxySettings( _mapNodeOptions.proxySettings().get() ); } // establish global driver options. These are OSG reader-writer options that // will make their way to any read* calls down the pipe const osgDB::Options* global_options = _map->getGlobalOptions(); osg::ref_ptr<osgDB::Options> local_options = global_options ? Registry::instance()->cloneOrCreateOptions( global_options ) : NULL; if ( local_options.valid() ) { OE_INFO << LC << "Options string = " << (local_options.valid()? local_options->getOptionString() : "<empty>") << std::endl; } // TODO: not sure why we call this here _map->setGlobalOptions( local_options.get() ); // load and attach the terrain engine, but don't initialize it until we need it const TerrainOptions& terrainOptions = _mapNodeOptions.getTerrainOptions(); _terrainEngine = TerrainEngineNodeFactory::create( _map.get(), terrainOptions ); _terrainEngineInitialized = false; // the engine needs a container so we can set lighting state on the container and // not on the terrain engine itself. Setting the dynamic variance will prevent // an optimizer from collapsing the empty group node. _terrainEngineContainer = new osg::Group(); _terrainEngineContainer->setDataVariance( osg::Object::DYNAMIC ); this->addChild( _terrainEngineContainer ); // initialize terrain-level lighting: if ( terrainOptions.enableLighting().isSet() ) { _terrainEngineContainer->getOrCreateStateSet()->setMode( GL_LIGHTING, terrainOptions.enableLighting().value() ? 1 : 0 ); } if ( _terrainEngine ) { // inform the terrain engine of the map information now so that it can properly // initialize it's CoordinateSystemNode. This is necessary in order to support // manipulators and to set up the texture compositor prior to frame-loop // initialization. _terrainEngine->preInitialize( _map.get(), terrainOptions ); _terrainEngineContainer->addChild( _terrainEngine ); } else { OE_WARN << "FAILED to create a terrain engine for this map" << std::endl; } // make a group for the model layers. // NOTE: for now, we are going to nullify any shader programs that occur above the model // group, since it does not YET support shader composition. Programs defined INSIDE a // model layer will still work OK though. _models = new osg::Group(); _models->setName( "osgEarth::MapNode.modelsGroup" ); addChild( _models.get() ); // make a group for overlay model layers: _overlayModels = new ObserverGroup(); //osg::Group(); _overlayModels->setName( "osgEarth::MapNode.overlayModelsGroup" ); // a decorator for overlay models: _overlayDecorator = new OverlayDecorator(); _overlayDecorator->setOverlayGraphTraversalMask( terrainOptions.secondaryTraversalMask().value() ); if ( _mapNodeOptions.overlayBlending().isSet() ) _overlayDecorator->setOverlayBlending( *_mapNodeOptions.overlayBlending() ); if ( _mapNodeOptions.overlayTextureSize().isSet() ) _overlayDecorator->setTextureSize( *_mapNodeOptions.overlayTextureSize() ); if ( _mapNodeOptions.overlayMipMapping().isSet() ) _overlayDecorator->setMipMapping( *_mapNodeOptions.overlayMipMapping() ); addTerrainDecorator( _overlayDecorator ); // install any pre-existing model layers: ModelLayerVector modelLayers; _map->getModelLayers( modelLayers ); int modelLayerIndex = 0; for( ModelLayerVector::const_iterator k = modelLayers.begin(); k != modelLayers.end(); k++, modelLayerIndex++ ) { onModelLayerAdded( k->get(), modelLayerIndex ); } _mapCallback = new MapNodeMapCallbackProxy(this); // install a layer callback for processing further map actions: _map->addMapCallback( _mapCallback.get() ); osg::StateSet* ss = getOrCreateStateSet(); if ( _mapNodeOptions.enableLighting().isSet() ) { ss->setMode( GL_LIGHTING, _mapNodeOptions.enableLighting().value() ? 1 : 0 ); } dirtyBound(); // Install top-level shader programs: if ( Registry::capabilities().supportsGLSL() ) { VirtualProgram* vp = new VirtualProgram(); vp->setName( "MapNode" ); vp->installDefaultColoringAndLightingShaders(); ss->setAttributeAndModes( vp, osg::StateAttribute::ON ); } // register for event traversals so we can deal with blacklisted filenames ADJUST_EVENT_TRAV_COUNT( this, 1 ); // remove the temporary reference. this->unref_nodelete(); }
Config EarthFileSerializer2::serialize(const MapNode* input, const std::string& referrer) const { Config mapConf("map"); mapConf.set("version", "2"); if ( !input || !input->getMap() ) return mapConf; const Map* map = input->getMap(); MapFrame mapf( map, Map::ENTIRE_MODEL ); // the map and node options: Config optionsConf = map->getInitialMapOptions().getConfig(); optionsConf.merge( input->getMapNodeOptions().getConfig() ); mapConf.add( "options", optionsConf ); // the layers for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); //Config layerConf = layer->getInitialOptions().getConfig(); Config layerConf = layer->getImageLayerOptions().getConfig(); layerConf.set("name", layer->getName()); layerConf.set("driver", layer->getInitialOptions().driver()->getDriver()); mapConf.add( "image", layerConf ); } for( ElevationLayerVector::const_iterator i = mapf.elevationLayers().begin(); i != mapf.elevationLayers().end(); ++i ) { ElevationLayer* layer = i->get(); //Config layerConf = layer->getInitialOptions().getConfig(); Config layerConf = layer->getElevationLayerOptions().getConfig(); layerConf.set("name", layer->getName()); layerConf.set("driver", layer->getInitialOptions().driver()->getDriver()); mapConf.add( "elevation", layerConf ); } for( ModelLayerVector::const_iterator i = mapf.modelLayers().begin(); i != mapf.modelLayers().end(); ++i ) { ModelLayer* layer = i->get(); Config layerConf = layer->getModelLayerOptions().getConfig(); layerConf.set("name", layer->getName()); layerConf.set("driver", layer->getModelLayerOptions().driver()->getDriver()); mapConf.add( "model", layerConf ); } Config ext = input->externalConfig(); if ( !ext.empty() ) { ext.key() = "extensions"; mapConf.add( ext ); } #if 1 // removed until it can be debugged. // Re-write pathnames in the Config so they are relative to the new referrer. if ( _rewritePaths && !referrer.empty() ) { RewritePaths rewritePaths( referrer ); rewritePaths.setRewriteAbsolutePaths( _rewriteAbsolutePaths ); rewritePaths.apply( mapConf ); } #endif return mapConf; }
void MapNode::init() { // Take a reference to this object so that it doesn't get inadvertently // deleting during startup. It is possible that during startup, a driver // will load that will take a reference to the MapNode (like in a // ModelSource node operation) and we don't want that deleting the MapNode // out from under us. // This is paired by an unref_nodelete() at the end of this method. this->ref(); // Protect the MapNode from the Optimizer setDataVariance(osg::Object::DYNAMIC); // Protect the MapNode from the ShaderGenerator ShaderGenerator::setIgnoreHint(this, true); // initialize 0Ls _terrainEngine = 0L; _terrainEngineContainer = 0L; _overlayDecorator = 0L; setName( "osgEarth::MapNode" ); _maskLayerNode = 0L; _lastNumBlacklistedFilenames = 0; // Set the global proxy settings // TODO: this should probably happen elsewhere, like in the registry? if ( _mapNodeOptions.proxySettings().isSet() ) { HTTPClient::setProxySettings( _mapNodeOptions.proxySettings().get() ); } // establish global driver options. These are OSG reader-writer options that // will make their way to any read* calls down the pipe const osgDB::Options* global_options = _map->getGlobalOptions(); osg::ref_ptr<osgDB::Options> local_options = global_options ? Registry::instance()->cloneOrCreateOptions( global_options ) : NULL; if ( local_options.valid() ) { OE_INFO << LC << "Options string = " << (local_options.valid()? local_options->getOptionString() : "<empty>") << std::endl; } // TODO: not sure why we call this here _map->setGlobalOptions( local_options.get() ); // load and attach the terrain engine, but don't initialize it until we need it const TerrainOptions& terrainOptions = _mapNodeOptions.getTerrainOptions(); _terrainEngine = TerrainEngineNodeFactory::create( _map.get(), terrainOptions ); _terrainEngineInitialized = false; // the engine needs a container so we can set lighting state on the container and // not on the terrain engine itself. Setting the dynamic variance will prevent // an optimizer from collapsing the empty group node. _terrainEngineContainer = new osg::Group(); _terrainEngineContainer->setDataVariance( osg::Object::DYNAMIC ); this->addChild( _terrainEngineContainer ); // initialize terrain-level lighting: if ( terrainOptions.enableLighting().isSet() ) { _terrainEngineContainer->getOrCreateStateSet()->addUniform( Registry::shaderFactory()->createUniformForGLMode(GL_LIGHTING, *terrainOptions.enableLighting()) ); _terrainEngineContainer->getOrCreateStateSet()->setMode( GL_LIGHTING, terrainOptions.enableLighting().value() ? 1 : 0 ); } if ( _terrainEngine ) { // inform the terrain engine of the map information now so that it can properly // initialize it's CoordinateSystemNode. This is necessary in order to support // manipulators and to set up the texture compositor prior to frame-loop // initialization. _terrainEngine->preInitialize( _map.get(), terrainOptions ); _terrainEngineContainer->addChild( _terrainEngine ); } else { OE_WARN << "FAILED to create a terrain engine for this map" << std::endl; } // make a group for the model layers. // NOTE: for now, we are going to nullify any shader programs that occur above the model // group, since it does not YET support shader composition. Programs defined INSIDE a // model layer will still work OK though. _models = new osg::Group(); _models->setName( "osgEarth::MapNode.modelsGroup" ); _models->getOrCreateStateSet()->setRenderBinDetails(2, "RenderBin"); addChild( _models.get() ); // a decorator for overlay models: _overlayDecorator = new OverlayDecorator(); // install the Draping technique for overlays: { DrapingTechnique* draping = new DrapingTechnique(); const char* envOverlayTextureSize = ::getenv("OSGEARTH_OVERLAY_TEXTURE_SIZE"); if ( _mapNodeOptions.overlayBlending().isSet() ) draping->setOverlayBlending( *_mapNodeOptions.overlayBlending() ); if ( envOverlayTextureSize ) draping->setTextureSize( as<int>(envOverlayTextureSize, 1024) ); else if ( _mapNodeOptions.overlayTextureSize().isSet() ) draping->setTextureSize( *_mapNodeOptions.overlayTextureSize() ); if ( _mapNodeOptions.overlayMipMapping().isSet() ) draping->setMipMapping( *_mapNodeOptions.overlayMipMapping() ); if ( _mapNodeOptions.overlayAttachStencil().isSet() ) draping->setAttachStencil( *_mapNodeOptions.overlayAttachStencil() ); if ( _mapNodeOptions.overlayResolutionRatio().isSet() ) draping->setResolutionRatio( *_mapNodeOptions.overlayResolutionRatio() ); _overlayDecorator->addTechnique( draping ); } // install the Clamping technique for overlays: { _overlayDecorator->addTechnique( new ClampingTechnique() ); } addTerrainDecorator( _overlayDecorator ); // install any pre-existing model layers: ModelLayerVector modelLayers; _map->getModelLayers( modelLayers ); int modelLayerIndex = 0; for( ModelLayerVector::const_iterator k = modelLayers.begin(); k != modelLayers.end(); k++, modelLayerIndex++ ) { onModelLayerAdded( k->get(), modelLayerIndex ); } _mapCallback = new MapNodeMapCallbackProxy(this); // install a layer callback for processing further map actions: _map->addMapCallback( _mapCallback.get() ); osg::StateSet* stateset = getOrCreateStateSet(); if ( _mapNodeOptions.enableLighting().isSet() ) { stateset->addUniform(Registry::shaderFactory()->createUniformForGLMode( GL_LIGHTING, _mapNodeOptions.enableLighting().value() ? 1 : 0)); stateset->setMode( GL_LIGHTING, _mapNodeOptions.enableLighting().value() ? 1 : 0); } // Add in some global uniforms stateset->addUniform( new osg::Uniform("oe_isGeocentric", _map->isGeocentric()) ); if ( _map->isGeocentric() ) { OE_INFO << LC << "Adding ellipsoid uniforms.\n"; // for a geocentric map, use an ellipsoid unit-frame transform and its inverse: osg::Vec3d ellipFrameInverse( _map->getSRS()->getEllipsoid()->getRadiusEquator(), _map->getSRS()->getEllipsoid()->getRadiusEquator(), _map->getSRS()->getEllipsoid()->getRadiusPolar()); stateset->addUniform( new osg::Uniform("oe_ellipsoidFrameInverse", osg::Vec3f(ellipFrameInverse)) ); osg::Vec3d ellipFrame = osg::componentDivide(osg::Vec3d(1.0,1.0,1.0), ellipFrameInverse); stateset->addUniform( new osg::Uniform("oe_ellipsoidFrame", osg::Vec3f(ellipFrame)) ); } // install the default rendermode uniform: stateset->addUniform( new osg::Uniform("oe_isPickCamera", false) ); dirtyBound(); // register for event traversals so we can deal with blacklisted filenames ADJUST_EVENT_TRAV_COUNT( this, 1 ); // remove the temporary reference. this->unref_nodelete(); }
void MapNode::init() { // Protect the MapNode from the Optimizer setDataVariance(osg::Object::DYNAMIC); setName( "osgEarth::MapNode" ); // Since we have global uniforms in the stateset, mark it dynamic so it is immune to // multi-threaded overlap // TODO: do we need this anymore? there are no more global uniforms in here.. gw getOrCreateStateSet()->setDataVariance(osg::Object::DYNAMIC); _modelLayerCallback = new MapModelLayerCallback(this); _maskLayerNode = 0L; _lastNumBlacklistedFilenames = 0; // Set the global proxy settings // TODO: this should probably happen elsewhere, like in the registry? if ( _mapNodeOptions.proxySettings().isSet() ) { HTTPClient::setProxySettings( _mapNodeOptions.proxySettings().get() ); } // establish global driver options. These are OSG reader-writer options that // will make their way to any read* calls down the pipe const osgDB::ReaderWriter::Options* global_options = _map->getGlobalOptions(); osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = global_options ? new osgDB::ReaderWriter::Options( *global_options ) : NULL; if ( local_options.valid() ) { OE_INFO << LC << "Options string = " << (local_options.valid()? local_options->getOptionString() : "<empty>") << std::endl; } // TODO: not sure why we call this here _map->setGlobalOptions( local_options.get() ); // overlays: _pendingOverlayAutoSetTextureUnit = true; // load and attach the terrain engine, but don't initialize it until we need it const TerrainOptions& terrainOptions = _mapNodeOptions.getTerrainOptions(); _terrainEngine = TerrainEngineNodeFactory::create( _map.get(), terrainOptions ); _terrainEngineInitialized = false; // the engine needs a container so we can set lighting state on the container and // not on the terrain engine itself. Setting the dynamic variance will prevent // an optimizer from collapsing the empty group node. _terrainEngineContainer = new osg::Group(); _terrainEngineContainer->setDataVariance( osg::Object::DYNAMIC ); this->addChild( _terrainEngineContainer.get() ); // initialize terrain-level lighting: if ( terrainOptions.enableLighting().isSet() ) { _terrainEngineContainer->getOrCreateStateSet()->setMode( GL_LIGHTING, terrainOptions.enableLighting().value() ? osg::StateAttribute::ON | osg::StateAttribute::PROTECTED : osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); } if ( _terrainEngine.valid() ) { // inform the terrain engine of the map information now so that it can properly // initialize it's CoordinateSystemNode. This is necessary in order to support // manipulators and to set up the texture compositor prior to frame-loop // initialization. _terrainEngine->preInitialize( _map.get(), terrainOptions ); _terrainEngineContainer->addChild( _terrainEngine.get() ); } else OE_WARN << "FAILED to create a terrain engine for this map" << std::endl; // make a group for the model layers: _models = new osg::Group(); _models->setName( "osgEarth::MapNode.modelsGroup" ); addChild( _models.get() ); // make a group for overlay model layers: _overlayModels = new osg::Group(); _overlayModels->setName( "osgEarth::MapNode.overlayModelsGroup" ); // a decorator for overlay models: _overlayDecorator = new OverlayDecorator(); if ( _mapNodeOptions.overlayVertexWarping().isSet() ) _overlayDecorator->setVertexWarping( *_mapNodeOptions.overlayVertexWarping() ); if ( _mapNodeOptions.overlayBlending().isSet() ) _overlayDecorator->setOverlayBlending( *_mapNodeOptions.overlayBlending() ); if ( _mapNodeOptions.overlayTextureSize().isSet() ) _overlayDecorator->setTextureSize( *_mapNodeOptions.overlayTextureSize() ); if ( _mapNodeOptions.overlayMipMapping().isSet() ) _overlayDecorator->setMipMapping( *_mapNodeOptions.overlayMipMapping() ); addTerrainDecorator( _overlayDecorator.get() ); // install any pre-existing model layers: ModelLayerVector modelLayers; _map->getModelLayers( modelLayers ); int modelLayerIndex = 0; for( ModelLayerVector::const_iterator k = modelLayers.begin(); k != modelLayers.end(); k++, modelLayerIndex++ ) { onModelLayerAdded( k->get(), modelLayerIndex ); } _mapCallback = new MapNodeMapCallbackProxy(this); // install a layer callback for processing further map actions: _map->addMapCallback( _mapCallback.get() ); osg::StateSet* ss = getOrCreateStateSet(); //ss->setAttributeAndModes( new osg::CullFace() ); //, osg::StateAttribute::ON); //ss->setAttributeAndModes( new osg::PolygonOffset( -1, -1 ) ); if ( _mapNodeOptions.enableLighting().isSet() ) { ss->setMode( GL_LIGHTING, _mapNodeOptions.enableLighting().value() ? osg::StateAttribute::ON | osg::StateAttribute::PROTECTED : osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); } dirtyBound(); // register for event traversals so we can deal with blacklisted filenames ADJUST_EVENT_TRAV_COUNT( this, 1 ); }