void TileModelFactory::createTileModel(const TileKey& key, const MapFrame& frame, bool accumulate, osg::ref_ptr<TileModel>& out_model, ProgressCallback* progress) { osg::ref_ptr<TileModel> model = new TileModel( frame.getRevision(), frame.getMapInfo() ); model->_useParentData = _terrainReqs->parentTexturesRequired(); model->_tileKey = key; model->_tileLocator = GeoLocator::createForKey(key, frame.getMapInfo()); OE_START_TIMER(fetch_imagery); // Fetch the image data and make color layers. unsigned index = 0; unsigned order = 0; for( ImageLayerVector::const_iterator i = frame.imageLayers().begin(); i != frame.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); if ( layer->getEnabled() && layer->isKeyInRange(key) ) { BuildColorData build; build.init( key, layer, order, frame.getMapInfo(), _terrainOptions, _liveTiles.get(), model.get() ); bool addedToModel = build.execute(progress); if ( addedToModel ) { // only bump the order if we added something to the data model. order++; } } } if (progress) progress->stats()["fetch_imagery_time"] += OE_STOP_TIMER(fetch_imagery); // make an elevation layer. OE_START_TIMER(fetch_elevation); buildElevation(key, frame, accumulate, _terrainReqs->elevationTexturesRequired(), model.get(), progress); if (progress) progress->stats()["fetch_elevation_time"] += OE_STOP_TIMER(fetch_elevation); // make a normal map layer (if necessary) if ( _terrainReqs->normalTexturesRequired() ) { OE_START_TIMER(fetch_normalmap); buildNormalMap(key, frame, accumulate, model.get(), progress); if (progress) progress->stats()["fetch_normalmap_time"] += OE_STOP_TIMER(fetch_normalmap); } // If nothing was added, not even a fallback heightfield, something went // horribly wrong. Leave without a tile model. Chances are that a parent tile // not not found in the live-tile registry. if ( model->_colorData.size() == 0 && !model->_elevationData.getHeightField() ) { return; } // OK we are making a tile, so if there's no heightfield yet, make an empty one (and mark it // as fallback data of course) if ( !model->_elevationData.getHeightField() ) { osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 15, 15 ); model->_elevationData = TileModel::ElevationData( hf, GeoLocator::createForKey(key, frame.getMapInfo()), true ); } // look up the parent model and cache it. osg::ref_ptr<TileNode> parentTile; if ( _liveTiles->get(key.createParentKey(), parentTile) ) { model->_parentModel = parentTile->getTileModel(); } out_model = model.release(); }
void TileModelFactory::createTileModel(const TileKey& key, osg::ref_ptr<TileModel>& out_model, bool& out_hasRealData, bool& out_hasLodBlendedLayers ) { MapFrame mapf( _map, Map::MASKED_TERRAIN_LAYERS ); const MapInfo& mapInfo = mapf.getMapInfo(); osg::ref_ptr<TileModel> model = new TileModel(); model->_tileKey = key; model->_tileLocator = GeoLocator::createForKey(key, mapInfo); // init this to false, then search for real data. "Real data" is data corresponding // directly to the key, as opposed to fallback data, which is derived from a lower // LOD key. out_hasRealData = false; out_hasLodBlendedLayers = false; // Fetch the image data and make color layers. for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); if ( layer->getEnabled() ) { BuildColorData build; build.init( key, layer, mapInfo, _terrainOptions, model.get() ); build.execute(); if ( layer->getImageLayerOptions().lodBlending() == true ) { out_hasLodBlendedLayers = true; } } } // make an elevation layer. BuildElevationData build; build.init( key, mapf, _terrainOptions, model.get(), _hfCache ); build.execute(); // Bail out now if there's no data to be had. if ( model->_colorData.size() == 0 && !model->_elevationData.getHFLayer() ) { return; } // OK we are making a tile, so if there's no heightfield yet, make an empty one. if ( !model->_elevationData.getHFLayer() ) { osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 8, 8 ); osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf ); hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) ); model->_elevationData = TileModel::ElevationData( hfLayer, true ); } // Now, if there are any color layers that did not get built, create them with an empty // image so the shaders have something to draw. osg::ref_ptr<osg::Image> emptyImage; osgTerrain::Locator* locator = model->_elevationData.getHFLayer()->getLocator(); for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); if ( layer->getEnabled() && !layer->isKeyValid(key) ) { if ( !emptyImage.valid() ) emptyImage = ImageUtils::createEmptyImage(); model->_colorData[i->get()->getUID()] = TileModel::ColorData( layer, emptyImage.get(), locator, key.getLevelOfDetail(), key, true ); } } // Ready to create the actual tile. //AssembleTile assemble; //assemble.init( key, mapInfo, _terrainOptions, model.get(), mapf.terrainMaskLayers() ); //assemble.execute(); // if we're using LOD blending, find and add the parent's state set. if ( out_hasLodBlendedLayers && key.getLevelOfDetail() > 0 && _liveTiles.valid() ) { osg::ref_ptr<TileNode> parent; if ( _liveTiles->get( key.createParentKey(), parent ) ) { model->_parentStateSet = parent->getPublicStateSet(); } } if (!out_hasRealData) { // Check the results and see if we have any real data. for( TileModel::ColorDataByUID::const_iterator i = model->_colorData.begin(); i != model->_colorData.end(); ++i ) { if ( !i->second.isFallbackData() ) { out_hasRealData = true; break; } } } if ( !out_hasRealData && !model->_elevationData.isFallbackData() ) { out_hasRealData = true; } out_model = model.release(); //out_tile = assemble._node; }
void TileModelFactory::createTileModel(const TileKey& key, const MapFrame& frame, osg::ref_ptr<TileModel>& out_model) //, //bool& out_hasRealData) { osg::ref_ptr<TileModel> model = new TileModel( frame.getRevision(), frame.getMapInfo() ); model->_tileKey = key; model->_tileLocator = GeoLocator::createForKey(key, frame.getMapInfo()); // Fetch the image data and make color layers. unsigned order = 0; for( ImageLayerVector::const_iterator i = frame.imageLayers().begin(); i != frame.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); if ( layer->getEnabled() ) { BuildColorData build; build.init( key, layer, order, frame.getMapInfo(), _terrainOptions, model.get() ); bool addedToModel = build.execute(); if ( addedToModel ) { // only bump the order if we added something to the data model. order++; } } } // make an elevation layer. BuildElevationData build; build.init( key, frame, _terrainOptions, model.get(), _hfCache ); build.execute(); // Bail out now if there's no data to be had. if ( model->_colorData.size() == 0 && !model->_elevationData.getHeightField() ) { return; } // OK we are making a tile, so if there's no heightfield yet, make an empty one (and mark it // as fallback data of course) if ( !model->_elevationData.getHeightField() ) { osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 15, 15 ); model->_elevationData = TileModel::ElevationData( hf, GeoLocator::createForKey(key, frame.getMapInfo()), true ); } // look up the parent model and cache it. osg::ref_ptr<TileNode> parentTile; if ( _liveTiles->get(key.createParentKey(), parentTile) ) model->_parentModel = parentTile->getTileModel(); out_model = model.release(); }
void TileModelFactory::createTileModel(const TileKey& key, osg::ref_ptr<TileModel>& out_model, bool& out_hasRealData) { MapFrame mapf( _map, Map::MASKED_TERRAIN_LAYERS ); const MapInfo& mapInfo = mapf.getMapInfo(); osg::ref_ptr<TileModel> model = new TileModel(); model->_map = _map; model->_tileKey = key; model->_tileLocator = GeoLocator::createForKey(key, mapInfo); // init this to false, then search for real data. "Real data" is data corresponding // directly to the key, as opposed to fallback data, which is derived from a lower // LOD key. out_hasRealData = false; // Fetch the image data and make color layers. unsigned order = 0; for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i ) { ImageLayer* layer = i->get(); if ( layer->getEnabled() ) { BuildColorData build; build.init( key, layer, order, mapInfo, _terrainOptions, model.get() ); bool addedToModel = build.execute(); if ( addedToModel ) { // only bump the order if we added something to the data model. order++; } } } // make an elevation layer. BuildElevationData build; build.init( key, mapf, _terrainOptions, model.get(), _hfCache ); build.execute(); // Bail out now if there's no data to be had. if ( model->_colorData.size() == 0 && !model->_elevationData.getHeightField() ) { return; } // OK we are making a tile, so if there's no heightfield yet, make an empty one. if ( !model->_elevationData.getHeightField() ) { osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 8, 8 ); model->_elevationData = TileModel::ElevationData( hf, GeoLocator::createForKey(key, mapInfo), true ); } if (!out_hasRealData) { // Check the results and see if we have any real data. for( TileModel::ColorDataByUID::const_iterator i = model->_colorData.begin(); i != model->_colorData.end(); ++i ) { if ( !i->second.isFallbackData() ) { out_hasRealData = true; break; } } } if ( !out_hasRealData && !model->_elevationData.isFallbackData() ) { out_hasRealData = true; } // look up the parent model and cache it. osg::ref_ptr<TileNode> parentTile; if ( _liveTiles->get(key.createParentKey(), parentTile) ) model->_parentModel = parentTile->getTileModel(); out_model = model.release(); }