(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:
parent
6efea97fb0
commit
e5a87cf9fa
5 changed files with 194 additions and 62 deletions
|
@ -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";
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue