X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScenery%2Ftilemgr.cxx;h=54fe7988e30c78dc08d93038d9fbd4f59b94857b;hb=070dba29f9390806457206c2660f2daebd3d847c;hp=642133229175a302d9132463c4f5fd75966110cd;hpb=e03ebef99f8a4cf9e76734a76ad5e4d84f0d29f4;p=flightgear.git diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 642133229..54fe7988e 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -38,6 +38,7 @@ #include #include #include +#include #include
#include
@@ -52,14 +53,37 @@ using flightgear::SceneryPager; +class FGTileMgr::TileManagerListener : public SGPropertyChangeListener +{ +public: + TileManagerListener(FGTileMgr* manager) : + _manager(manager) + { + fgGetNode("/sim/rendering/use-vbos", true)->addChangeListener(this, true); + } + + ~TileManagerListener() + { + fgGetNode("/sim/rendering/use-vbos")->removeChangeListener(this); + } + + virtual void valueChanged(SGPropertyNode* prop) + { + bool useVBOs = prop->getBoolValue(); + _manager->_options->setPluginStringData("SimGear::USE_VBOS", + useVBOs ? "ON" : "OFF"); + } + +private: + FGTileMgr* _manager; +}; FGTileMgr::FGTileMgr(): state( Start ), last_state( Running ), - longitude(-1000.0), - latitude(-1000.0), scheduled_visibility(100.0), _terra_sync(NULL), + _listener(NULL), _visibilityMeters(fgGetNode("/environment/visibility-m", true)), _maxTileRangeM(fgGetNode("/sim/rendering/static-lod/bare", true)), _disableNasalHooks(fgGetNode("/sim/temp/disable-scenery-nasal", true)), @@ -72,6 +96,8 @@ FGTileMgr::FGTileMgr(): FGTileMgr::~FGTileMgr() { + delete _listener; + // remove all nodes we might have left behind osg::Group* group = globals->get_scenery()->get_terrain_branch(); group->removeChildren(0, group->getNumChildren()); @@ -85,7 +111,9 @@ void FGTileMgr::init() { SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." ); _options = new simgear::SGReaderWriterOptions; - _options->setMaterialLib(globals->get_matlib()); + _listener = new TileManagerListener(this); + + materialLibChanged(); _options->setPropertyNode(globals->get_props()); osgDB::FilePathList &fp = _options->getDatabasePathList(); @@ -104,17 +132,10 @@ void FGTileMgr::init() { reinit(); } -void FGTileMgr::refresh_tile(void* tileMgr, long tileIndex) -{ - ((FGTileMgr*) tileMgr)->tile_cache.refresh_tile(tileIndex); -} - void FGTileMgr::reinit() { _terra_sync = static_cast (globals->get_subsystem("terrasync")); - if (_terra_sync) - _terra_sync->setTileRefreshCb(&refresh_tile, this); - + // protect against multiple scenery reloads and properly reset flags, // otherwise aircraft fall through the ground while reloading scenery if (!fgGetBool("/sim/sceneryloaded",true)) @@ -122,8 +143,7 @@ void FGTileMgr::reinit() fgSetBool("/sim/sceneryloaded",false); fgSetDouble("/sim/startup/splash-alpha", 1.0); - // Reload the materials definitions - _options->setMaterialLib(globals->get_matlib()); + materialLibChanged(); // remove all old scenery nodes from scenegraph and clear cache osg::Group* group = globals->get_scenery()->get_terrain_branch(); @@ -140,13 +160,18 @@ void FGTileMgr::reinit() previous_bucket.make_bad(); current_bucket.make_bad(); - longitude = latitude = -1000.0; scheduled_visibility = 100.0; // force an update now update(0.0); } +void FGTileMgr::materialLibChanged() +{ + _options->setMaterialLib(globals->get_matlib()); + _options->getMaterialLib()->refreshActiveMaterials(); +} + /* schedule a tile for loading, keep request for given amount of time. * Returns true if tile is already loaded. */ bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_view, double duration) @@ -185,21 +210,20 @@ bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_vie void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) { // sanity check (unfortunately needed!) - if ( longitude < -180.0 || longitude > 180.0 - || latitude < -90.0 || latitude > 90.0 ) + if (!curr_bucket.isValid() ) { SG_LOG( SG_TERRAIN, SG_ALERT, - "Attempting to schedule tiles for bogus lon and lat = (" - << longitude << "," << latitude << ")" ); + "Attempting to schedule tiles for invalid bucket" ); return; } - SG_LOG( SG_TERRAIN, SG_INFO, - "scheduling needed tiles for " << longitude << " " << latitude << ", curr_bucket:" - << curr_bucket.gen_base_path() << "/" << curr_bucket.gen_index_str()); - double tile_width = curr_bucket.get_width_m(); double tile_height = curr_bucket.get_height_m(); + SG_LOG( SG_TERRAIN, SG_INFO, + "scheduling needed tiles for " << curr_bucket + << ", tile-width-m:" << tile_width << ", tile-height-m:" << tile_height); + + // cout << "tile width = " << tile_width << " tile_height = " // << tile_height << endl; @@ -234,7 +258,11 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) { for ( y = -yrange; y <= yrange; ++y ) { - SGBucket b = sgBucketOffset( longitude, latitude, x, y ); + SGBucket b = curr_bucket.sibling(x, y); + if (!b.isValid()) { + continue; + } + float priority = (-1.0) * (x*x+y*y); sched_tile( b, priority, true, 0.0 ); @@ -249,7 +277,7 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) * Update the various queues maintained by the tilemagr (private * internal function, do not call directly.) */ -void FGTileMgr::update_queues() +void FGTileMgr::update_queues(bool& isDownloadingScenery) { osg::FrameStamp* framestamp = globals->get_renderer()->getViewer()->getFrameStamp(); @@ -258,7 +286,8 @@ void FGTileMgr::update_queues() TileEntry *e; int loading=0; int sz=0; - + bool didRefreshMaterialCache = false; + tile_cache.set_current_time( current_time ); tile_cache.reset_traversal(); @@ -272,22 +301,27 @@ void FGTileMgr::update_queues() // based on current visibilty e->prep_ssg_node(vis); - bool nonExpiredOrCurrent = !e->is_expired(current_time) || e->is_current_view(); - if ( !e->is_loaded() && - !isTileDirSyncing(e->tileFileName) && - nonExpiredOrCurrent) - { - // schedule tile for loading with osg pager - _pager->queueRequest(e->tileFileName, - e->getNode(), - e->get_priority(), - framestamp, - e->getDatabaseRequest(), - _options.get()); - loading++; - } - } else - { + if (!e->is_loaded()) { + if (!didRefreshMaterialCache) { + didRefreshMaterialCache = true; + globals->get_matlib()->refreshActiveMaterials(); + } + + bool nonExpiredOrCurrent = !e->is_expired(current_time) || e->is_current_view(); + bool downloading = isTileDirSyncing(e->tileFileName); + isDownloadingScenery |= downloading; + if ( !downloading && nonExpiredOrCurrent) { + // schedule tile for loading with osg pager + _pager->queueRequest(e->tileFileName, + e->getNode(), + e->get_priority(), + framestamp, + e->getDatabaseRequest(), + _options.get()); + loading++; + } + } // of tile not loaded case + } else { SG_LOG(SG_TERRAIN, SG_ALERT, "Warning: empty tile in cache!"); } tile_cache.next(); @@ -328,7 +362,8 @@ void FGTileMgr::update(double) double vis = _visibilityMeters->getDoubleValue(); schedule_tiles_at(globals->get_view_position(), vis); - update_queues(); + bool waitingOnTerrasync = false; + update_queues(waitingOnTerrasync); // scenery loading check, triggers after each sim (tile manager) reinit if (!_scenery_loaded->getBoolValue()) @@ -337,6 +372,7 @@ void FGTileMgr::update(double) bool positionFinalized = fgGetBool("sim/position-finalized"); bool sceneryOverride = _scenery_override->getBoolValue(); + // we are done if final position is set and the scenery & FDM are done. // scenery-override can ignore the last two, but not position finalization. if (positionFinalized && (sceneryOverride || (isSceneryLoaded() && fdmInited))) @@ -346,7 +382,14 @@ void FGTileMgr::update(double) } else { - fgSplashProgress(positionFinalized ? "loading-scenery" : "finalize-position"); + if (!positionFinalized) { + fgSplashProgress("finalize-position"); + } else if (waitingOnTerrasync) { + fgSplashProgress("downloading-scenery"); + } else { + fgSplashProgress("loading-scenery"); + } + // be nice to loader threads while waiting for initial scenery, reduce to 20fps SGTimeStamp::sleepForMSec(50); } @@ -357,13 +400,10 @@ void FGTileMgr::update(double) // (FDM/AI/groundcache/... should use "schedule_scenery" instead) void FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m) { - longitude = location.getLongitudeDeg(); - latitude = location.getLatitudeDeg(); - // SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update() for " // << longitude << " " << latitude ); - current_bucket.set_bucket( location ); + current_bucket = SGBucket( location ); // schedule more tiles when visibility increased considerably // TODO Calculate tile size - instead of using fixed value (5000m) @@ -384,7 +424,8 @@ void FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m) if (current_bucket != previous_bucket) { // We've moved to a new bucket, we need to schedule any // needed tiles for loading. - SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" ); + SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr: at " << location << ", scheduling needed for:" << current_bucket + << ", visbility=" << range_m); scheduled_visibility = range_m; schedule_needed(current_bucket, range_m); } @@ -407,16 +448,12 @@ void FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m) */ bool FGTileMgr::schedule_scenery(const SGGeod& position, double range_m, double duration) { - const float priority = 0.0; - double current_longitude = position.getLongitudeDeg(); - double current_latitude = position.getLatitudeDeg(); - bool available = true; - // sanity check (unfortunately needed!) - if (current_longitude < -180 || current_longitude > 180 || - current_latitude < -90 || current_latitude > 90) + if (!position.isValid()) return false; - + const float priority = 0.0; + bool available = true; + SGBucket bucket(position); available = sched_tile( bucket, priority, false, duration ); @@ -442,8 +479,11 @@ bool FGTileMgr::schedule_scenery(const SGGeod& position, double range_m, double // We have already checked for the center tile. if ( x != 0 || y != 0 ) { - SGBucket b = sgBucketOffset( current_longitude, - current_latitude, x, y ); + SGBucket b = bucket.sibling(x, y ); + if (!b.isValid()) { + continue; + } + double distance2 = distSqr(cartPos, SGVec3d::fromGeod(b.get_center())); // Do not ask if it is just the next tile but way out of range. if (distance2 <= max_dist2) @@ -466,7 +506,7 @@ bool FGTileMgr::isSceneryLoaded() if (scheduled_visibility < range_m) range_m = scheduled_visibility; - return schedule_scenery(SGGeod::fromDeg(longitude, latitude), range_m, 0.0); + return schedule_scenery(globals->get_view_position(), range_m, 0.0); } bool FGTileMgr::isTileDirSyncing(const std::string& tileFileName) const