ReadResult readNode(const std::string& uri, const osgDB::Options* dboptions) const { std::string ext = osgDB::getFileExtension(uri); if ( acceptsExtension(ext) ) { // parse the tile key and engine ID: std::string requestdef = osgDB::getNameLessExtension(uri); unsigned requestUID, engineUID; sscanf(requestdef.c_str(), "%u.%u", &requestUID, &engineUID); // find the appropriate engine: osg::ref_ptr<RexTerrainEngineNode> engineNode; RexTerrainEngineNode::getEngineByUID( (UID)engineUID, engineNode ); if ( engineNode.valid() ) { PagerLoader* loader = dynamic_cast<PagerLoader*>(engineNode->getLoader()); if ( loader ) { Loader::Request* req = loader->invokeAndRelease( requestUID ); return new RequestResultNode(req); } } return ReadResult::FILE_NOT_FOUND; } else { return ReadResult::FILE_NOT_HANDLED; } };
void RexTerrainEngineNode::postInitialize( const Map* map, const TerrainOptions& options ) { TerrainEngineNode::postInitialize( map, options ); // Initialize the map frames. We need one for the update thread and one for the // cull thread. Someday we can detect whether these are actually the same thread // (depends on the viewer's threading mode). _update_mapf = new MapFrame( map, Map::ENTIRE_MODEL ); // merge in the custom options: _terrainOptions.merge( options ); // morphing imagery LODs requires we bind parent textures to their own unit. if ( _terrainOptions.morphImagery() == true ) { _requireParentTextures = true; } // if the envvar for tile expiration is set, overide the options setting const char* val = ::getenv("OSGEARTH_EXPIRATION_THRESHOLD"); if ( val ) { _terrainOptions.expirationThreshold() = as<unsigned>(val, _terrainOptions.expirationThreshold().get()); OE_INFO << LC << "Expiration threshold set by env var = " << _terrainOptions.expirationThreshold().get() << "\n"; } // if the envvar for hires prioritization is set, override the options setting const char* hiresFirst = ::getenv("OSGEARTH_HIGH_RES_FIRST"); if ( hiresFirst ) { _terrainOptions.highResolutionFirst() = true; } // check for normal map generation (required for lighting). if ( _terrainOptions.normalMaps() == true ) { this->_requireNormalTextures = true; } // A shared registry for tile nodes in the scene graph. Enable revision tracking // if requested in the options. Revision tracking lets the registry notify all // live tiles of the current map revision so they can inrementally update // themselves if necessary. _liveTiles = new TileNodeRegistry("live"); _liveTiles->setMapRevision( _update_mapf->getRevision() ); if ( _terrainOptions.quickReleaseGLObjects() == true ) { _deadTiles = new TileNodeRegistry("dead"); _quickReleaseInstalled = false; ADJUST_UPDATE_TRAV_COUNT( this, +1 ); } // A shared geometry pool. if ( ::getenv("OSGEARTH_REX_NO_POOL") == 0L ) { _geometryPool = new GeometryPool( _terrainOptions ); } // Make a tile loader PagerLoader* loader = new PagerLoader( this ); loader->setMergesPerFrame( _terrainOptions.mergesPerFrame().get() ); _loader = loader; //_loader = new SimpleLoader(); this->addChild( _loader.get() ); // handle an already-established map profile: MapInfo mapInfo( map ); if ( _update_mapf->getProfile() ) { // NOTE: this will initialize the map with the startup layers onMapInfoEstablished( mapInfo ); } // install a layer callback for processing further map actions: map->addMapCallback( new RexTerrainEngineNodeMapCallbackProxy(this) ); // Prime with existing layers: _batchUpdateInProgress = true; ElevationLayerVector elevationLayers; map->getElevationLayers( elevationLayers ); for( ElevationLayerVector::const_iterator i = elevationLayers.begin(); i != elevationLayers.end(); ++i ) addElevationLayer( i->get() ); ImageLayerVector imageLayers; map->getImageLayers( imageLayers ); for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i ) addImageLayer( i->get() ); _batchUpdateInProgress = false; // set up the initial shaders updateState(); // register this instance to the osgDB plugin can find it. registerEngine( this ); // now that we have a map, set up to recompute the bounds dirtyBound(); }
void RexTerrainEngineNode::postInitialize( const Map* map, const TerrainOptions& options ) { // Force the mercator fast path off, since REX does not support it yet. TerrainOptions myOptions = options; myOptions.enableMercatorFastPath() = false; TerrainEngineNode::postInitialize( map, myOptions ); // Initialize the map frames. We need one for the update thread and one for the // cull thread. Someday we can detect whether these are actually the same thread // (depends on the viewer's threading mode). _update_mapf = new MapFrame( map, Map::ENTIRE_MODEL ); // A callback for overriding bounding boxes for tiles _modifyBBoxCallback = new ModifyBoundingBoxCallback(*_update_mapf); // merge in the custom options: _terrainOptions.merge( myOptions ); // morphing imagery LODs requires we bind parent textures to their own unit. if ( _terrainOptions.morphImagery() == true ) { _requireParentTextures = true; } // Terrain morphing doesn't work in projected maps: if (map->getSRS()->isProjected()) { _terrainOptions.morphTerrain() = false; } // if the envvar for tile expiration is set, overide the options setting const char* val = ::getenv("OSGEARTH_EXPIRATION_THRESHOLD"); if ( val ) { _terrainOptions.expirationThreshold() = as<unsigned>(val, _terrainOptions.expirationThreshold().get()); OE_INFO << LC << "Expiration threshold set by env var = " << _terrainOptions.expirationThreshold().get() << "\n"; } // if the envvar for hires prioritization is set, override the options setting const char* hiresFirst = ::getenv("OSGEARTH_HIGH_RES_FIRST"); if ( hiresFirst ) { _terrainOptions.highResolutionFirst() = true; } // check for normal map generation (required for lighting). if ( _terrainOptions.normalMaps() == true ) { this->_requireNormalTextures = true; } // A shared registry for tile nodes in the scene graph. Enable revision tracking // if requested in the options. Revision tracking lets the registry notify all // live tiles of the current map revision so they can inrementally update // themselves if necessary. _liveTiles = new TileNodeRegistry("live"); _liveTiles->setMapRevision( _update_mapf->getRevision() ); // A resource releaser that will call releaseGLObjects() on expired objects. _releaser = new ResourceReleaser(); this->addChild(_releaser.get()); // A shared geometry pool. _geometryPool = new GeometryPool( _terrainOptions ); _geometryPool->setReleaser( _releaser.get()); this->addChild( _geometryPool.get() ); // Make a tile loader PagerLoader* loader = new PagerLoader( this ); loader->setNumLODs(_terrainOptions.maxLOD().getOrUse(DEFAULT_MAX_LOD)); loader->setMergesPerFrame( _terrainOptions.mergesPerFrame().get() ); for (std::vector<RexTerrainEngineOptions::LODOptions>::const_iterator i = _terrainOptions.lods().begin(); i != _terrainOptions.lods().end(); ++i) { if (i->_lod.isSet()) { loader->setLODPriorityScale(i->_lod.get(), i->_priorityScale.getOrUse(1.0f)); loader->setLODPriorityOffset(i->_lod.get(), i->_priorityOffset.getOrUse(0.0f)); } } _loader = loader; this->addChild( _loader.get() ); // Make a tile unloader _unloader = new UnloaderGroup( _liveTiles.get() ); _unloader->setThreshold( _terrainOptions.expirationThreshold().get() ); _unloader->setReleaser(_releaser.get()); this->addChild( _unloader.get() ); // handle an already-established map profile: MapInfo mapInfo( map ); if ( _update_mapf->getProfile() ) { // NOTE: this will initialize the map with the startup layers onMapInfoEstablished( mapInfo ); } // install a layer callback for processing further map actions: map->addMapCallback( new RexTerrainEngineNodeMapCallbackProxy(this) ); // Prime with existing layers: _batchUpdateInProgress = true; ElevationLayerVector elevationLayers; map->getLayers( elevationLayers ); for( ElevationLayerVector::const_iterator i = elevationLayers.begin(); i != elevationLayers.end(); ++i ) addElevationLayer( i->get() ); ImageLayerVector imageLayers; map->getLayers( imageLayers ); for( ImageLayerVector::iterator i = imageLayers.begin(); i != imageLayers.end(); ++i ) addTileLayer( i->get() ); _batchUpdateInProgress = false; // set up the initial shaders updateState(); // register this instance to the osgDB plugin can find it. registerEngine( this ); // now that we have a map, set up to recompute the bounds dirtyBound(); }