Пример #1
0
int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc,argv);

    osgViewer::Viewer viewer(arguments);

    // Start by creating the map:
    MapOptions mapOptions;
    mapOptions.cachePolicy() = CachePolicy::NO_CACHE;
    Map* map = new Map( mapOptions );

    // Create out image layer with a custom tile source.
    ImageLayerOptions options( "custom" );
    CustomTileSource* tileSource = new CustomTileSource();
    tileSource->open();
    map->addImageLayer( new ImageLayer(options, tileSource) );

    // That's it, the map is ready; now create a MapNode to render the Map:
    MapNode* mapNode = new MapNode( map );

    viewer.setSceneData( mapNode );
    viewer.setCameraManipulator( new EarthManipulator() );

    // add some stock OSG handlers:
    viewer.addEventHandler(new osgViewer::StatsHandler());
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));

    return viewer.run();
}
        virtual ReadResult readNode(const std::string& fileName, const osgDB::Options* options) const
        {
            std::string ext = osgDB::getFileExtension( fileName );
            if ( !acceptsExtension( ext ) )
                return ReadResult::FILE_NOT_HANDLED;

            // See if the filename starts with server: and strip it off.  This will trick OSG into
            // passing in the filename to our plugin instead of using the CURL plugin if the filename
            // contains a URL.  So, if you want to read a URL, you can use the following format
            // osgDB::readNodeFile("server:http://myserver/myearth.earth").  This should only be
            // necessary for the first level as the other files will have a tilekey prepended to them.
            if ((fileName.length() > 7) && (fileName.substr(0, 7) == "server:"))
                return readNode(fileName.substr(7), options);            

            if ( fileName == "__globe.earth" )
            {
                return ReadResult( new MapNode() );
            }

            else if ( fileName == "__cube.earth" )
            {
                MapOptions options;
                options.coordSysType() = MapOptions::CSTYPE_GEOCENTRIC_CUBE;
                return ReadResult( new MapNode( new Map(options) ) );
            }

            else
            {
                std::string fullFileName = fileName;
                if ( !osgDB::containsServerAddress( fileName ) )
                {
                    fullFileName = osgDB::findDataFile( fileName, options );
                    if (fullFileName.empty()) return ReadResult::FILE_NOT_FOUND;
                }

                osgEarth::ReadResult r = URI(fullFileName).readString( options );
                if ( r.failed() )
                    return ReadResult::ERROR_IN_READING_FILE;

                // Since we're now passing off control to the stream, we have to pass along the
                // reference URI as well..
                osg::ref_ptr<osgDB::Options> myOptions = Registry::instance()->cloneOrCreateOptions(options);

                URIContext( fullFileName ).apply( myOptions.get() );

                std::stringstream in( r.getString() );
                return readNode( in, myOptions.get() );
            }
        }
Пример #3
0
/**
 * Makes a simple projected MapNode that contains a basemap of the world
 */
MapNode* makeMiniMapNode( ) {    
    MapOptions mapOpt;
    mapOpt.coordSysType() = MapOptions::CSTYPE_PROJECTED;  
    mapOpt.profile() = ProfileOptions("plate-carre");
    Map* map = new Map( mapOpt );    

    GDALOptions basemapOpt;
    basemapOpt.url() = "../data/world.tif";
    map->addImageLayer( new ImageLayer( ImageLayerOptions("basemap", basemapOpt) ) );

    // That's it, the map is ready; now create a MapNode to render the Map:
    MapNodeOptions mapNodeOptions;
    mapNodeOptions.enableLighting() = false;    

    return new MapNode( map, mapNodeOptions );
}
Пример #4
0
Map::Impl::Impl(RendererFrontend& frontend_,
                MapObserver& observer_,
                std::shared_ptr<FileSource> fileSource_,
                const MapOptions& mapOptions)
        : observer(observer_),
          rendererFrontend(frontend_),
          transform(observer, mapOptions.constrainMode(), mapOptions.viewportMode()),
          mode(mapOptions.mapMode()),
          pixelRatio(mapOptions.pixelRatio()),
          crossSourceCollisions(mapOptions.crossSourceCollisions()),
          fileSource(std::move(fileSource_)),
          style(std::make_unique<style::Style>(*fileSource, pixelRatio)),
          annotationManager(*style) {
    transform.setNorthOrientation(mapOptions.northOrientation());
    style->impl->setObserver(this);
    rendererFrontend.setObserver(*this);
    transform.resize(mapOptions.size());
}
Пример #5
0
void
SimpleOceanNode::rebuild()
{
    this->removeChildren( 0, this->getNumChildren() );

    osg::ref_ptr<MapNode> mapNode;
    if (_parentMapNode.lock(mapNode))
    {
        const MapOptions&     parentMapOptions     = mapNode->getMap()->getMapOptions();
        const MapNodeOptions& parentMapNodeOptions = mapNode->getMapNodeOptions();

        // set up the map to "match" the parent map:
        MapOptions mo;
        mo.coordSysType() = parentMapOptions.coordSysType();
        mo.profile()      = mapNode->getMap()->getProfile()->toProfileOptions();

        // new data model for the ocean:
        Map* oceanMap = new Map( mo );

        // ditto with the map node options:
        MapNodeOptions mno;
        if ( mno.enableLighting().isSet() )
            mno.enableLighting() = *mno.enableLighting();

        RexTerrainEngineOptions terrainoptions;

        terrainoptions.enableBlending() = true;        // gotsta blend with the main node

        terrainoptions.color() = baseColor().get();

        terrainoptions.tileSize() = 5;

        mno.setTerrainOptions( terrainoptions );

        // make the ocean's map node:
        MapNode* oceanMapNode = new MapNode( oceanMap, mno );

        // set up the shaders.
        osg::StateSet* ss = this->getOrCreateStateSet();

        // if the caller requested a mask layer, install that now.
        if ( maskLayer().isSet() )
        {
            if ( !maskLayer()->maxLevel().isSet() )
            {
                // set the max subdivision level if it's not already specified in the 
                // mask layer options:
                maskLayer()->maxLevel() = maxLOD().get();
            }

            // make sure the mask is shared (so we can access it from our shader)
            // and invisible (so we can't see it)
            maskLayer()->shared() = true;
            maskLayer()->visible() = false;

            ImageLayer* layer = new ImageLayer("ocean-mask", maskLayer().get());
            oceanMap->addLayer( layer );

            ss->setDefine("OE_SIMPLE_OCEAN_USE_MASK");
            OE_INFO << LC << "Using mask layer \"" << layer->getName() << "\"\n";
        }

        // otherwise, install a "proxy layer" that will use the elevation data in the map
        // to determine where the ocean is. This approach is limited in that it cannot
        // detect the difference between ocean and inland areas that are below sea level.
        else
        {
            // install an "elevation proxy" layer that reads elevation tiles from the
            // parent map and turns them into encoded images for our shader to use.
            ImageLayerOptions epo( "ocean-proxy" );
            epo.cachePolicy() = CachePolicy::NO_CACHE;
            epo.shared() = true;
            epo.visible() = false;
            epo.shareTexUniformName() = "oe_ocean_proxyTex";
            epo.shareTexMatUniformName() = "oe_ocean_proxyMat";
            oceanMap->addLayer( new ElevationProxyImageLayer(mapNode->getMap(), epo) );
            OE_INFO << LC << "Using elevation proxy layer\n";
        }

        this->addChild( oceanMapNode );

        // install the shaders on the ocean map node.
        VirtualProgram* vp = VirtualProgram::getOrCreate( ss );
        vp->setName( "osgEarth SimpleOcean" );        
        Shaders shaders;
        shaders.loadAll(vp, 0L);

        // set up the options uniforms.

        _seaLevel = new osg::Uniform(osg::Uniform::FLOAT, "ocean_seaLevel");
        ss->addUniform( _seaLevel.get() );

        _lowFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_lowFeather");
        ss->addUniform( _lowFeather.get() );

        _highFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_highFeather");
        ss->addUniform( _highFeather.get() );

        _baseColor = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "ocean_baseColor");
        ss->addUniform( _baseColor.get() );

        _maxRange = new osg::Uniform(osg::Uniform::FLOAT, "ocean_max_range");
        ss->addUniform( _maxRange.get() );

        _fadeRange = new osg::Uniform(osg::Uniform::FLOAT, "ocean_fade_range");
        ss->addUniform( _fadeRange.get() );

        _alphaUniform = new osg::Uniform(osg::Uniform::FLOAT, "oe_ocean_alpha");
        ss->addUniform( _alphaUniform.get() );

        // disable depth writes.
        ss->setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL, 0.0, 1.0, false) );

        // load up a surface texture
        osg::ref_ptr<osg::Image> surfaceImage;
        if ( textureURI().isSet() )
        {
            surfaceImage = textureURI()->getImage();
        }

        //if ( !surfaceImage.valid() )
        //{
        //    surfaceImage = createSurfaceImage();
        //}

        if ( surfaceImage.valid() )
        {
            osg::Texture2D* tex = new osg::Texture2D( surfaceImage.get() );
            tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
            tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
            tex->setWrap  ( osg::Texture::WRAP_S, osg::Texture::REPEAT );
            tex->setWrap  ( osg::Texture::WRAP_T, osg::Texture::REPEAT );

            ss->setTextureAttributeAndModes( 5, tex, 1 );
            ss->getOrCreateUniform( "ocean_surface_tex", osg::Uniform::SAMPLER_2D )->set( 5 );

            ss->setDefine("OE_SIMPLE_OCEAN_USE_TEXTURE");
            OE_INFO << LC << "Using a surface texture (" << surfaceImage->getFileName() << ")\n";
        }

        // remove backface culling so we can see underwater
        // (use OVERRIDE since the terrain engine sets back face culling.)
        ss->setAttributeAndModes( 
            new osg::CullFace(), 
            osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE );

        // Material.
        osg::Material* m = new osgEarth::MaterialGL3();
        m->setAmbient(m->FRONT_AND_BACK, osg::Vec4(.5,.5,.5,1));
        m->setDiffuse(m->FRONT_AND_BACK, osg::Vec4(1,1,1,1));
        m->setSpecular(m->FRONT_AND_BACK, osg::Vec4(0.2,0.2,0.2,1));
        m->setEmission(m->FRONT_AND_BACK, osg::Vec4(0,0,0,1));
        m->setShininess(m->FRONT_AND_BACK, 40.0);
        ss->setAttributeAndModes(m, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE );

        // force apply options:
        applyOptions();
    }
}
Пример #6
0
void
OceanSurfaceContainer::rebuild()
{
    this->removeChildren( 0, this->getNumChildren() );

    if ( _parentMapNode.valid() )
    {
        const MapOptions&     parentMapOptions     = _parentMapNode->getMap()->getMapOptions();
        const MapNodeOptions& parentMapNodeOptions = _parentMapNode->getMapNodeOptions();

        // set up the map to "match" the parent map:
        MapOptions mo;
        mo.coordSysType() = parentMapOptions.coordSysType();
        mo.profile()      = _parentMapNode->getMap()->getProfile()->toProfileOptions();

        // new data model for the ocean:
        Map* oceanMap = new Map( mo );

        // ditto with the map node options:
        MapNodeOptions mno;
        if ( mno.enableLighting().isSet() )
            mno.enableLighting() = *mno.enableLighting();

        QuadTreeTerrainEngineOptions to;
        to.heightFieldSkirtRatio() = 0.0;  // don't want to see skirts
        to.clusterCulling() = false;       // want to see underwater
        to.enableBlending() = true;        // gotsta blend with the main node
        mno.setTerrainOptions( to );

        // make the ocean's map node:
        MapNode* oceanMapNode = new MapNode( oceanMap, mno );
        
        // install a custom compositor. Must do this before adding any image layers.
        oceanMapNode->setCompositorTechnique( new OceanCompositor() );

        // install an "elevation proxy" layer that reads elevation tiles from the
        // parent map and turns them into encoded images for our shader to use.
        ImageLayerOptions epo( "ocean-proxy" );
        epo.cachePolicy() = CachePolicy::NO_CACHE;
        epo.maxLevel() = *_options.maxLOD();
        oceanMap->addImageLayer( new ElevationProxyImageLayer(_parentMapNode->getMap(), epo) );

        this->addChild( oceanMapNode );

        // set up the options uniforms.
        osg::StateSet* ss = this->getOrCreateStateSet();

        _seaLevel = new osg::Uniform(osg::Uniform::FLOAT, "ocean_seaLevel");
        ss->addUniform( _seaLevel.get() );

        _lowFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_lowFeather");
        ss->addUniform( _lowFeather.get() );

        _highFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_highFeather");
        ss->addUniform( _highFeather.get() );

        _baseColor = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "ocean_baseColor");
        ss->addUniform( _baseColor.get() );

        // trick to prevent z-fighting..
        ss->setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL, 0.0, 1.0, false) );
        ss->setRenderBinDetails( 15, "RenderBin" );

        // load up a surface texture
        ss->getOrCreateUniform( "ocean_has_tex1", osg::Uniform::BOOL )->set( false );
        if ( _options.textureURI().isSet() )
        {
            //TODO: enable cache support here:
            osg::Image* image = _options.textureURI()->getImage();
            if ( image )
            {
                osg::Texture2D* tex = new osg::Texture2D( image );
                tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
                tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
                tex->setWrap  ( osg::Texture::WRAP_S, osg::Texture::REPEAT );
                tex->setWrap  ( osg::Texture::WRAP_T, osg::Texture::REPEAT );

                ss->setTextureAttributeAndModes( 1, tex, 1 );
                ss->getOrCreateUniform( "ocean_tex1", osg::Uniform::SAMPLER_2D )->set( 1 );
                ss->getOrCreateUniform( "ocean_has_tex1", osg::Uniform::BOOL )->set( true );
            }
        }

        // remove backface culling so we can see underwater
        // (use OVERRIDE since the terrain engine sets back face culling.)
        ss->setAttributeAndModes( new osg::CullFace(), osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE );

        apply( _options );
    }
}
Пример #7
0
void GlobePlugin::setupMap()
{
  QSettings settings;
  QString cacheDirectory = settings.value( "cache/directory", QgsApplication::qgisSettingsDirPath() + "cache" ).toString();
  TMSCacheOptions cacheOptions;
  cacheOptions.setPath( cacheDirectory.toStdString() );

  MapOptions mapOptions;
  mapOptions.cache() = cacheOptions;
  osgEarth::Map *map = new osgEarth::Map( mapOptions );

  //Default image layer
  GDALOptions driverOptions;
  driverOptions.url() = QDir::cleanPath( QgsApplication::pkgDataPath() + "/globe/world.tif" ).toStdString();
  ImageLayerOptions layerOptions( "world", driverOptions );
  layerOptions.cacheEnabled() = false;
  map->addImageLayer( new osgEarth::ImageLayer( layerOptions ) );

  MapNodeOptions nodeOptions;
  //nodeOptions.proxySettings() =
  //nodeOptions.enableLighting() = false;

  //LoadingPolicy loadingPolicy( LoadingPolicy::MODE_SEQUENTIAL );
  TerrainOptions terrainOptions;
  //terrainOptions.loadingPolicy() = loadingPolicy;
  terrainOptions.compositingTechnique() = TerrainOptions::COMPOSITING_MULTITEXTURE_FFP;
  nodeOptions.setTerrainOptions( terrainOptions );

  // The MapNode will render the Map object in the scene graph.
  mMapNode = new osgEarth::MapNode( map, nodeOptions );

  //prefill cache
  if ( !QFile::exists( cacheDirectory + "/worldwind_srtm" ) )
  {
    copyFolder( QgsApplication::pkgDataPath() + "/globe/data/worldwind_srtm", cacheDirectory + "/globe/worldwind_srtm" );
  }

  mRootNode = new osg::Group();
  mRootNode->addChild( mMapNode );

  // Add layers to the map
  layersChanged();

  // model placement utils
  mElevationManager = new osgEarth::Util::ElevationManager( mMapNode->getMap() );
  mElevationManager->setTechnique( osgEarth::Util::ElevationManager::TECHNIQUE_GEOMETRIC );
  mElevationManager->setMaxTilesToCache( 50 );

  mObjectPlacer = new osgEarth::Util::ObjectPlacer( mMapNode );

  // place 3D model on point layer
  if ( mSettingsDialog.modelLayer() && !mSettingsDialog.modelPath().isEmpty() )
  {
    osg::Node* model = osgDB::readNodeFile( mSettingsDialog.modelPath().toStdString() );
    if ( model )
    {
      QgsVectorLayer* layer = mSettingsDialog.modelLayer();
      QgsAttributeList fetchAttributes;
      layer->select( fetchAttributes ); //TODO: select only visible features
      QgsFeature feature;
      while ( layer->nextFeature( feature ) )
      {
        QgsPoint point = feature.geometry()->asPoint();
        placeNode( model, point.y(), point.x() );
      }
    }
  }

}
Пример #8
0
void
SimpleOceanNode::rebuild()
{
    this->removeChildren( 0, this->getNumChildren() );

    if ( _parentMapNode.valid() )
    {
        const MapOptions&     parentMapOptions     = _parentMapNode->getMap()->getMapOptions();
        const MapNodeOptions& parentMapNodeOptions = _parentMapNode->getMapNodeOptions();

        // set up the map to "match" the parent map:
        MapOptions mo;
        mo.coordSysType() = parentMapOptions.coordSysType();
        mo.profile()      = _parentMapNode->getMap()->getProfile()->toProfileOptions();

        // new data model for the ocean:
        Map* oceanMap = new Map( mo );

        // ditto with the map node options:
        MapNodeOptions mno;
        if ( mno.enableLighting().isSet() )
            mno.enableLighting() = *mno.enableLighting();

        MPTerrainEngineOptions mpoptions;
        mpoptions.heightFieldSkirtRatio() = 0.0;      // don't want to see skirts
        mpoptions.minLOD() = _options.maxLOD().get(); // weird, I know

        // so we can the surface from underwater:
        mpoptions.clusterCulling() = false;       // want to see underwater

        mpoptions.enableBlending() = true;        // gotsta blend with the main node

        mpoptions.color() = _options.baseColor().get();

        mno.setTerrainOptions( mpoptions );

        // make the ocean's map node:
        MapNode* oceanMapNode = new MapNode( oceanMap, mno );

        // if the caller requested a mask layer, install that now.
        if ( _options.maskLayer().isSet() )
        {
            if ( !_options.maskLayer()->maxLevel().isSet() )
            {
                // set the max subdivision level if it's not already specified in the 
                // mask layer options:
                _options.maskLayer()->maxLevel() = *_options.maxLOD();
            }

            // make sure the mask is shared (so we can access it from our shader)
            // and invisible (so we can't see it)
            _options.maskLayer()->shared() = true;
            _options.maskLayer()->visible() = false;

            ImageLayer* maskLayer = new ImageLayer( "ocean-mask", *_options.maskLayer() );
            oceanMap->addImageLayer( maskLayer );
        }

        // otherwise, install a "proxy layer" that will use the elevation data in the map
        // to determine where the ocean is. This approach is limited in that it cannot
        // detect the difference between ocean and inland areas that are below sea level.
        else
        {
            // install an "elevation proxy" layer that reads elevation tiles from the
            // parent map and turns them into encoded images for our shader to use.
            ImageLayerOptions epo( "ocean-proxy" );
            epo.cachePolicy() = CachePolicy::NO_CACHE;
            //epo.maxLevel() = *_options.maxLOD();
            oceanMap->addImageLayer( new ElevationProxyImageLayer(_parentMapNode->getMap(), epo) );
        }

        this->addChild( oceanMapNode );

        // set up the shaders.
        osg::StateSet* ss = this->getOrCreateStateSet();

        // install the shaders on the ocean map node.
        VirtualProgram* vp = VirtualProgram::getOrCreate( ss );
        vp->setName( "osgEarth SimpleOcean" );

        // use the appropriate shader for the active technique:
        std::string vertSource = _options.maskLayer().isSet() ? source_vertMask : source_vertProxy;
        std::string fragSource = _options.maskLayer().isSet() ? source_fragMask : source_fragProxy;

        vp->setFunction( "oe_ocean_vertex",   vertSource, ShaderComp::LOCATION_VERTEX_VIEW );
        vp->setFunction( "oe_ocean_fragment", fragSource, ShaderComp::LOCATION_FRAGMENT_COLORING, 0.6f );

        // install the slot attribute(s)
        ss->getOrCreateUniform( "ocean_data", osg::Uniform::SAMPLER_2D )->set( 0 );

        // set up the options uniforms.

        _seaLevel = new osg::Uniform(osg::Uniform::FLOAT, "ocean_seaLevel");
        ss->addUniform( _seaLevel.get() );

        _lowFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_lowFeather");
        ss->addUniform( _lowFeather.get() );

        _highFeather = new osg::Uniform(osg::Uniform::FLOAT, "ocean_highFeather");
        ss->addUniform( _highFeather.get() );

        _baseColor = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "ocean_baseColor");
        ss->addUniform( _baseColor.get() );

        _maxRange = new osg::Uniform(osg::Uniform::FLOAT, "ocean_max_range");
        ss->addUniform( _maxRange.get() );

        _fadeRange = new osg::Uniform(osg::Uniform::FLOAT, "ocean_fade_range");
        ss->addUniform( _fadeRange.get() );

        // trick to mitigate z-fighting..
        ss->setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL, 0.0, 1.0, false) );
        ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

        // load up a surface texture
        osg::ref_ptr<osg::Image> surfaceImage;
        ss->getOrCreateUniform( "ocean_has_surface_tex", osg::Uniform::BOOL )->set( false );
        if ( _options.textureURI().isSet() )
        {
            //TODO: enable cache support here?
            surfaceImage = _options.textureURI()->getImage();
        }

        if ( !surfaceImage.valid() )
        {
            surfaceImage = createSurfaceImage();
        }

        if ( surfaceImage.valid() )
        {
            osg::Texture2D* tex = new osg::Texture2D( surfaceImage.get() );
            tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
            tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
            tex->setWrap  ( osg::Texture::WRAP_S, osg::Texture::REPEAT );
            tex->setWrap  ( osg::Texture::WRAP_T, osg::Texture::REPEAT );

            ss->setTextureAttributeAndModes( 2, tex, 1 );
            ss->getOrCreateUniform( "ocean_surface_tex", osg::Uniform::SAMPLER_2D )->set( 2 );
            ss->getOrCreateUniform( "ocean_has_surface_tex", osg::Uniform::BOOL )->set( true );
        }

        // remove backface culling so we can see underwater
        // (use OVERRIDE since the terrain engine sets back face culling.)
        ss->setAttributeAndModes( 
            new osg::CullFace(), 
            osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE );

        // Material.
        osg::Material* m = new osg::Material();
        m->setAmbient(m->FRONT_AND_BACK, osg::Vec4(0,0,0,1));
        m->setDiffuse(m->FRONT_AND_BACK, osg::Vec4(1,1,1,1));
        m->setSpecular(m->FRONT_AND_BACK, osg::Vec4(0.1,0.1,0.1,1));
        m->setEmission(m->FRONT_AND_BACK, osg::Vec4(0,0,0,1));
        m->setShininess(m->FRONT_AND_BACK, 32.0);
        ss->setAttributeAndModes(m, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE );

        // force apply options:
        applyOptions();
    }
}
Пример #9
0
void GlobePlugin::setupMap()
{
  QSettings settings;
  QString cacheDirectory = settings.value( "cache/directory", QgsApplication::qgisSettingsDirPath() + "cache" ).toString();

#if OSGEARTH_VERSION_GREATER_OR_EQUAL( 2, 2, 0 )
  FileSystemCacheOptions cacheOptions;
  cacheOptions.rootPath() = cacheDirectory.toStdString();
#else
  TMSCacheOptions cacheOptions;
  cacheOptions.setPath( cacheDirectory.toStdString() );
#endif

  MapOptions mapOptions;
  mapOptions.cache() = cacheOptions;
  osgEarth::Map *map = new osgEarth::Map( mapOptions );

  //Default image layer
  /*
  GDALOptions driverOptions;
  driverOptions.url() = QDir::cleanPath( QgsApplication::pkgDataPath() + "/globe/world.tif" ).toStdString();
  ImageLayerOptions layerOptions( "world", driverOptions );
  map->addImageLayer( new osgEarth::ImageLayer( layerOptions ) );
  */

  MapNodeOptions nodeOptions;
  //nodeOptions.proxySettings() =
  //nodeOptions.enableLighting() = false;

  //LoadingPolicy loadingPolicy( LoadingPolicy::MODE_SEQUENTIAL );
  TerrainOptions terrainOptions;
  //terrainOptions.loadingPolicy() = loadingPolicy;
  terrainOptions.compositingTechnique() = TerrainOptions::COMPOSITING_MULTITEXTURE_FFP;
  //terrainOptions.lodFallOff() = 6.0;
  nodeOptions.setTerrainOptions( terrainOptions );

  // The MapNode will render the Map object in the scene graph.
  mMapNode = new osgEarth::MapNode( map, nodeOptions );

  if ( settings.value( "/Plugin-Globe/baseLayerEnabled", true ).toBool() )
  {
    setBaseMap( settings.value( "/Plugin-Globe/baseLayerURL", "http://readymap.org/readymap/tiles/1.0.0/7/" ).toString() );
  }

  mRootNode = new osg::Group();
  mRootNode->addChild( mMapNode );

  // Add layers to the map
  imageLayersChanged();
  elevationLayersChanged();

  // model placement utils
#ifdef HAVE_OSGEARTH_ELEVATION_QUERY
#else
  mElevationManager = new osgEarth::Util::ElevationManager( mMapNode->getMap() );
  mElevationManager->setTechnique( osgEarth::Util::ElevationManager::TECHNIQUE_GEOMETRIC );
  mElevationManager->setMaxTilesToCache( 50 );

  mObjectPlacer = new osgEarth::Util::ObjectPlacer( mMapNode );

  // place 3D model on point layer
  if ( mSettingsDialog->modelLayer() && !mSettingsDialog->modelPath().isEmpty() )
  {
    osg::Node* model = osgDB::readNodeFile( mSettingsDialog->modelPath().toStdString() );
    if ( model )
    {
      QgsVectorLayer* layer = mSettingsDialog->modelLayer();
      QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ) ); //TODO: select only visible features
      QgsFeature feature;
      while ( fit.nextFeature( feature ) )
      {
        QgsPoint point = feature.geometry()->asPoint();
        placeNode( model, point.y(), point.x() );
      }
    }
  }
#endif

}