Esempio n. 1
0
FeatureModelGraph::FeatureModelGraph(FeatureSource*                   source,
                                     const FeatureModelSourceOptions& options,
                                     FeatureNodeFactory*              factory,
                                     const StyleSheet&                styles,
                                     Session*                         session ) :
_source ( source ),
_options( options ),
_factory( factory ),
_styles ( styles ),
_session( session )
{
    _uid = osgEarthFeatureModelPseudoLoader::registerGraph( this );

    osg::StateSet* stateSet = getOrCreateStateSet();

    if ( _options.enableLighting().isSet() )
        stateSet->setMode( GL_LIGHTING, *_options.enableLighting() ? 1 : 0 );
    
    // Calculate the usable extent (in both feature and map coordinates) and bounds.
    const Profile* mapProfile = session->getMapInfo().getProfile();

    // the part of the feature extent that will fit on the map (in map coords):
    _usableMapExtent = mapProfile->clampAndTransformExtent( 
        _source->getFeatureProfile()->getExtent(), 
        &_featureExtentClamped );

    // same, back into feature coords:
    _usableFeatureExtent = _usableMapExtent.transform( _source->getFeatureProfile()->getSRS() );

    // world-space bounds of the feature layer
    _fullWorldBound = getBoundInWorldCoords( _usableMapExtent );

    // whether to request tiles from the source (if available). if the source is tiled, but the
    // user manually specified schema levels, don't use the tiles.
    _useTiledSource = _source->getFeatureProfile()->getTiled();
    if ( _useTiledSource && options.levels().isSet() && options.levels()->getNumLevels() > 0 )
        _useTiledSource = false;

    // if there's a display schema in place, set up for quadtree paging.
    if ( options.levels().isSet() || _useTiledSource ) //_source->getFeatureProfile()->getTiled() )
    {
        setupPaging();
    }
    else
    {
        FeatureLevel defaultLevel( 0.0f, FLT_MAX );
        osg::Node* node = build( defaultLevel, GeoExtent::INVALID, 0 );
        if ( node )
            this->addChild( node );
    }
}
Esempio n. 2
0
FeatureModelGraph::FeatureModelGraph(Session*                         session,
                                     const FeatureModelSourceOptions& options,
                                     FeatureNodeFactory*              factory ) :
_session      ( session ),
_options      ( options ),
_factory      ( factory ),
_dirty        ( false ),
_pendingUpdate( false )
{
    _uid = osgEarthFeatureModelPseudoLoader::registerGraph( this );

    _postMergeOperations = new RefNodeOperationVector();

    // install the stylesheet in the session if it doesn't already have one.
    if ( !session->styles() )
        session->setStyles( _options.styles().get() );

    if ( !session->getFeatureSource() )
    {
        OE_WARN << LC << "ILLEGAL: Session must have a feature source" << std::endl;
        return;
    }
    
    // Calculate the usable extent (in both feature and map coordinates) and bounds.
    const Profile* mapProfile = session->getMapInfo().getProfile();
    const FeatureProfile* featureProfile = session->getFeatureSource()->getFeatureProfile();

    // Bail out if the feature profile is bad
    if ( !featureProfile || !featureProfile->getExtent().isValid() )
    {
        // warn or allow?
        return;
    }

    // the part of the feature extent that will fit on the map (in map coords):
    _usableMapExtent = mapProfile->clampAndTransformExtent( 
        featureProfile->getExtent(), 
        &_featureExtentClamped );

    // same, back into feature coords:
    _usableFeatureExtent = _usableMapExtent.transform( featureProfile->getSRS() );

    // world-space bounds of the feature layer
    _fullWorldBound = getBoundInWorldCoords( _usableMapExtent, 0L );

    // whether to request tiles from the source (if available). if the source is tiled, but the
    // user manually specified schema levels, don't use the tiles.
    _useTiledSource = featureProfile->getTiled();

    if ( options.layout().isSet() && options.layout()->getNumLevels() > 0 )
    {
        // the user provided a custom levels setup, so don't use the tiled source (which
        // provides its own levels setup)
        _useTiledSource = false;

        // for each custom level, calculate the best LOD match and store it in the level
        // layout data. We will use this information later when constructing the SG in
        // the pager.
        for( unsigned i = 0; i < options.layout()->getNumLevels(); ++i )
        {
            const FeatureLevel* level = options.layout()->getLevel( i );
            unsigned lod = options.layout()->chooseLOD( *level, _fullWorldBound.radius() );
            _lodmap.resize( lod+1, 0L );
            _lodmap[lod] = level;

            OE_INFO << LC << session->getFeatureSource()->getName() 
                << ": F.Level max=" << level->maxRange() << ", min=" << level->minRange()
                << ", LOD=" << lod << std::endl;
        }
    }

    // install base shader mains.
    if ( Registry::instance()->getCapabilities().supportsGLSL() )
    {
        installShaderMains();
    }

    // Set up the state set.
    // backface culling is ON by default. By the way, this is most definitely
    // necessary when shading with shadows.
    osg::StateSet* stateSet = getOrCreateStateSet();
    stateSet->setMode( GL_CULL_FACE, 1 );
    stateSet->setMode( GL_BLEND, 1 );
    if ( _options.enableLighting().isSet() )
        stateSet->setMode( GL_LIGHTING, *_options.enableLighting() ? 1 : 0 );

    ADJUST_EVENT_TRAV_COUNT( this, 1 );

    redraw();
}
Esempio n. 3
0
FeatureModelGraph::FeatureModelGraph(Session*                         session,
                                     const FeatureModelSourceOptions& options,
                                     FeatureNodeFactory*              factory,
                                     RefNodeOperationVector*          postMergeOperations) :
_session            ( session ),
_options            ( options ),
_factory            ( factory ),
_postMergeOperations( postMergeOperations ),
_dirty              ( false ),
_pendingUpdate      ( false ),
_overlayInstalled   ( 0L ),
_overlayPlaceholder ( 0L ),
_clampable          ( 0L ),
_drapeable          ( 0L ),
_overlayChange      ( OVERLAY_NO_CHANGE )
{
    _uid = osgEarthFeatureModelPseudoLoader::registerGraph( this );

    // an FLC that queues feature data on the high-latency thread.
    _defaultFileLocationCallback = new HighLatencyFileLocationCallback();

    // install the stylesheet in the session if it doesn't already have one.
    if ( !session->styles() )
        session->setStyles( _options.styles().get() );

    if ( !session->getFeatureSource() )
    {
        OE_WARN << LC << "ILLEGAL: Session must have a feature source" << std::endl;
        return;
    }

    // set up a shared resource cache for the session. The ResourceCache will make sure
    // that resources (skin textures, instance models, etc.) only get loaded once.
    if ( !session->getResourceCache() && _options.sessionWideResourceCache() == true )
    {
        session->setResourceCache( new ResourceCache(session->getDBOptions()) );
    }
    
    // Calculate the usable extent (in both feature and map coordinates) and bounds.
    const Profile* mapProfile = session->getMapInfo().getProfile();
    const FeatureProfile* featureProfile = session->getFeatureSource()->getFeatureProfile();

    // Bail out if the feature profile is bad
    if ( !featureProfile || !featureProfile->getExtent().isValid() )
    {
        // warn or allow?
        return;
    }

    // the part of the feature extent that will fit on the map (in map coords):
    _usableMapExtent = mapProfile->clampAndTransformExtent( 
        featureProfile->getExtent(), 
        &_featureExtentClamped );

    // same, back into feature coords:
    _usableFeatureExtent = _usableMapExtent.transform( featureProfile->getSRS() );

    // world-space bounds of the feature layer
    _fullWorldBound = getBoundInWorldCoords( _usableMapExtent, 0L );

    // whether to request tiles from the source (if available). if the source is tiled, but the
    // user manually specified schema levels, don't use the tiles.
    _useTiledSource = featureProfile->getTiled();

    if ( options.layout().isSet() && options.layout()->getNumLevels() > 0 )
    {
        // the user provided a custom levels setup, so don't use the tiled source (which
        // provides its own levels setup)
        _useTiledSource = false;

        // for each custom level, calculate the best LOD match and store it in the level
        // layout data. We will use this information later when constructing the SG in
        // the pager.
        for( unsigned i = 0; i < options.layout()->getNumLevels(); ++i )
        {
            const FeatureLevel* level = options.layout()->getLevel( i );
            unsigned lod = options.layout()->chooseLOD( *level, _fullWorldBound.radius() );
            _lodmap.resize( lod+1, 0L );
            _lodmap[lod] = level;

            OE_INFO << LC << session->getFeatureSource()->getName() 
                << ": F.Level max=" << level->maxRange() << ", min=" << level->minRange()
                << ", LOD=" << lod << std::endl;
        }
    }

    // Apply some default state. The options properties let you override the
    // defaults, but we'll set some reasonable state if they are not set.

    osg::StateSet* stateSet = getOrCreateStateSet();

    // Set up backface culling. If the option is unset, enable it by default
    // since shadowing requires it and it's a decent general-purpose setting
    if ( _options.backfaceCulling().isSet() )
        stateSet->setMode( GL_CULL_FACE, *_options.backfaceCulling() ? 1 : 0 );
    else
        stateSet->setMode( GL_CULL_FACE, 1 );

    // Set up alpha blending. Enable it by default if not specified.
    if ( _options.alphaBlending().isSet() )
        stateSet->setMode( GL_BLEND, *_options.alphaBlending() ? 1 : 0 );
    else
        stateSet->setMode( GL_BLEND, 1 );

    // Set up lighting, only if the option is set
    if ( _options.enableLighting().isSet() )
        stateSet->setMode( GL_LIGHTING, *_options.enableLighting() ? 1 : 0 );

    // If the user requests fade-in, install a post-merge operation that will set the 
    // proper fade time for paged nodes.
    if ( _options.fading().isSet() )
    {
        _postMergeOperations->mutex().writeLock();
        _postMergeOperations->push_back( new SetupFading() );
        _postMergeOperations->mutex().writeUnlock();
        OE_INFO << LC << "Added fading post-merge operation" << std::endl;
    }

    ADJUST_EVENT_TRAV_COUNT( this, 1 );

    redraw();
}