void
StreamingTerrainNode::updateTraversal( osg::NodeVisitor& nv )
{
    // this stamp keeps track of when requests are dispatched. If a request's stamp gets too
    // old, it is considered "expired" and subject to cancelation
    int stamp = nv.getFrameStamp()->getFrameNumber();

    // update the frame stamp on the task services. This is necessary to support 
    // automatic request cancelation for image requests.
    {
        ScopedLock<Mutex> lock( _taskServiceMutex );
        for (TaskServiceMap::iterator i = _taskServices.begin(); i != _taskServices.end(); ++i)
        {
            i->second->setStamp( stamp );
        }
    }

    // next, go through the live tiles and process update-traversal requests. This
    // requires a read-lock on the master tiles table.
    {
        Threading::ScopedReadLock tileTableReadLock( _tilesMutex );

        for( TileTable::const_iterator i = _tiles.begin(); i != _tiles.end(); ++i )
        {
            StreamingTile* tile = static_cast<StreamingTile*>( i->second.get() );

            // update the neighbor list for each tile.
            refreshFamily( _update_mapf.getMapInfo(), tile->getKey(), tile->getFamily(), true );

            tile->servicePendingElevationRequests( _update_mapf, stamp, true );                   
            tile->serviceCompletedRequests( _update_mapf, true );
        }
    }
}
示例#2
0
void
OSGTerrainEngineNode::updateElevation( Tile* tile )
{
    Threading::ScopedWriteLock exclusiveLock( tile->getTileLayersMutex() );

    const TileKey& key = tile->getKey();

    bool hasElevation = _update_mapf->elevationLayers().size() > 0;

    osgTerrain::HeightFieldLayer* heightFieldLayer = dynamic_cast<osgTerrain::HeightFieldLayer*>(tile->getElevationLayer());
    if (heightFieldLayer)
    {
        // In standard mode, just load the elevation data and dirty the tile.
        if ( !_isStreaming )
        {
            osg::ref_ptr<osg::HeightField> hf;

            if (hasElevation)
                _update_mapf->getHeightField( key, true, hf, 0L);

            if (!hf.valid()) 
                hf = OSGTileFactory::createEmptyHeightField( key );

            heightFieldLayer->setHeightField( hf.get() );
            hf->setSkirtHeight( tile->getBound().radius() * _terrainOptions.heightFieldSkirtRatio().value() );

            //TODO: review this in favor of a tile update...
            tile->setDirty( true );
        }

        else // if ( isStreaming )
        {
            StreamingTile* stile = static_cast<StreamingTile*>(tile);

            //Update the elevation hint
            stile->setHasElevationHint( hasElevation );

            //In seq/pre mode, if there is no elevation, just clear out all the elevation on the tiles
            if ( !hasElevation )
            {
                osg::ref_ptr<osg::HeightField> hf = OSGTileFactory::createEmptyHeightField( key );
                heightFieldLayer->setHeightField( hf.get() );
                hf->setSkirtHeight( stile->getBound().radius() * _terrainOptions.heightFieldSkirtRatio().value() );
                stile->setElevationLOD( key.getLevelOfDetail() );
                stile->resetElevationRequests( *_update_mapf );
                stile->queueTileUpdate( TileUpdate::UPDATE_ELEVATION );
            }
            else
            {
                //Always load the first LOD so the children tiles can have something to use for placeholders
                if (stile->getKey().getLevelOfDetail() == 1)
                {
                    osg::ref_ptr<osg::HeightField> hf;
                    _update_mapf->getHeightField( key, true, hf, 0L);
                    if (!hf.valid()) 
                        hf = OSGTileFactory::createEmptyHeightField( key );
                    heightFieldLayer->setHeightField( hf.get() );
                    hf->setSkirtHeight( stile->getBound().radius() * _terrainOptions.heightFieldSkirtRatio().value() );
                    stile->setElevationLOD(tile->getKey().getLevelOfDetail());
                    stile->queueTileUpdate( TileUpdate::UPDATE_ELEVATION );
                }
                else
                {
                    //Set the elevation LOD to -1
                    stile->setElevationLOD(-1);
                    stile->resetElevationRequests( *_update_mapf );
                }
            }
        }
    }
}