]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scenery/tilemgr.cxx
Fix issue reported by heap debugger
[flightgear.git] / src / Scenery / tilemgr.cxx
index 81e84bfe6af86b45f63c8f37170f5d90c40c8311..6eeb706679077d70b36065859b277f8e9ecf7c13 100644 (file)
@@ -35,6 +35,7 @@
 #include <simgear/structure/exception.hxx>
 #include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
+#include <simgear/scene/tsync/terrasync.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
@@ -52,17 +53,47 @@ using simgear::SGModelLib;
 using simgear::TileEntry;
 using simgear::TileCache;
 
+
+// helper: listen to property changes affecting tile loading
+class LoaderPropertyWatcher : public SGPropertyChangeListener
+{
+public:
+    LoaderPropertyWatcher(FGTileMgr* pTileMgr) :
+        _pTileMgr(pTileMgr)
+    {
+    }
+
+    virtual void valueChanged(SGPropertyNode*)
+    {
+        _pTileMgr->configChanged();
+    }
+
+private:
+    FGTileMgr* _pTileMgr;
+};
+
+
 FGTileMgr::FGTileMgr():
     state( Start ),
-    vis( 16000 )
+    vis( 16000 ),
+    _terra_sync(NULL),
+    _propListener(new LoaderPropertyWatcher(this))
 {
+    _randomObjects = fgGetNode("/sim/rendering/random-objects", true);
+    _randomVegetation = fgGetNode("/sim/rendering/random-vegetation", true);
+    _maxTileRangeM = fgGetNode("/sim/rendering/static-lod/bare", true);
 }
 
 
-FGTileMgr::~FGTileMgr() {
+FGTileMgr::~FGTileMgr()
+{
     // remove all nodes we might have left behind
     osg::Group* group = globals->get_scenery()->get_terrain_branch();
     group->removeChildren(0, group->getNumChildren());
+    delete _propListener;
+    _propListener = NULL;
+    // clear OSG cache
+    osgDB::Registry::instance()->clearObjectCache();
 }
 
 
@@ -72,8 +103,11 @@ void FGTileMgr::init() {
 
     _options = new SGReaderWriterBTGOptions;
     _options->setMatlib(globals->get_matlib());
-    _options->setUseRandomObjects(fgGetBool("/sim/rendering/random-objects", true));
-    _options->setUseRandomVegetation(fgGetBool("/sim/rendering/random-vegetation", true));
+
+    _randomObjects.get()->addChangeListener(_propListener, false);
+    _randomVegetation.get()->addChangeListener(_propListener, false);
+    configChanged();
+
     osgDB::FilePathList &fp = _options->getDatabasePathList();
     const string_list &sc = globals->get_fg_scenery();
     fp.clear();
@@ -89,18 +123,36 @@ void FGTileMgr::init() {
 
 void FGTileMgr::reinit()
 {
+    // remove all old scenery nodes from scenegraph and clear cache
+    osg::Group* group = globals->get_scenery()->get_terrain_branch();
+    group->removeChildren(0, group->getNumChildren());
     tile_cache.init();
     
+    // clear OSG cache, except on initial start-up
+    if (state != Start)
+    {
+        osgDB::Registry::instance()->clearObjectCache();
+    }
+    
     state = Inited;
     
     previous_bucket.make_bad();
     current_bucket.make_bad();
     longitude = latitude = -1000.0;
-    
+
+    _terra_sync = (simgear::SGTerraSync*) globals->get_subsystem("terrasync");
+    if (_terra_sync)
+        _terra_sync->setTileCache(&tile_cache);
+
     // force an update now
     update(0.0);
 }
 
+void FGTileMgr::configChanged()
+{
+    _options->setUseRandomObjects(_randomObjects.get()->getBoolValue());
+    _options->setUseRandomVegetation(_randomVegetation.get()->getBoolValue());
+}
 
 /* schedule a tile for loading, keep request for given amount of time.
  * Returns true if tile is already loaded. */
@@ -145,10 +197,7 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis)
         SG_LOG( SG_TERRAIN, SG_ALERT,
                 "Attempting to schedule tiles for bogus lon and lat  = ("
                 << longitude << "," << latitude << ")" );
-        return;                // FIXME
-        SG_LOG( SG_TERRAIN, SG_ALERT,
-                "This is a FATAL error.  Exiting!" );
-        exit(-1);
+        return;
     }
 
     SG_LOG( SG_TERRAIN, SG_INFO,
@@ -159,8 +208,9 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis)
     // cout << "tile width = " << tile_width << "  tile_height = "
     //      << tile_height << endl;
 
-    xrange = (int)(vis / tile_width) + 1;
-    yrange = (int)(vis / tile_height) + 1;
+    double tileRangeM = min(vis,_maxTileRangeM->getDoubleValue());
+    xrange = (int)(tileRangeM / tile_width) + 1;
+    yrange = (int)(tileRangeM / tile_height) + 1;
     if ( xrange < 1 ) { xrange = 1; }
     if ( yrange < 1 ) { yrange = 1; }
 
@@ -265,7 +315,8 @@ void FGTileMgr::update_queues()
             e->prep_ssg_node(vis);
 
             if (( !e->is_loaded() )&&
-                ( !e->is_expired(current_time) ))
+                ((!e->is_expired(current_time))||
+                  e->is_current_view() ))
             {
                 // schedule tile for loading with osg pager
                 pager->queueRequest(e->tileFileName,
@@ -278,7 +329,7 @@ void FGTileMgr::update_queues()
             }
         } else
         {
-            SG_LOG(SG_INPUT, SG_ALERT, "warning ... empty tile in cache");
+            SG_LOG(SG_INPUT, SG_ALERT, "Warning: empty tile in cache!");
         }
         tile_cache.next();
         sz++;
@@ -344,7 +395,7 @@ int FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m)
     //         << current_bucket );
     fgSetInt( "/environment/current-tile-id", current_bucket.gen_index() );
 
-    // do tile load scheduling. 
+    // do tile load scheduling.
     // Note that we need keep track of both viewer buckets and fdm buckets.
     if ( state == Running ) {
         SG_LOG( SG_TERRAIN, SG_DEBUG, "State == Running" );
@@ -354,6 +405,8 @@ int FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m)
             SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" );
             scheduled_visibility = range_m;
             schedule_needed(current_bucket, range_m);
+            if (_terra_sync)
+                _terra_sync->schedulePosition(latitude,longitude);
         }
         // save bucket
         previous_bucket = current_bucket;