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;
if (!globals->get_tile_mgr()->scenery_available(pos, range)) {
// 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;

View file

@ -122,10 +122,9 @@ wxRadarBg::init ()
"Aircraft/Instruments/Textures/od_wxradar.rgb");
_resultTexture = FGTextureManager::createTexture(_texture_path.c_str(), false);
SGPath tpath(globals->get_fg_root());
string path = _Instrument->getStringValue("echo-texture-path",
"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
_wxEcho = SGLoadTexture2D(tpath, false, false);

View file

@ -556,15 +556,9 @@ do_tile_cache_reload (const SGPropertyNode * arg)
if ( !freeze ) {
fgSetBool("/sim/freeze/master", true);
}
if ( globals->get_tile_mgr()->init() ) {
// Load the local scenery data
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_subsystem("tile-manager")->reinit();
if ( !freeze ) {
fgSetBool("/sim/freeze/master", false);
}
@ -1241,8 +1235,6 @@ do_presets_commit (const SGPropertyNode * arg)
fgReInitSubsystems();
globals->get_tile_mgr()->update( fgGetDouble("/environment/visibility-m") );
#if 0
if ( ! fgGetBool("/sim/presets/onground") ) {
fgSetBool( "/sim/freeze/master", true );

View file

@ -1321,14 +1321,8 @@ bool fgInitSubsystems() {
// Initialize the scenery management subsystem.
////////////////////////////////////////////////////////////////////
if ( globals->get_tile_mgr()->init() ) {
// Load the local scenery data
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->add_subsystem("tile-manager", globals->get_tile_mgr(),
SGSubsystemMgr::DISPLAY);
globals->get_scenery()->get_scene_graph()
->addChild(simgear::Particles::getCommonRoot());
@ -1553,6 +1547,7 @@ void fgReInitSubsystems()
globals->get_controls()->reset_all();
globals->get_subsystem("time")->reinit();
globals->get_subsystem("tile-manager")->reinit();
if ( !freeze ) {
fgSetBool("/sim/freeze/master", false);
@ -1580,7 +1575,6 @@ void doSimulatorReset(void) // from gui_local.cxx -- TODO merge with fgReInitSu
fgReInitSubsystems();
globals->get_tile_mgr()->update(fgGetDouble("/environment/visibility-m"));
fgSetBool("/sim/signals/reinit", false);
if (!freeze)

View file

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

View file

@ -160,19 +160,6 @@ static void fgMainLoop( void ) {
globals->get_subsystem_mgr()->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
globals->get_event_mgr()->update(sim_dt);

View file

@ -67,7 +67,7 @@ FGTileMgr::~FGTileMgr() {
// Initialize the Tile Manager subsystem
int FGTileMgr::init() {
void FGTileMgr::init() {
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." );
_options = new SGReaderWriterBTGOptions;
@ -81,64 +81,77 @@ int FGTileMgr::init() {
TileEntry::setModelLoadHelper(this);
tile_cache.init();
_visibilityMeters = fgGetNode("/environment/visibility-m", true);
state = Inited;
previous_bucket.make_bad();
current_bucket.make_bad();
reinit();
}
longitude = latitude = -1000.0;
return 1;
void FGTileMgr::reinit()
{
tile_cache.init();
state = Inited;
previous_bucket.make_bad();
current_bucket.make_bad();
longitude = latitude = -1000.0;
// force an update now
update(0.0);
}
// 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
TileEntry *t = tile_cache.get_tile( b );
if (t) {
t->set_timestamp(tile_cache.get_current_time());
t->set_inner_ring( is_inner_ring );
t->set_cache_lock( is_cache_locked );
return;
}
if ( !t ) {
// make space in the cache
SceneryPager* pager = FGScenery::getPagerSingleton();
while ( (int)tile_cache.get_size() > tile_cache.get_max_cache_size() ) {
long index = tile_cache.get_oldest_tile();
if ( index >= 0 ) {
TileEntry *old = tile_cache.get_tile( index );
tile_cache.clear_entry( index );
osg::ref_ptr<osg::Object> subgraph = old->getNode();
old->removeFromSceneGraph();
delete old;
// zeros out subgraph ref_ptr, so subgraph is owned by
// the pager and will be deleted in the pager thread.
pager->queueDeleteRequest(subgraph);
} else {
// nothing to free ?!? forge ahead
break;
}
}
// 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
// make space in the cache
SceneryPager* pager = FGScenery::getPagerSingleton();
while ( (int)tile_cache.get_size() >= tile_cache.get_max_cache_size() ) {
long index = tile_cache.get_oldest_tile();
if ( index >= 0 ) {
TileEntry *old = tile_cache.get_tile( index );
tile_cache.clear_entry( index );
osg::ref_ptr<osg::Object> subgraph = old->getNode();
old->removeFromSceneGraph();
delete old;
// zeros out subgraph ref_ptr, so subgraph is owned by
// the pager and will be deleted in the pager thread.
pager->queueDeleteRequest(subgraph);
} else {
// insert failed (cache full with no available entries to
// delete.) Try again later
delete e;
// nothing to free ?!? forge ahead
break;
}
}
// 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
e->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
} 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
void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) {
// sanity check (unfortunately needed!)
if ( longitude < -180.0 || longitude > 180.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,
"scheduling needed tiles for " << longitude << " " << latitude );
// vis = fgGetDouble("/environment/visibility-m");
double tile_width = curr_bucket.get_width_m();
double tile_height = curr_bucket.get_height_m();
// cout << "tile width = " << tile_width << " tile_height = "
@ -180,11 +191,20 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
// location.
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;
// schedule center tile first so it can be loaded first
b = sgBucketOffset( longitude, latitude, 0, 0 );
sched_tile( b, true );
sched_tile( b, true, true );
int x, y;
@ -193,7 +213,7 @@ void FGTileMgr::schedule_needed( double vis, const SGBucket& curr_bucket) {
for ( y = -1; y <= 1; ++y ) {
if ( x != 0 || y != 0 ) {
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 ) {
if ( x < -1 || x > 1 || y < -1 || y > 1 ) {
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*
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
// chunks. If the chunk isn't already in the cache, then read it from
// disk.
int FGTileMgr::update( double visibility_meters )
{
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)
void FGTileMgr::update(double)
{
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();
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
// needed tiles for loading.
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 ) {
SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" );
// initialize_queue();
state = Running;
if (current_bucket != previous_bucket
&& current_bucket.get_chunk_lon() != -1000) {
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;
}
void FGTileMgr::prep_ssg_nodes(float vis) {
void FGTileMgr::prep_ssg_nodes() {
// traverse the potentially viewable tile list and update range
// selector and transform
double vis = _visibilityMeters->getDoubleValue();
TileEntry *e;
tile_cache.reset_traversal();

View file

@ -26,6 +26,7 @@
#include <simgear/compiler.h>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/scene/tgdb/TileEntry.hxx>
#include <simgear/scene/tgdb/TileCache.hxx>
@ -37,7 +38,7 @@ namespace osg
class Node;
}
class FGTileMgr : public simgear::ModelLoadHelper {
class FGTileMgr : public SGSubsystem, public simgear::ModelLoadHelper {
private:
@ -50,14 +51,11 @@ private:
load_state state;
// initialize the cache
void initialize_queue();
// 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
void schedule_needed(double visibility_meters, const SGBucket& curr_bucket);
void schedule_needed(const SGBucket& curr_bucket, double rangeM);
SGBucket previous_bucket;
SGBucket current_bucket;
@ -77,29 +75,31 @@ private:
*/
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:
FGTileMgr();
~FGTileMgr();
// Initialize the Tile Manager
int init();
virtual void init();
virtual void reinit();
// Update the various queues maintained by the tilemagr (private
// internal function, do not call directly.)
void update_queues();
virtual void update(double dt);
// 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 update( double visibility_meters );
int update( const SGGeod& location, double visibility_meters);
int schedule_tiles_at(const SGGeod& location, double rangeM);
// 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; }