1
0
Fork 0

Merge branch 'next' of git://gitorious.org/fg/flightgear into next

This commit is contained in:
Thorsten Brehm 2010-10-03 21:26:37 +02:00
commit 80c0db093d
8 changed files with 109 additions and 139 deletions

View file

@ -421,7 +421,7 @@ void FGAIAircraft::getGroundElev(double dt) {
double range = 500.0; double range = 500.0;
if (!globals->get_tile_mgr()->scenery_available(pos, range)) { if (!globals->get_tile_mgr()->scenery_available(pos, range)) {
// Try to shedule tiles for that position. // Try to shedule tiles for that position.
globals->get_tile_mgr()->update( pos, range ); globals->get_tile_mgr()->schedule_tiles_at( pos, range );
} }
double alt; double alt;

View file

@ -122,10 +122,9 @@ wxRadarBg::init ()
"Aircraft/Instruments/Textures/od_wxradar.rgb"); "Aircraft/Instruments/Textures/od_wxradar.rgb");
_resultTexture = FGTextureManager::createTexture(_texture_path.c_str(), false); _resultTexture = FGTextureManager::createTexture(_texture_path.c_str(), false);
SGPath tpath(globals->get_fg_root());
string path = _Instrument->getStringValue("echo-texture-path", string path = _Instrument->getStringValue("echo-texture-path",
"Aircraft/Instruments/Textures/wxecho.rgb"); "Aircraft/Instruments/Textures/wxecho.rgb");
tpath.append(path); SGPath tpath = globals->resolve_aircraft_path(path);
// no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect // no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
_wxEcho = SGLoadTexture2D(tpath, false, false); _wxEcho = SGLoadTexture2D(tpath, false, false);

View file

@ -556,15 +556,9 @@ do_tile_cache_reload (const SGPropertyNode * arg)
if ( !freeze ) { if ( !freeze ) {
fgSetBool("/sim/freeze/master", true); fgSetBool("/sim/freeze/master", true);
} }
if ( globals->get_tile_mgr()->init() ) {
// Load the local scenery data globals->get_subsystem("tile-manager")->reinit();
double visibility_meters = fgGetDouble("/environment/visibility-m");
globals->get_tile_mgr()->update( visibility_meters );
} else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Error in Tile Manager initialization!" );
exit(-1);
}
if ( !freeze ) { if ( !freeze ) {
fgSetBool("/sim/freeze/master", false); fgSetBool("/sim/freeze/master", false);
} }
@ -1241,8 +1235,6 @@ do_presets_commit (const SGPropertyNode * arg)
fgReInitSubsystems(); fgReInitSubsystems();
globals->get_tile_mgr()->update( fgGetDouble("/environment/visibility-m") );
#if 0 #if 0
if ( ! fgGetBool("/sim/presets/onground") ) { if ( ! fgGetBool("/sim/presets/onground") ) {
fgSetBool( "/sim/freeze/master", true ); fgSetBool( "/sim/freeze/master", true );

View file

@ -1321,14 +1321,8 @@ bool fgInitSubsystems() {
// Initialize the scenery management subsystem. // Initialize the scenery management subsystem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
if ( globals->get_tile_mgr()->init() ) { globals->add_subsystem("tile-manager", globals->get_tile_mgr(),
// Load the local scenery data SGSubsystemMgr::DISPLAY);
double visibility_meters = fgGetDouble("/environment/visibility-m");
globals->get_tile_mgr()->update( visibility_meters );
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" );
exit(-1);
}
globals->get_scenery()->get_scene_graph() globals->get_scenery()->get_scene_graph()
->addChild(simgear::Particles::getCommonRoot()); ->addChild(simgear::Particles::getCommonRoot());
@ -1553,7 +1547,8 @@ void fgReInitSubsystems()
globals->get_controls()->reset_all(); globals->get_controls()->reset_all();
globals->get_subsystem("time")->reinit(); globals->get_subsystem("time")->reinit();
globals->get_subsystem("tile-manager")->reinit();
if ( !freeze ) { if ( !freeze ) {
fgSetBool("/sim/freeze/master", false); fgSetBool("/sim/freeze/master", false);
} }
@ -1580,7 +1575,6 @@ void doSimulatorReset(void) // from gui_local.cxx -- TODO merge with fgReInitSu
fgReInitSubsystems(); fgReInitSubsystems();
globals->get_tile_mgr()->update(fgGetDouble("/environment/visibility-m"));
fgSetBool("/sim/signals/reinit", false); fgSetBool("/sim/signals/reinit", false);
if (!freeze) if (!freeze)

View file

@ -193,7 +193,6 @@ FGGlobals::~FGGlobals()
delete model_mgr; delete model_mgr;
delete channel_options_list; delete channel_options_list;
delete initial_waypoints; delete initial_waypoints;
delete tile_mgr;
delete scenery; delete scenery;
delete fontcache; delete fontcache;

View file

@ -159,19 +159,6 @@ static void fgMainLoop( void ) {
globals->get_subsystem_mgr()->update(sim_dt); globals->get_subsystem_mgr()->update(sim_dt);
globals->get_aircraft_model()->update(sim_dt); globals->get_aircraft_model()->update(sim_dt);
//
// Tile Manager updates - see if we need to load any new scenery tiles.
// this code ties together the fdm, viewer and scenery classes...
// we may want to move this to its own class at some point
//
double visibility_meters = fgGetDouble("/environment/visibility-m");
globals->get_tile_mgr()->prep_ssg_nodes( visibility_meters );
// update tile manager for view...
SGVec3d viewPos = globals->get_current_view()->get_view_pos();
SGGeod geodViewPos = SGGeod::fromCart(viewPos);
globals->get_tile_mgr()->update(geodViewPos, visibility_meters);
// run Nasal's settimer() loops right before the view manager // run Nasal's settimer() loops right before the view manager
globals->get_event_mgr()->update(sim_dt); globals->get_event_mgr()->update(sim_dt);

View file

@ -67,7 +67,7 @@ FGTileMgr::~FGTileMgr() {
// Initialize the Tile Manager subsystem // Initialize the Tile Manager subsystem
int FGTileMgr::init() { void FGTileMgr::init() {
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." ); SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." );
_options = new SGReaderWriterBTGOptions; _options = new SGReaderWriterBTGOptions;
@ -80,65 +80,78 @@ int FGTileMgr::init() {
std::copy(sc.begin(), sc.end(), back_inserter(fp)); std::copy(sc.begin(), sc.end(), back_inserter(fp));
TileEntry::setModelLoadHelper(this); TileEntry::setModelLoadHelper(this);
_visibilityMeters = fgGetNode("/environment/visibility-m", true);
tile_cache.init(); reinit();
}
state = Inited;
previous_bucket.make_bad(); void FGTileMgr::reinit()
current_bucket.make_bad(); {
tile_cache.init();
state = Inited;
longitude = latitude = -1000.0; previous_bucket.make_bad();
current_bucket.make_bad();
longitude = latitude = -1000.0;
return 1; // force an update now
update(0.0);
} }
// schedule a tile for loading // schedule a tile for loading
void FGTileMgr::sched_tile( const SGBucket& b, const bool is_inner_ring ) { void FGTileMgr::sched_tile( const SGBucket& b, const bool is_inner_ring, const bool is_cache_locked ) {
// see if tile already exists in the cache // see if tile already exists in the cache
TileEntry *t = tile_cache.get_tile( b ); TileEntry *t = tile_cache.get_tile( b );
if (t) {
if ( !t ) { t->set_timestamp(tile_cache.get_current_time());
// make space in the cache t->set_inner_ring( is_inner_ring );
SceneryPager* pager = FGScenery::getPagerSingleton(); t->set_cache_lock( is_cache_locked );
while ( (int)tile_cache.get_size() > tile_cache.get_max_cache_size() ) { return;
long index = tile_cache.get_oldest_tile(); }
if ( index >= 0 ) {
TileEntry *old = tile_cache.get_tile( index ); // make space in the cache
tile_cache.clear_entry( index ); SceneryPager* pager = FGScenery::getPagerSingleton();
osg::ref_ptr<osg::Object> subgraph = old->getNode(); while ( (int)tile_cache.get_size() >= tile_cache.get_max_cache_size() ) {
old->removeFromSceneGraph(); long index = tile_cache.get_oldest_tile();
delete old; if ( index >= 0 ) {
// zeros out subgraph ref_ptr, so subgraph is owned by TileEntry *old = tile_cache.get_tile( index );
// the pager and will be deleted in the pager thread. tile_cache.clear_entry( index );
pager->queueDeleteRequest(subgraph); osg::ref_ptr<osg::Object> subgraph = old->getNode();
} else { old->removeFromSceneGraph();
// nothing to free ?!? forge ahead delete old;
break; // zeros out subgraph ref_ptr, so subgraph is owned by
} // the pager and will be deleted in the pager thread.
} pager->queueDeleteRequest(subgraph);
// create a new entry
TileEntry *e = new TileEntry( b );
// insert the tile into the cache
if ( tile_cache.insert_tile( e ) ) {
// update_queues will generate load request
} else { } else {
// insert failed (cache full with no available entries to // nothing to free ?!? forge ahead
// delete.) Try again later break;
delete e;
} }
}
// create a new entry
TileEntry *e = new TileEntry( b );
// insert the tile into the cache
if ( tile_cache.insert_tile( e ) ) {
e->set_inner_ring( is_inner_ring );
e->set_cache_lock( is_cache_locked );
// update_queues will generate load request
// Attach to scene graph // Attach to scene graph
e->addToSceneGraph(globals->get_scenery()->get_terrain_branch()); e->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
} else { } else {
t->set_inner_ring( is_inner_ring ); // insert failed (cache full with no available entries to
// delete.) Try again later
delete e;
} }
} }
// schedule a needed buckets for loading // schedule a needed buckets for loading
void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) { void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) {
// sanity check (unfortunately needed!) // sanity check (unfortunately needed!)
if ( longitude < -180.0 || longitude > 180.0 if ( longitude < -180.0 || longitude > 180.0
|| latitude < -90.0 || latitude > 90.0 ) || latitude < -90.0 || latitude > 90.0 )
@ -155,8 +168,6 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
SG_LOG( SG_TERRAIN, SG_INFO, SG_LOG( SG_TERRAIN, SG_INFO,
"scheduling needed tiles for " << longitude << " " << latitude ); "scheduling needed tiles for " << longitude << " " << latitude );
// vis = fgGetDouble("/environment/visibility-m");
double tile_width = curr_bucket.get_width_m(); double tile_width = curr_bucket.get_width_m();
double tile_height = curr_bucket.get_height_m(); double tile_height = curr_bucket.get_height_m();
// cout << "tile width = " << tile_width << " tile_height = " // cout << "tile width = " << tile_width << " tile_height = "
@ -180,11 +191,20 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
// location. // location.
tile_cache.clear_inner_ring_flags(); tile_cache.clear_inner_ring_flags();
// clear the cache lock flags which prevented tiles of the previous position to be dropped
// from the cache.
tile_cache.clear_cache_lock_flags();
// update timestamps, so all tiles scheduled now are *newer* than any tile previously loaded
osg::FrameStamp* framestamp
= globals->get_renderer()->getViewer()->getFrameStamp();
tile_cache.set_current_time(framestamp->getReferenceTime());
SGBucket b; SGBucket b;
// schedule center tile first so it can be loaded first // schedule center tile first so it can be loaded first
b = sgBucketOffset( longitude, latitude, 0, 0 ); b = sgBucketOffset( longitude, latitude, 0, 0 );
sched_tile( b, true ); sched_tile( b, true, true );
int x, y; int x, y;
@ -193,7 +213,7 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
for ( y = -1; y <= 1; ++y ) { for ( y = -1; y <= 1; ++y ) {
if ( x != 0 || y != 0 ) { if ( x != 0 || y != 0 ) {
b = sgBucketOffset( longitude, latitude, x, y ); b = sgBucketOffset( longitude, latitude, x, y );
sched_tile( b, true ); sched_tile( b, true, true);
} }
} }
} }
@ -203,35 +223,12 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
for ( y = -yrange; y <= yrange; ++y ) { for ( y = -yrange; y <= yrange; ++y ) {
if ( x < -1 || x > 1 || y < -1 || y > 1 ) { if ( x < -1 || x > 1 || y < -1 || y > 1 ) {
SGBucket b = sgBucketOffset( longitude, latitude, x, y ); SGBucket b = sgBucketOffset( longitude, latitude, x, y );
sched_tile( b, false ); sched_tile( b, false, true);
} }
} }
} }
} }
void FGTileMgr::initialize_queue()
{
// First time through or we have teleported, initialize the
// system and load all relavant tiles
SG_LOG( SG_TERRAIN, SG_INFO, "Initialize_queue(): Updating Tile list for "
<< current_bucket );
// cout << "tile cache size = " << tile_cache.get_size() << endl;
// wipe/initialize tile cache
// tile_cache.init();
previous_bucket.make_bad();
// build the local area list and schedule tiles for loading
// start with the center tile and work out in concentric
// "rings"
double visibility_meters = fgGetDouble("/environment/visibility-m");
schedule_needed(visibility_meters, current_bucket);
}
osg::Node* osg::Node*
FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel) FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel)
{ {
@ -322,16 +319,17 @@ void FGTileMgr::update_queues()
// given the current lon/lat (in degrees), fill in the array of local // 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 // chunks. If the chunk isn't already in the cache, then read it from
// disk. // disk.
int FGTileMgr::update( double visibility_meters ) void FGTileMgr::update(double)
{
SGVec3d viewPos = globals->get_current_view()->get_view_pos();
return update(SGGeod::fromCart(viewPos), visibility_meters);
}
int FGTileMgr::update( const SGGeod& location, double visibility_meters)
{ {
SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" ); SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" );
SGVec3d viewPos = globals->get_current_view()->get_view_pos();
prep_ssg_nodes();
double vis = _visibilityMeters->getDoubleValue();
schedule_tiles_at(SGGeod::fromCart(viewPos), vis);
}
int FGTileMgr::schedule_tiles_at(const SGGeod& location, double rangeM)
{
longitude = location.getLongitudeDeg(); longitude = location.getLongitudeDeg();
latitude = location.getLatitudeDeg(); latitude = location.getLatitudeDeg();
@ -351,16 +349,16 @@ int FGTileMgr::update( const SGGeod& location, double visibility_meters)
// We've moved to a new bucket, we need to schedule any // We've moved to a new bucket, we need to schedule any
// needed tiles for loading. // needed tiles for loading.
SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" ); SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" );
schedule_needed(visibility_meters, current_bucket); schedule_needed(current_bucket, rangeM);
} }
} else if ( state == Start || state == Inited ) { } else if ( state == Start || state == Inited ) {
SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" ); SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" );
// initialize_queue();
state = Running; state = Running;
if (current_bucket != previous_bucket if (current_bucket != previous_bucket
&& current_bucket.get_chunk_lon() != -1000) { && current_bucket.get_chunk_lon() != -1000) {
SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" ); SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" );
schedule_needed(visibility_meters, current_bucket); schedule_needed(current_bucket, rangeM);
} }
} }
@ -372,11 +370,12 @@ int FGTileMgr::update( const SGGeod& location, double visibility_meters)
return 1; return 1;
} }
void FGTileMgr::prep_ssg_nodes(float vis) { void FGTileMgr::prep_ssg_nodes() {
// traverse the potentially viewable tile list and update range // traverse the potentially viewable tile list and update range
// selector and transform // selector and transform
double vis = _visibilityMeters->getDoubleValue();
TileEntry *e; TileEntry *e;
tile_cache.reset_traversal(); tile_cache.reset_traversal();

View file

@ -26,6 +26,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/bucket/newbucket.hxx> #include <simgear/bucket/newbucket.hxx>
#include <simgear/scene/tgdb/TileEntry.hxx> #include <simgear/scene/tgdb/TileEntry.hxx>
#include <simgear/scene/tgdb/TileCache.hxx> #include <simgear/scene/tgdb/TileCache.hxx>
@ -37,7 +38,7 @@ namespace osg
class Node; class Node;
} }
class FGTileMgr : public simgear::ModelLoadHelper { class FGTileMgr : public SGSubsystem, public simgear::ModelLoadHelper {
private: private:
@ -49,15 +50,12 @@ private:
}; };
load_state state; load_state state;
// initialize the cache
void initialize_queue();
// schedule a tile for loading // schedule a tile for loading
void sched_tile( const SGBucket& b, const bool is_inner_ring ); void sched_tile( const SGBucket& b, const bool is_inner_ring, const bool is_cache_locked );
// schedule a needed buckets for loading // schedule a needed buckets for loading
void schedule_needed(double visibility_meters, const SGBucket& curr_bucket); void schedule_needed(const SGBucket& curr_bucket, double rangeM);
SGBucket previous_bucket; SGBucket previous_bucket;
SGBucket current_bucket; SGBucket current_bucket;
@ -77,29 +75,31 @@ private:
*/ */
simgear::TileCache tile_cache; simgear::TileCache tile_cache;
// Update the various queues maintained by the tilemagr (private
// internal function, do not call directly.)
void update_queues();
// Prepare the ssg nodes corresponding to each tile. For each
// tile, set the ssg transform and update it's range selector
// based on current visibilty void prep_ssg_nodes( float
// visibility_meters );
void prep_ssg_nodes();
SGPropertyNode* _visibilityMeters;
public: public:
FGTileMgr(); FGTileMgr();
~FGTileMgr(); ~FGTileMgr();
// Initialize the Tile Manager // Initialize the Tile Manager
int init(); virtual void init();
virtual void reinit();
// Update the various queues maintained by the tilemagr (private virtual void update(double dt);
// internal function, do not call directly.)
void update_queues();
// given the current lon/lat (in degrees), fill in the array of int schedule_tiles_at(const SGGeod& location, double rangeM);
// local chunks. If the chunk isn't already in the cache, then
// read it from disk.
int update( double visibility_meters );
int update( const SGGeod& location, double visibility_meters);
// Prepare the ssg nodes corresponding to each tile. For each
// tile, set the ssg transform and update it's range selector
// based on current visibilty void prep_ssg_nodes( float
// visibility_meters );
void prep_ssg_nodes(float visibility_meters );
const SGBucket& get_current_bucket () const { return current_bucket; } const SGBucket& get_current_bucket () const { return current_bucket; }