]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scenery/tilemgr.cxx
Tweaks ...
[flightgear.git] / src / Scenery / tilemgr.cxx
index 2f71d6bff73ae270499d85c233f7c0b1356bea68..77f6c745ef284a7823b95f0cfe3d3ff444b22995 100644 (file)
@@ -39,7 +39,7 @@
 #include <simgear/math/polar3d.hxx>
 #include <simgear/math/vector.hxx>
 
-#include <Aircraft/aircraft.hxx>
+// #include <Aircraft/aircraft.hxx>
 #include <Main/options.hxx>
 #include <Main/views.hxx>
 #include <Objects/obj.hxx>
@@ -86,13 +86,20 @@ FGTileMgr::~FGTileMgr ( void ) {
 int FGTileMgr::init( void ) {
     FG_LOG( FG_TERRAIN, FG_INFO, "Initializing Tile Manager subsystem." );
 
+    if ( state != Start ) {
+       FG_LOG( FG_TERRAIN, FG_INFO,
+               "... Reinitializing." );
+       destroy_queue();
+    } else {
+       FG_LOG( FG_TERRAIN, FG_INFO,
+               "... First time through." );
+    }
+
     global_tile_cache.init();
     hit_list.clear();
 
     state = Inited;
 
-    // last_hit = 0;
-
     tile_diameter = current_options.get_tile_diameter();
     FG_LOG( FG_TERRAIN, FG_INFO, "Tile Diameter = " << tile_diameter);
     
@@ -108,15 +115,6 @@ int FGTileMgr::init( void ) {
     return 1;
 }
 
-#if 0
-// schedule a tile for loading
-static void disable_tile( int cache_index ) {
-    // see if tile already exists in the cache
-    // cout << "DISABLING CACHE ENTRY = " << cache_index << endl;
-    FGTileEntry *t = global_tile_cache.get_tile( cache_index );
-    t->ssg_disable();
-}
-#endif
 
 // schedule a tile for loading
 int FGTileMgr::sched_tile( const FGBucket& b ) {
@@ -151,9 +149,7 @@ int FGTileMgr::sched_tile( const FGBucket& b ) {
 void FGTileMgr::load_tile( const FGBucket& b, int cache_index) {
 
     FG_LOG( FG_TERRAIN, FG_DEBUG, "Loading tile " << b );
-
     global_tile_cache.fill_in(cache_index, b);
-
     FG_LOG( FG_TERRAIN, FG_DEBUG, "Loaded for cache index: " << cache_index );
 }
 
@@ -194,7 +190,13 @@ FGTileMgr::current_elev_ssg( const Point3D& abs_view_pos,
     if ( result > -9000 ) {
        scenery.cur_elev = result;
        scenery.cur_radius = geoc.radius();
-       sgdCopyVec3(scenery.cur_normal, hit_list.get_normal(this_hit));
+       sgVec3 tmp;
+       sgSetVec3(tmp, hit_list.get_normal(this_hit));
+       ssgState *IntersectedLeafState =
+           ((ssgLeaf*)hit_list.get_entity(this_hit))->getState();
+       current_view.CurrentNormalInLocalPlane(tmp, tmp);
+       sgdSetVec3( scenery.cur_normal, tmp );
+       // cout << "NED: " << tmp[0] << " " << tmp[1] << " " << tmp[2] << endl;
        return true;
     } else {
        FG_LOG( FG_TERRAIN, FG_INFO, "no terrain intersection" );
@@ -210,11 +212,9 @@ FGBucket FGTileMgr::BucketOffset( int dx, int dy )
 {
     double clat, clon, span;
     if( scroll_direction == SCROLL_INIT ) {
-       pending.set_bucket( longitude, latitude );
-       clat = pending.get_center_lat() + dy * FG_BUCKET_SPAN;
-
+       // use current latitude and longitude
        // walk dy units in the lat direction
-       pending.set_bucket( longitude, clat );
+       clat = current_bucket.get_center_lat() + dy * FG_BUCKET_SPAN;
 
        // find the lon span for the new latitude
        span = bucket_span( clat );
@@ -222,11 +222,9 @@ FGBucket FGTileMgr::BucketOffset( int dx, int dy )
        // walk dx units in the lon direction
        clon = longitude + dx * span;
     } else     {
-       pending.set_bucket( last_longitude, last_latitude );
-       clat = pending.get_center_lat() + dy * FG_BUCKET_SPAN;
-
+       // use previous latitude and longitude
        // walk dy units in the lat direction
-       pending.set_bucket( last_longitude, clat );
+       clat = previous_bucket.get_center_lat() + dy * FG_BUCKET_SPAN;
 
        // find the lon span for the new latitude
        span = bucket_span( clat );
@@ -258,7 +256,7 @@ void FGTileMgr::scroll( void )
        dw = tile_diameter / 2;
        dh = dw + 1;
        for ( i = 0; i < tile_diameter; i++ ) {
-           sched_tile( BucketOffset( i - dw, dh) );
+           sched_tile( BucketOffset( i - dw, dh ) );
        }
        break;
     case SCROLL_EAST:
@@ -271,19 +269,19 @@ void FGTileMgr::scroll( void )
        }
        break;
     case SCROLL_SOUTH:
-       dw = tile_diameter / 2;
-       dh = -dw - 1;
        FG_LOG( FG_TERRAIN, FG_DEBUG, 
                "  (South) Loading " << tile_diameter << " tiles" );
+       dw = tile_diameter / 2;
+       dh = -dw - 1;
        for ( i = 0; i < tile_diameter; i++ ) {
-           sched_tile( BucketOffset( i - dw, dh) );
+           sched_tile( BucketOffset( i - dw, dh ) );
        }
        break;
     case SCROLL_WEST:
-       dh = tile_diameter / 2;
-       dw = -dh - 1;
        FG_LOG( FG_TERRAIN, FG_DEBUG, 
                "  (West) Loading " << tile_diameter << " tiles" );
+       dh = tile_diameter / 2;
+       dw = -dh - 1;
        for ( i = 0; i < tile_diameter; i++ ) {
            sched_tile( BucketOffset( dw, i - dh ) );
        }
@@ -296,13 +294,12 @@ void FGTileMgr::scroll( void )
 }
 
 
-void FGTileMgr::initialize_queue( void )
+void FGTileMgr::initialize_queue()
 {
     // First time through or we have teleported, initialize the
     // system and load all relavant tiles
 
     FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << current_bucket );
-    FG_LOG( FG_TERRAIN, FG_INFO, "  First time through ... " );
     FG_LOG( FG_TERRAIN, FG_INFO, "  Updating Tile list for " << current_bucket );
     FG_LOG( FG_TERRAIN, FG_INFO, "  Loading " 
             << tile_diameter * tile_diameter << " tiles" );
@@ -320,12 +317,6 @@ void FGTileMgr::initialize_queue( void )
     // "rings"
 
     sched_tile( current_bucket );
-    Point3D geod_view_center( current_bucket.get_center_lon(), 
-                              current_bucket.get_center_lat(), 
-                              cur_fdm_state->get_Altitude()*FEET_TO_METER + 3 );
-
-    current_view.abs_view_pos = fgGeodToCart( geod_view_center );
-    current_view.view_pos = current_view.abs_view_pos - scenery.next_center;
 
     for ( i = 3; i <= tile_diameter; i = i + 2 ) {
         int j;
@@ -364,16 +355,40 @@ void FGTileMgr::initialize_queue( void )
 }
 
 
-// given the current lon/lat, fill in the array of local chunks.  If
-// the chunk isn't already in the cache, then read it from disk.
-int FGTileMgr::update( double junk1, double junk2 ) {
+// forced emptying of the queue
+// This is necessay to keep bookeeping straight for the
+// tile_cache   -- which actually handles all the
+// (de)allocations  
+void FGTileMgr::destroy_queue() {
+    while( load_queue.size() ) {
+       FG_LOG( FG_TERRAIN, FG_INFO, 
+               "Load queue not empty, popping a tile" );
+       FGLoadRec pending = load_queue.front();
+       load_queue.pop_front();
+        FGTileEntry *t = global_tile_cache.get_tile( pending.cache_index );
+       // just t->mark_unused() should be enough
+       // but a little paranoia doesn't hurt us here
+       if(t->is_scheduled_for_use())
+           t->mark_unused();
+       else
+           load_tile( pending.b, pending.cache_index );
+    }
+}
+
+
+// given the current lon/lat (in degrees), fill in the array of local
+// chunks.  If the chunk isn't already in the cache, then read it from
+// disk.
+int FGTileMgr::update( double lon, double lat ) {
     // FG_LOG( FG_TERRAIN, FG_DEBUG, "FGTileMgr::update()" );
 
-    FGInterface *f = current_aircraft.fdm_state;
+    // FGInterface *f = current_aircraft.fdm_state;
 
     // lonlat for this update 
-    longitude = f->get_Longitude() * RAD_TO_DEG;
-    latitude = f->get_Latitude() * RAD_TO_DEG;
+    // longitude = f->get_Longitude() * RAD_TO_DEG;
+    // latitude = f->get_Latitude() * RAD_TO_DEG;
+    longitude = lon;
+    latitude = lat;
     // FG_LOG( FG_TERRAIN, FG_DEBUG, "lon "<< lonlat[LON] <<
     //      " lat " << lonlat[LAT] );
 
@@ -387,7 +402,7 @@ int FGTileMgr::update( double junk1, double junk2 ) {
         current_tile = global_tile_cache.get_tile(tile_index);
         scenery.next_center = current_tile->center;
     } else {
-        FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found" );
+        FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found (Ok if initializing)" );
     }
 
     if ( state == Running ) {
@@ -430,7 +445,7 @@ int FGTileMgr::update( double junk1, double junk2 ) {
            scroll();
        }
 
-    } else if ( (state == Start) || (state == Inited) ) {
+    } else if ( state == Start || state == Inited ) {
        initialize_queue();
        state = Running;
     }
@@ -443,19 +458,25 @@ int FGTileMgr::update( double junk1, double junk2 ) {
        load_tile( pending.b, pending.cache_index );
     }
 
-    // find our current elevation (feed in the current bucket to save work)
-    // Point3D geod_pos = Point3D( f->get_Longitude(), f->get_Latitude(), 0.0);
-    // Point3D tmp_abs_view_pos = fgGeodToCart(geod_pos);
-
-    // cout << "current elevation (old) == " 
-    //      << current_elev( f->get_Longitude(), f->get_Latitude(), 
-    //                       tmp_abs_view_pos ) 
-    //      << endl;
-
-    // set scenery.cur_elev and scenery.cur_radius
+    if ( scenery.center == Point3D(0.0) ) {
+       // initializing
+       // cout << "initializing ... " << endl;
+       Point3D geod_pos = Point3D( longitude * DEG_TO_RAD,
+                                   latitude * DEG_TO_RAD,
+                                   0.0);
+       Point3D tmp_abs_view_pos = fgGeodToCart( geod_pos );
+       scenery.center = tmp_abs_view_pos;
+       // cout << "abs_view_pos = " << tmp_abs_view_pos << endl;
+       prep_ssg_nodes();
+       current_elev_ssg( tmp_abs_view_pos,
+                         Point3D( 0.0 ) );
+    } else {
+       // cout << "abs view pos = " << current_view.abs_view_pos
+       //      << " view pos = " << current_view.view_pos << endl;
+       current_elev_ssg( current_view.abs_view_pos,
+                         current_view.view_pos );
+    }
 
-    current_elev_ssg( current_view.abs_view_pos,
-                      current_view.view_pos );
     // cout << "current elevation (ssg) == " << scenery.cur_elev << endl;
 
     previous_bucket = current_bucket;
@@ -475,6 +496,18 @@ void FGTileMgr::prep_ssg_nodes( void ) {
     FGTileEntry *t;
     float ranges[2];
     ranges[0] = 0.0f;
+    double vis = 0.0;
+
+#ifndef FG_OLD_WEATHER
+    if ( WeatherDatabase != NULL ) {
+       vis = WeatherDatabase->getWeatherVisibility();
+    } else {
+       vis = 16000;
+    }
+#else
+    vis = current_weather.get_visibility();
+#endif
+    // cout << "visibility = " << vis << endl;
 
     // traverse the potentially viewable tile list and update range
     // selector and transform
@@ -485,12 +518,7 @@ void FGTileMgr::prep_ssg_nodes( void ) {
            // set range selector (LOD trick) to be distance to center
            // of tile + bounding radius
 
-#ifndef FG_OLD_WEATHER
-            ranges[1] = WeatherDatabase->getWeatherVisibility()
-               + t->bounding_radius;
-#else
-            ranges[1] = current_weather.get_visibility()+t->bounding_radius;
-#endif
+            ranges[1] = vis + t->bounding_radius;
             t->range_ptr->setRanges( ranges, 2 );
 
             // calculate tile offset