1
0
Fork 0

(Hopefully) fixed bug which caused corrupt entries to be loaded into the

scene graph when a tile shift occured while the tile load queue was not
  empty.
This commit is contained in:
curt 1999-07-04 07:37:30 +00:00
parent 6efea97fb0
commit e5a87cf9fa
5 changed files with 194 additions and 62 deletions

View file

@ -129,34 +129,39 @@ FGTileCache::exists( const FGBucket& p )
void void
FGTileCache::fill_in( int index, const FGBucket& p ) FGTileCache::fill_in( int index, const FGBucket& p )
{ {
// cout << "FILL IN CACHE ENTRY = " << index << endl;
// Load the appropriate data file and build tile fragment list // Load the appropriate data file and build tile fragment list
FGPath tile_path( current_options.get_fg_root() ); FGPath tile_path( current_options.get_fg_root() );
tile_path.append( "Scenery" ); tile_path.append( "Scenery" );
tile_path.append( p.gen_base_path() ); tile_path.append( p.gen_base_path() );
tile_path.append( p.gen_index_str() ); tile_path.append( p.gen_index_str() );
tile_cache[index].mark_loaded();
tile_cache[index].tile_bucket = p; tile_cache[index].tile_bucket = p;
tile_cache[index].branch_ptr = new ssgTransform;
tile_cache[index].select_ptr = new ssgSelector;
tile_cache[index].transform_ptr = new ssgTransform;
tile_cache[index].range_ptr = new ssgRangeSelector; tile_cache[index].range_ptr = new ssgRangeSelector;
ssgBranch *new_tile = fgObjLoad( tile_path.str(), &tile_cache[index] ); ssgBranch *new_tile = fgObjLoad( tile_path.str(), &tile_cache[index] );
if ( new_tile != NULL ) { if ( new_tile != NULL ) {
tile_cache[index].range_ptr->addKid( new_tile ); tile_cache[index].range_ptr->addKid( new_tile );
} }
tile_cache[index].branch_ptr->addKid( tile_cache[index].range_ptr ); tile_cache[index].transform_ptr->addKid( tile_cache[index].range_ptr );
terrain->addKid( tile_cache[index].branch_ptr ); tile_cache[index].select_ptr->addKid( tile_cache[index].transform_ptr );
terrain->addKid( tile_cache[index].select_ptr );
// cout << " ncount before = " << tile_cache[index].ncount << "\n"; if ( tile_cache[index].is_scheduled_for_cache() ) {
// cout << " fragments before = " << tile_cache[index].fragment_list.size() // cout << "FOUND ONE SCHEDULED FOR CACHE" << endl;
// << "\n"; // load, but not needed now so disable
tile_cache[index].mark_loaded();
string apt_path = tile_path.str(); tile_cache[index].ssg_disable();
apt_path += ".apt"; tile_cache[index].select_ptr->select(0);
fgAptGenerate( apt_path, &tile_cache[index] ); } else {
// cout << "FOUND ONE READY TO LOAD" << endl;
// cout << " ncount after = " << tile_cache[index].ncount << "\n"; tile_cache[index].mark_loaded();
// cout << " fragments after = " << tile_cache[index].fragment_list.size() tile_cache[index].select_ptr->select(1);
// << "\n"; }
} }

View file

@ -89,17 +89,17 @@ FGTileEntry::free_tile()
// delete the ssg branch // delete the ssg branch
// make sure we have a sane number of parents // make sure we have a sane number of parents
int pcount = branch_ptr->getNumParents(); int pcount = select_ptr->getNumParents();
if ( pcount > 0 ) { if ( pcount > 0 ) {
// find the first parent (should only be one) // find the first parent (should only be one)
ssgBranch *parent = branch_ptr->getParent( 0 ) ; ssgBranch *parent = select_ptr->getParent( 0 ) ;
// find the number of kids this parent has // find the number of kids this parent has
int kcount = parent->getNumKids(); int kcount = parent->getNumKids();
// find the kid that matches our original branch_ptr // find the kid that matches our original select_ptr
bool found_kid = false; bool found_kid = false;
for ( int i = 0; i < kcount; ++i ) { for ( int i = 0; i < kcount; ++i ) {
ssgEntity *kid = parent->getKid( i ); ssgEntity *kid = parent->getKid( i );
if ( kid == branch_ptr ) { if ( kid == select_ptr ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
"Found a kid to delete " << kid); "Found a kid to delete " << kid);
found_kid = true; found_kid = true;
@ -118,3 +118,37 @@ FGTileEntry::free_tile()
} }
// when a tile is still in the cache, but not in the immediate draw l
// ist, it can still remain in the scene graph, but we use a range
// selector to disable it from ever being drawn.
void
FGTileEntry::ssg_disable() {
// 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;
select_ptr->select(0);
#if 0
// set a really tiny range
// cout << "SETTING TINY RANGE" << endl;
float ranges[2];
ranges[0] = 0.0f;
ranges[1] = 0.00001f;
range_ptr->setRanges( ranges, 2 );
// transform to a long way away
// cout << "MOVING FAR AWAY" << endl;
sgCoord sgcoord;
sgSetCoord( &sgcoord, 999999.0, 999999.0, 999999.0, 0.0, 0.0, 0.0 );
transform_ptr->setTransform( &sgcoord );
#endif
} else {
FG_LOG( FG_TERRAIN, FG_ALERT,
"Trying to disable an unused tile! Dying" );
exit(-1);
}
// cout << "TILE STATE = " << state << endl;
}

View file

@ -73,8 +73,10 @@ private:
// Tile state // Tile state
enum tile_state { enum tile_state {
Unused = 0, Unused = 0,
Scheduled = 1, Scheduled_for_use = 1,
Loaded = 2 Scheduled_for_cache = 2,
Loaded = 3,
Cached = 4
}; };
public: public:
@ -112,6 +114,7 @@ public:
// ssg tree structure for this tile is as follows: // ssg tree structure for this tile is as follows:
// ssgRoot(scene) // ssgRoot(scene)
// - ssgBranch(terrain) // - ssgBranch(terrain)
// - ssgSelector(tile)
// - ssgTransform(tile) // - ssgTransform(tile)
// - ssgRangeSelector(tile) // - ssgRangeSelector(tile)
// - ssgEntity(tile) // - ssgEntity(tile)
@ -120,11 +123,14 @@ public:
// ... // ...
// - kidn(fan) // - kidn(fan)
// pointer to ssg range selector for this tile // selector (turn tile on/off)
ssgRangeSelector *range_ptr; ssgSelector *select_ptr;
// pointer to ssg transform for this tile // pointer to ssg transform for this tile
ssgTransform *branch_ptr; ssgTransform *transform_ptr;
// pointer to ssg range selector for this tile
ssgRangeSelector *range_ptr;
public: public:
@ -189,11 +195,24 @@ public:
} }
inline bool is_unused() const { return state == Unused; } inline bool is_unused() const { return state == Unused; }
inline bool is_scheduled_for_use() const {
return state == Scheduled_for_use;
}
inline bool is_scheduled_for_cache() const {
return state == Scheduled_for_cache;
}
inline bool is_loaded() const { return state == Loaded; } inline bool is_loaded() const { return state == Loaded; }
inline void mark_unused() { state = Unused; } inline void mark_unused() { state = Unused; }
inline void mark_scheduled() { state = Scheduled; } inline void mark_scheduled_for_use() { state = Scheduled_for_use; }
inline void mark_scheduled_for_cache() { state = Scheduled_for_use; }
inline void mark_loaded() { state = Loaded; } inline void mark_loaded() { state = Loaded; }
// when a tile is still in the cache, but not in the immediate
// draw l ist, it can still remain in the scene graph, but we use
// a range selector to disable it from ever being drawn.
void ssg_disable();
}; };

View file

@ -61,6 +61,9 @@
#endif #endif
extern ssgRoot *scene;
// the tile manager // the tile manager
FGTileMgr global_tile_mgr; FGTileMgr global_tile_mgr;
@ -93,21 +96,40 @@ int FGTileMgr::init( void ) {
// schedule a tile for loading // schedule a tile for loading
void FGTileMgr::sched_tile( const FGBucket& b, int *index ) { static void disable_tile( int cache_index ) {
// see if tile already exists in the cache // see if tile already exists in the cache
*index = global_tile_cache.exists( b ); // cout << "DISABLING CACHE ENTRY = " << cache_index << endl;
if ( *index < 0 ) { FGTileEntry *t = global_tile_cache.get_tile( cache_index );
// find the next availabel cache entry and mark it as scheduled t->ssg_disable();
*index = global_tile_cache.next_avail(); }
FGTileEntry *t = global_tile_cache.get_tile( *index );
t->mark_scheduled();
// schedule a tile for loading
int FGTileMgr::sched_tile( const FGBucket& b ) {
// see if tile already exists in the cache
int cache_index = global_tile_cache.exists( b );
if ( cache_index >= 0 ) {
// tile exists in cache, reenable it.
// cout << "REENABLING DISABLED TILE" << endl;
FGTileEntry *t = global_tile_cache.get_tile( cache_index );
t->select_ptr->select( 1 );
t->mark_loaded();
} else {
// find the next available cache entry and mark it as
// scheduled
cache_index = global_tile_cache.next_avail();
FGTileEntry *t = global_tile_cache.get_tile( cache_index );
t->mark_scheduled_for_use();
// register a load request // register a load request
FGLoadRec request; FGLoadRec request;
request.b = b; request.b = b;
request.index = *index; request.cache_index = cache_index;
load_queue.push_back( request ); load_queue.push_back( request );
} }
return cache_index;
} }
@ -340,6 +362,40 @@ FGTileMgr::current_elev( double lon, double lat, const Point3D& abs_view_pos ) {
} }
// Determine scenery altitude via ssg. Normally this just happens
// when we render the scene, but we'd also like to be able to do this
// explicitely. lat & lon are in radians. view_pos in current world
// coordinate translated near (0,0,0) (in meters.) Returns result in
// meters.
double
FGTileMgr::current_elev_ssg( const Point3D& abs_view_pos,
const Point3D& view_pos )
{
ssgHit *results ;
// cout << "view pos = " << view_pos << endl;
// cout << "abs view pos = " << abs_view_pos << endl;
sgMat4 m;
sgMakeTransMat4( m, view_pos.x(), view_pos.y(), view_pos.z() );
sgVec3 s;
sgSetVec3(s, -abs_view_pos.x(), -abs_view_pos.y(), -abs_view_pos.z() );
int num_hits = ssgLOS ( scene, s, m, &results ) ;
for ( int i = 0 ; i < num_hits ; i++ ) {
ssgHit *h = &(results [ i ]) ;
cout << "got a hit!" << endl;
/* Do something with 'h' */
}
FG_LOG( FG_TERRAIN, FG_INFO, "(ssg) no terrain intersection found" );
return 0.0;
}
// given the current lon/lat, fill in the array of local chunks. If // 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. // the chunk isn't already in the cache, then read it from disk.
int FGTileMgr::update( void ) { int FGTileMgr::update( void ) {
@ -368,7 +424,7 @@ int FGTileMgr::update( void ) {
} else if ( (state == Start) || (state == Inited) ) { } else if ( (state == Start) || (state == Inited) ) {
state = Running; state = Running;
// First time through or we have teleporte, initialize the // First time through or we have teleported, initialize the
// system and load all relavant tiles // system and load all relavant tiles
FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << p1 ); FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << p1 );
@ -389,7 +445,7 @@ int FGTileMgr::update( void ) {
p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG, p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
f->get_Latitude() * RAD_TO_DEG, f->get_Latitude() * RAD_TO_DEG,
0, 0 ); 0, 0 );
sched_tile( p2, &tiles[(dh*tile_diameter) + dw]); tiles[(dh*tile_diameter) + dw] = sched_tile( p2 );
for ( i = 3; i <= tile_diameter; i = i + 2 ) { for ( i = 3; i <= tile_diameter; i = i + 2 ) {
int span = i / 2; int span = i / 2;
@ -399,7 +455,7 @@ int FGTileMgr::update( void ) {
p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG, p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
f->get_Latitude() * RAD_TO_DEG, f->get_Latitude() * RAD_TO_DEG,
j, -span ); j, -span );
sched_tile( p2, &tiles[((dh-span)*tile_diameter) + dw+j]); tiles[((dh-span)*tile_diameter) + dw+j] = sched_tile( p2 );
} }
// top row // top row
@ -407,7 +463,7 @@ int FGTileMgr::update( void ) {
p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG, p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
f->get_Latitude() * RAD_TO_DEG, f->get_Latitude() * RAD_TO_DEG,
j, span ); j, span );
sched_tile( p2, &tiles[((dh+span)*tile_diameter) + dw+j]); tiles[((dh+span)*tile_diameter) + dw+j] = sched_tile( p2 );
} }
// middle rows // middle rows
@ -415,11 +471,11 @@ int FGTileMgr::update( void ) {
p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG, p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
f->get_Latitude() * RAD_TO_DEG, f->get_Latitude() * RAD_TO_DEG,
-span, j ); -span, j );
sched_tile( p2, &tiles[((dh+j)*tile_diameter) + dw-span]); tiles[((dh+j)*tile_diameter) + dw-span] = sched_tile( p2 );
p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG, p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
f->get_Latitude() * RAD_TO_DEG, f->get_Latitude() * RAD_TO_DEG,
span, j ); span, j );
sched_tile( p2, &tiles[((dh+j)*tile_diameter) + dw+span]); tiles[((dh+j)*tile_diameter) + dw+span] = sched_tile( p2 );
} }
} }
@ -430,7 +486,7 @@ int FGTileMgr::update( void ) {
p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG, p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
f->get_Latitude() * RAD_TO_DEG, f->get_Latitude() * RAD_TO_DEG,
i - dw, j -dh ); i - dw, j -dh );
sched_tile( p2, &tiles[(j*tile_diameter) + i]); tiles[(j*tile_diameter) + i] = sched_tile( p2 );
} }
} */ } */
@ -443,7 +499,7 @@ int FGTileMgr::update( void ) {
FGLoadRec pending = load_queue.front(); FGLoadRec pending = load_queue.front();
load_queue.pop_front(); load_queue.pop_front();
load_tile( pending.b, pending.index ); load_tile( pending.b, pending.cache_index );
} }
} }
@ -451,6 +507,18 @@ int FGTileMgr::update( void ) {
// We've moved to a new bucket, we need to scroll our // We've moved to a new bucket, we need to scroll our
// structures, and load in the new tiles // structures, and load in the new tiles
#if 0
// make sure load queue is flushed before doing shift
while ( load_queue.size() ) {
FG_LOG( FG_TERRAIN, FG_INFO,
"Load queue not empty, flushing queue before tile shift." );
FGLoadRec pending = load_queue.front();
load_queue.pop_front();
load_tile( pending.b, pending.index );
}
#endif
// CURRENTLY THIS ASSUMES WE CAN ONLY MOVE TO ADJACENT TILES. // CURRENTLY THIS ASSUMES WE CAN ONLY MOVE TO ADJACENT TILES.
// AT ULTRA HIGH SPEEDS THIS ASSUMPTION MAY NOT BE VALID IF // AT ULTRA HIGH SPEEDS THIS ASSUMPTION MAY NOT BE VALID IF
// THE AIRCRAFT CAN SKIP A TILE IN A SINGLE ITERATION. // THE AIRCRAFT CAN SKIP A TILE IN A SINGLE ITERATION.
@ -460,66 +528,66 @@ int FGTileMgr::update( void ) {
if ( (p1.get_lon() > p_last.get_lon()) || if ( (p1.get_lon() > p_last.get_lon()) ||
( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) { ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << "tiles" ); " Loading " << tile_diameter << " tiles" );
for ( j = 0; j < tile_diameter; j++ ) { for ( j = 0; j < tile_diameter; j++ ) {
// scrolling East // scrolling East
disable_tile( tiles[(j*tile_diameter) + 0] );
for ( i = 0; i < tile_diameter - 1; i++ ) { for ( i = 0; i < tile_diameter - 1; i++ ) {
tiles[(j*tile_diameter) + i] = tiles[(j*tile_diameter) + i] =
tiles[(j*tile_diameter) + i + 1]; tiles[(j*tile_diameter) + i + 1];
} }
// load in new column // load in new column
// fgBucketOffset(&p_last, &p2, dw + 1, j - dh);
p2 = fgBucketOffset( last_lon, last_lat, dw + 1, j - dh ); p2 = fgBucketOffset( last_lon, last_lat, dw + 1, j - dh );
sched_tile( p2, &tiles[(j*tile_diameter) + tiles[(j*tile_diameter) + tile_diameter - 1] = sched_tile( p2 );
tile_diameter - 1]);
} }
} else if ( (p1.get_lon() < p_last.get_lon()) || } else if ( (p1.get_lon() < p_last.get_lon()) ||
( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() < p_last.get_x()) ) ) { ( (p1.get_lon() == p_last.get_lon()) &&
(p1.get_x() < p_last.get_x()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << "tiles" ); " Loading " << tile_diameter << " tiles" );
for ( j = 0; j < tile_diameter; j++ ) { for ( j = 0; j < tile_diameter; j++ ) {
// scrolling West // scrolling West
disable_tile( tiles[(j*tile_diameter) + tile_diameter - 1] );
for ( i = tile_diameter - 1; i > 0; i-- ) { for ( i = tile_diameter - 1; i > 0; i-- ) {
tiles[(j*tile_diameter) + i] = tiles[(j*tile_diameter) + i] =
tiles[(j*tile_diameter) + i - 1]; tiles[(j*tile_diameter) + i - 1];
} }
// load in new column // load in new column
// fgBucketOffset(&p_last, &p2, -dw - 1, j - dh);
p2 = fgBucketOffset( last_lon, last_lat, -dw - 1, j - dh ); p2 = fgBucketOffset( last_lon, last_lat, -dw - 1, j - dh );
sched_tile( p2, &tiles[(j*tile_diameter) + 0]); tiles[(j*tile_diameter) + 0] = sched_tile( p2 );
} }
} }
if ( (p1.get_lat() > p_last.get_lat()) || if ( (p1.get_lat() > p_last.get_lat()) ||
( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) { ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << "tiles" ); " Loading " << tile_diameter << " tiles" );
for ( i = 0; i < tile_diameter; i++ ) { for ( i = 0; i < tile_diameter; i++ ) {
// scrolling North // scrolling North
disable_tile( tiles[0 + i] );
for ( j = 0; j < tile_diameter - 1; j++ ) { for ( j = 0; j < tile_diameter - 1; j++ ) {
tiles[(j * tile_diameter) + i] = tiles[(j * tile_diameter) + i] =
tiles[((j+1) * tile_diameter) + i]; tiles[((j+1) * tile_diameter) + i];
} }
// load in new column // load in new column
// fgBucketOffset(&p_last, &p2, i - dw, dh + 1);
p2 = fgBucketOffset( last_lon, last_lat, i - dw, dh + 1); p2 = fgBucketOffset( last_lon, last_lat, i - dw, dh + 1);
sched_tile( p2, &tiles[((tile_diameter-1) * tiles[((tile_diameter-1) * tile_diameter) + i] =
tile_diameter) + i]); sched_tile( p2 );
} }
} else if ( (p1.get_lat() < p_last.get_lat()) || } else if ( (p1.get_lat() < p_last.get_lat()) ||
( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) { ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << "tiles" ); " Loading " << tile_diameter << " tiles" );
for ( i = 0; i < tile_diameter; i++ ) { for ( i = 0; i < tile_diameter; i++ ) {
// scrolling South // scrolling South
disable_tile( tiles[((tile_diameter-1) * tile_diameter) + i] );
for ( j = tile_diameter - 1; j > 0; j-- ) { for ( j = tile_diameter - 1; j > 0; j-- ) {
tiles[(j * tile_diameter) + i] = tiles[(j * tile_diameter) + i] =
tiles[((j-1) * tile_diameter) + i]; tiles[((j-1) * tile_diameter) + i];
} }
// load in new column // load in new column
// fgBucketOffset(&p_last, &p2, i - dw, -dh - 1);
p2 = fgBucketOffset( last_lon, last_lat, i - dw, -dh - 1); p2 = fgBucketOffset( last_lon, last_lat, i - dw, -dh - 1);
sched_tile( p2, &tiles[0 + i]); tiles[0 + i] = sched_tile( p2 );
} }
} }
} }
@ -529,7 +597,7 @@ int FGTileMgr::update( void ) {
FGLoadRec pending = load_queue.front(); FGLoadRec pending = load_queue.front();
load_queue.pop_front(); load_queue.pop_front();
load_tile( pending.b, pending.index ); load_tile( pending.b, pending.cache_index );
} }
// find our current elevation (feed in the current bucket to save work) // find our current elevation (feed in the current bucket to save work)
@ -538,7 +606,11 @@ int FGTileMgr::update( void ) {
scenery.cur_elev = scenery.cur_elev =
current_elev( f->get_Longitude(), f->get_Latitude(), tmp_abs_view_pos ); current_elev( f->get_Longitude(), f->get_Latitude(), tmp_abs_view_pos );
// cout << "current elevation == " << scenery.cur_elev << endl;
// double junk = current_elev_ssg( current_view.abs_view_pos,
// current_view.view_pos );
// cout << "current elevation (ssg) == " <<
p_last = p1; p_last = p1;
last_lon = f->get_Longitude() * RAD_TO_DEG; last_lon = f->get_Longitude() * RAD_TO_DEG;
last_lat = f->get_Latitude() * RAD_TO_DEG; last_lat = f->get_Latitude() * RAD_TO_DEG;
@ -765,7 +837,7 @@ void FGTileMgr::prep_ssg_nodes( void ) {
sgSetCoord( &sgcoord, sgSetCoord( &sgcoord,
t->offset.x(), t->offset.y(), t->offset.z(), t->offset.x(), t->offset.y(), t->offset.z(),
0.0, 0.0, 0.0 ); 0.0, 0.0, 0.0 );
t->branch_ptr->setTransform( &sgcoord ); t->transform_ptr->setTransform( &sgcoord );
} }
} }
} }

View file

@ -55,7 +55,7 @@ class FGLoadRec {
public: public:
FGBucket b; FGBucket b;
int index; int cache_index;
}; };
@ -80,7 +80,7 @@ private:
list < FGLoadRec > load_queue; list < FGLoadRec > load_queue;
// schedule a tile for loading // schedule a tile for loading
void sched_tile( const FGBucket& b, int *index ); int sched_tile( const FGBucket& b );
// load a tile // load a tile
void load_tile( const FGBucket& b, int cache_index ); void load_tile( const FGBucket& b, int cache_index );
@ -105,8 +105,10 @@ public:
// render the scene, but we'd also like to be able to do this // render the scene, but we'd also like to be able to do this
// explicitely. lat & lon are in radians. abs_view_pos in // explicitely. lat & lon are in radians. abs_view_pos in
// meters. Returns result in meters. // meters. Returns result in meters.
double current_elev_new( const FGBucket& p );
double current_elev( double lon, double lat, const Point3D& abs_view_pos ); double current_elev( double lon, double lat, const Point3D& abs_view_pos );
double current_elev_ssg( const Point3D& abs_view_pos,
const Point3D& view_pos );
double current_elev_new( const FGBucket& p );
// Prepare the ssg nodes ... for each tile, set it's proper // Prepare the ssg nodes ... for each tile, set it's proper
// transform and update it's range selector based on current // transform and update it's range selector based on current