void TerrainTileModelFactory::addNormalMap(TerrainTileModel* model, const Map* map, const TileKey& key, ProgressCallback* progress) { OE_START_TIMER(fetch_normalmap); if (model->elevationModel().valid()) { const osgEarth::ElevationInterpolation& interp = map->getMapOptions().elevationInterpolation().get(); // Can only generate the normal map if the center heightfield was built: osg::ref_ptr<osg::Image> image = HeightFieldUtils::convertToNormalMap( model->heightFields(), key.getProfile()->getSRS() ); if (image.valid()) { TerrainTileImageLayerModel* layerModel = new TerrainTileImageLayerModel(); layerModel->setName( "oe_normal_map" ); // Made an image, so store this as a texture with no matrix. osg::Texture* texture = createNormalTexture( image.get() ); layerModel->setTexture( texture ); model->normalModel() = layerModel; } } if (progress) progress->stats()["fetch_normalmap_time"] += OE_STOP_TIMER(fetch_normalmap); }
void TerrainTileModelFactory::addColorLayers(TerrainTileModel* model, const Map* map, const TerrainEngineRequirements* reqs, const TileKey& key, const CreateTileModelFilter& filter, ProgressCallback* progress) { OE_START_TIMER(fetch_image_layers); int order = 0; LayerVector layers; map->getLayers(layers); for (LayerVector::const_iterator i = layers.begin(); i != layers.end(); ++i) { Layer* layer = i->get(); if (layer->getRenderType() != layer->RENDERTYPE_TERRAIN_SURFACE) continue; if (!layer->getEnabled()) continue; if (!filter.accept(layer)) continue; ImageLayer* imageLayer = dynamic_cast<ImageLayer*>(layer); if (imageLayer) { osg::Texture* tex = 0L; osg::Matrixf textureMatrix; if (imageLayer->isKeyInLegalRange(key) && imageLayer->mayHaveDataInExtent(key.getExtent())) { if (imageLayer->createTextureSupported()) { tex = imageLayer->createTexture( key, progress, textureMatrix ); } else { GeoImage geoImage = imageLayer->createImage( key, progress ); if ( geoImage.valid() ) { if ( imageLayer->isCoverage() ) tex = createCoverageTexture(geoImage.getImage(), imageLayer); else tex = createImageTexture(geoImage.getImage(), imageLayer); } } } // if this is the first LOD, and the engine requires that the first LOD // be populated, make an empty texture if we didn't get one. if (tex == 0L && _options.firstLOD() == key.getLOD() && reqs && reqs->fullDataAtFirstLodRequired()) { tex = _emptyTexture.get(); } if (tex) { tex->setName(model->getKey().str()); TerrainTileImageLayerModel* layerModel = new TerrainTileImageLayerModel(); layerModel->setImageLayer(imageLayer); layerModel->setTexture(tex); layerModel->setMatrix(new osg::RefMatrixf(textureMatrix)); model->colorLayers().push_back(layerModel); if (imageLayer->isShared()) { model->sharedLayers().push_back(layerModel); } if (imageLayer->isDynamic()) { model->setRequiresUpdateTraverse(true); } } } else // non-image kind of TILE layer: { TerrainTileColorLayerModel* colorModel = new TerrainTileColorLayerModel(); colorModel->setLayer(layer); model->colorLayers().push_back(colorModel); } } if (progress) progress->stats()["fetch_imagery_time"] += OE_STOP_TIMER(fetch_image_layers); }
void TerrainTileModelFactory::addElevation(TerrainTileModel* model, const Map* map, const TileKey& key, const CreateTileModelFilter& filter, unsigned border, ProgressCallback* progress) { // make an elevation layer. OE_START_TIMER(fetch_elevation); if (!filter.empty() && !filter.elevation().isSetTo(true)) return; const osgEarth::ElevationInterpolation& interp = map->getMapOptions().elevationInterpolation().get(); // Request a heightfield from the map. osg::ref_ptr<osg::HeightField> mainHF; osg::ref_ptr<NormalMap> normalMap; bool hfOK = getOrCreateHeightField(map, key, SAMPLE_FIRST_VALID, interp, border, mainHF, normalMap, progress) && mainHF.valid(); if (hfOK == false && key.getLOD() == _options.firstLOD().get()) { OE_DEBUG << LC << "No HF at key " << key.str() << ", making placeholder" << std::endl; mainHF = new osg::HeightField(); mainHF->allocate(1, 1); mainHF->setHeight(0, 0, 0.0f); hfOK = true; } if (hfOK && mainHF.valid()) { osg::ref_ptr<TerrainTileElevationModel> layerModel = new TerrainTileElevationModel(); layerModel->setHeightField( mainHF.get() ); // pre-calculate the min/max heights: for( unsigned col = 0; col < mainHF->getNumColumns(); ++col ) { for( unsigned row = 0; row < mainHF->getNumRows(); ++row ) { float h = mainHF->getHeight(col, row); if ( h > layerModel->getMaxHeight() ) layerModel->setMaxHeight( h ); if ( h < layerModel->getMinHeight() ) layerModel->setMinHeight( h ); } } // needed for normal map generation model->heightFields().setNeighbor(0, 0, mainHF.get()); // convert the heightfield to a 1-channel 32-bit fp image: ImageToHeightFieldConverter conv; osg::Image* hfImage = conv.convertToR32F(mainHF.get()); if ( hfImage ) { // Made an image, so store this as a texture with no matrix. osg::Texture* texture = createElevationTexture( hfImage ); layerModel->setTexture( texture ); model->elevationModel() = layerModel.get(); } if (normalMap.valid()) { TerrainTileImageLayerModel* layerModel = new TerrainTileImageLayerModel(); layerModel->setName( "oe_normal_map" ); // Made an image, so store this as a texture with no matrix. osg::Texture* texture = createNormalTexture(normalMap.get()); layerModel->setTexture( texture ); model->normalModel() = layerModel; } } if (progress) progress->stats()["fetch_elevation_time"] += OE_STOP_TIMER(fetch_elevation); }