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 ); } } }
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 ); } } } } }