From 8d58f642575718f4e5b7ddd480a8c1e86333cfab Mon Sep 17 00:00:00 2001 From: curt Date: Sun, 25 Jul 1999 01:52:36 +0000 Subject: [PATCH] Fixed a tile caching bug. When I was freeing tiles to make room in the cache, I was only checking currently visible tiles, rather than checking all the cache entries. --- src/Main/main.cxx | 2 +- src/Scenery/tilecache.cxx | 42 +++++++++++++++++++++++++++++---------- src/Scenery/tileentry.cxx | 18 +++++++++++++---- src/Scenery/tileentry.hxx | 1 + src/Scenery/tilemgr.cxx | 12 +++++------ 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 2274becd2..894294f6c 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -500,7 +500,7 @@ void fgUpdateTimeDepCalcs(int multi_loop, int remainder) { // printf("updating flight model x %d\n", multi_loop); fgFDMUpdate( current_options.get_flight_model(), - cur_fdm_state, multi_loop, remainder ); + cur_fdm_state, multi_loop * 1, remainder ); } else { fgFDMUpdate( current_options.get_flight_model(), cur_fdm_state, 0, remainder ); diff --git a/src/Scenery/tilecache.cxx b/src/Scenery/tilecache.cxx index 1e0411d22..f60bad41b 100644 --- a/src/Scenery/tilecache.cxx +++ b/src/Scenery/tilecache.cxx @@ -129,7 +129,14 @@ FGTileCache::exists( const FGBucket& p ) void FGTileCache::fill_in( int index, const FGBucket& p ) { - // cout << "FILL IN CACHE ENTRY = " << index << endl; + cout << "FILL IN CACHE ENTRY = " << index << endl; + + // Force some values in case the tile fails to load (i.e. fill + // doesn't exist) + tile_cache[index].center = Point3D( 0.0 ); + tile_cache[index].vtlist = NULL; + tile_cache[index].vnlist = NULL; + tile_cache[index].tclist = NULL; // Load the appropriate data file and build tile fragment list FGPath tile_path( current_options.get_fg_root() ); @@ -152,13 +159,13 @@ FGTileCache::fill_in( int index, const FGBucket& p ) terrain->addKid( tile_cache[index].select_ptr ); if ( tile_cache[index].is_scheduled_for_cache() ) { - // cout << "FOUND ONE SCHEDULED FOR CACHE" << endl; + cout << "FOUND ONE SCHEDULED FOR CACHE" << endl; // load, but not needed now so disable tile_cache[index].mark_loaded(); tile_cache[index].ssg_disable(); tile_cache[index].select_ptr->select(0); } else { - // cout << "FOUND ONE READY TO LOAD" << endl; + cout << "FOUND ONE READY TO LOAD" << endl; tile_cache[index].mark_loaded(); tile_cache[index].select_ptr->select(1); } @@ -167,9 +174,10 @@ FGTileCache::fill_in( int index, const FGBucket& p ) // Free a tile cache entry void -FGTileCache::entry_free( int index ) +FGTileCache::entry_free( int cache_index ) { - tile_cache[index].free_tile(); + cout << "FREEING CACHE ENTRY = " << cache_index << endl; + tile_cache[cache_index].free_tile(); } @@ -177,9 +185,10 @@ FGTileCache::entry_free( int index ) int FGTileCache::next_avail( void ) { - Point3D delta, abs_view_pos; + // Point3D delta; + Point3D abs_view_pos; int i; - float max, med, min, tmp; + // float max, med, min, tmp; float dist, max_dist; int max_index; @@ -194,7 +203,7 @@ FGTileCache::next_avail( void ) if ( tile_cache[i].is_unused() ) { // favor unused cache slots return(i); - } else if ( tile_cache[i].is_loaded() ) { + } else if ( tile_cache[i].is_loaded() || tile_cache[i].is_cached() ) { // calculate approximate distance from view point abs_view_pos = current_view.get_abs_view_pos(); @@ -203,6 +212,7 @@ FGTileCache::next_avail( void ) FG_LOG( FG_TERRAIN, FG_DEBUG, " ref point = " << tile_cache[i].center ); + /* delta.setx( fabs(tile_cache[i].center.x() - abs_view_pos.x() ) ); delta.sety( fabs(tile_cache[i].center.y() - abs_view_pos.y() ) ); delta.setz( fabs(tile_cache[i].center.z() - abs_view_pos.z() ) ); @@ -215,6 +225,9 @@ FGTileCache::next_avail( void ) tmp = max; max = min; min = tmp; } dist = max + (med + min) / 4; + */ + + dist = tile_cache[i].center.distance3D( abs_view_pos ); FG_LOG( FG_TERRAIN, FG_DEBUG, " distance = " << dist ); @@ -228,9 +241,16 @@ FGTileCache::next_avail( void ) // If we made it this far, then there were no open cache entries. // We will instead free the furthest cache entry and return it's // index. - - entry_free( max_index ); - return( max_index ); + + if ( max_index >=0 ) { + FG_LOG( FG_TERRAIN, FG_INFO, " max_dist = " << max_dist ); + FG_LOG( FG_TERRAIN, FG_INFO, " index = " << max_index ); + entry_free( max_index ); + return( max_index ); + } else { + FG_LOG( FG_TERRAIN, FG_ALERT, "WHOOPS!!! Dying in next_avail()" ); + exit( -1 ); + } } diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index bd246f1e9..bb22bd15f 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -64,24 +64,34 @@ FGTileEntry::~FGTileEntry ( void ) { void FGTileEntry::free_tile() { - FG_LOG( FG_TERRAIN, FG_DEBUG, + FG_LOG( FG_TERRAIN, FG_INFO, "FREEING TILE = (" << tile_bucket << ")" ); // mark tile unused mark_unused(); // delete fragment list + FG_LOG( FG_TERRAIN, FG_INFO, + " deleting " << fragment_list.size() << " fragments" ); for_each( begin(), end(), mem_fun_ref( &fgFRAGMENT::deleteDisplayList )); fragment_list.erase( begin(), end() ); // delete the ssg used structures + FG_LOG( FG_TERRAIN, FG_INFO, + " deleting vertex, normal, and texture coordinate arrays" ); + FG_LOG( FG_TERRAIN, FG_INFO, + " deleting vertex array" ); if ( vtlist != NULL ) { delete vtlist; } + FG_LOG( FG_TERRAIN, FG_INFO, + " deleting normal array" ); if ( vnlist != NULL ) { delete vnlist; } + FG_LOG( FG_TERRAIN, FG_INFO, + " deleting texture coordinate array" ); if ( tclist != NULL ) { delete tclist; } @@ -123,12 +133,12 @@ FGTileEntry::free_tile() // selector to disable it from ever being drawn. void FGTileEntry::ssg_disable() { - // cout << "TILE STATE = " << state << endl; + cout << "TILE STATE = " << state << endl; if ( state == Scheduled_for_use ) { state = Scheduled_for_cache; } else if ( (state == Loaded) || (state == Cached) ) { state = Cached; - // cout << "DISABLING SSG NODE" << endl; + cout << "DISABLING SSG NODE" << endl; select_ptr->select(0); #if 0 @@ -150,5 +160,5 @@ FGTileEntry::ssg_disable() { "Trying to disable an unused tile! Dying" ); exit(-1); } - // cout << "TILE STATE = " << state << endl; + cout << "TILE STATE = " << state << endl; } diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 8a5ec4c0a..aaa9088a8 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -202,6 +202,7 @@ public: return state == Scheduled_for_cache; } inline bool is_loaded() const { return state == Loaded; } + inline bool is_cached() const { return state == Cached; } inline void mark_unused() { state = Unused; } inline void mark_scheduled_for_use() { state = Scheduled_for_use; } diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 6e315a41e..4a07fc7b1 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -98,7 +98,7 @@ int FGTileMgr::init( void ) { // 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; + cout << "DISABLING CACHE ENTRY = " << cache_index << endl; FGTileEntry *t = global_tile_cache.get_tile( cache_index ); t->ssg_disable(); } @@ -111,7 +111,7 @@ int FGTileMgr::sched_tile( const FGBucket& b ) { if ( cache_index >= 0 ) { // tile exists in cache, reenable it. - // cout << "REENABLING DISABLED TILE" << endl; + cout << "REENABLING DISABLED TILE" << endl; FGTileEntry *t = global_tile_cache.get_tile( cache_index ); t->select_ptr->select( 1 ); t->mark_loaded(); @@ -528,7 +528,7 @@ int FGTileMgr::update( void ) { if ( (p1.get_lon() > p_last.get_lon()) || ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) { FG_LOG( FG_TERRAIN, FG_INFO, - " Loading " << tile_diameter << " tiles" ); + " (East) Loading " << tile_diameter << " tiles" ); for ( j = 0; j < tile_diameter; j++ ) { // scrolling East disable_tile( tiles[(j*tile_diameter) + 0] ); @@ -544,7 +544,7 @@ int FGTileMgr::update( void ) { ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() < p_last.get_x()) ) ) { FG_LOG( FG_TERRAIN, FG_INFO, - " Loading " << tile_diameter << " tiles" ); + " (West) Loading " << tile_diameter << " tiles" ); for ( j = 0; j < tile_diameter; j++ ) { // scrolling West disable_tile( tiles[(j*tile_diameter) + tile_diameter - 1] ); @@ -561,7 +561,7 @@ int FGTileMgr::update( void ) { if ( (p1.get_lat() > p_last.get_lat()) || ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) { FG_LOG( FG_TERRAIN, FG_INFO, - " Loading " << tile_diameter << " tiles" ); + " (North) Loading " << tile_diameter << " tiles" ); for ( i = 0; i < tile_diameter; i++ ) { // scrolling North disable_tile( tiles[0 + i] ); @@ -577,7 +577,7 @@ int FGTileMgr::update( void ) { } else if ( (p1.get_lat() < p_last.get_lat()) || ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) { FG_LOG( FG_TERRAIN, FG_INFO, - " Loading " << tile_diameter << " tiles" ); + " (South) Loading " << tile_diameter << " tiles" ); for ( i = 0; i < tile_diameter; i++ ) { // scrolling South disable_tile( tiles[((tile_diameter-1) * tile_diameter) + i] );