// Initialize the Tile Manager subsystem
-int FGTileMgr::init() {
+void FGTileMgr::init() {
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." );
_options = new SGReaderWriterBTGOptions;
std::copy(sc.begin(), sc.end(), back_inserter(fp));
TileEntry::setModelLoadHelper(this);
+
+ _visibilityMeters = fgGetNode("/environment/visibility-m", true);
+
- tile_cache.init();
+ reinit();
+}
- state = Inited;
- previous_bucket.make_bad();
- current_bucket.make_bad();
+void FGTileMgr::reinit()
+{
+ 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
void FGTileMgr::sched_tile( const SGBucket& b, const bool is_inner_ring ) {
// see if tile already exists in the cache
TileEntry *t = tile_cache.get_tile( b );
-
- 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;
- }
+ if (t) {
+ t->set_inner_ring( is_inner_ring );
+ return;
+ }
+
+ // 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 );
+ // 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 {
- // insert failed (cache full with no available entries to
- // delete.) Try again later
- delete e;
- }
- // Attach to scene graph
- e->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
+ // insert the tile into the cache
+ if ( tile_cache.insert_tile( e ) ) {
+ // update_queues will generate load request
} else {
- t->set_inner_ring( is_inner_ring );
+ // insert failed (cache full with no available entries to
+ // delete.) Try again later
+ delete e;
}
+ // Attach to scene graph
+ e->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
}
// 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 )
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 = "
}
}
-
-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)
{
// 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 )
+void FGTileMgr::update(double)
{
+ SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" );
SGVec3d viewPos = globals->get_current_view()->get_view_pos();
- return update(SGGeod::fromCart(viewPos), visibility_meters);
+ prep_ssg_nodes();
+ double vis = _visibilityMeters->getDoubleValue();
+ schedule_tiles_at(SGGeod::fromCart(viewPos), vis);
}
-int FGTileMgr::update( const SGGeod& location, double visibility_meters)
+int FGTileMgr::schedule_tiles_at(const SGGeod& location, double rangeM)
{
- SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" );
-
longitude = location.getLongitudeDeg();
latitude = location.getLatitudeDeg();
// 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);
}
}
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();
#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>
class Node;
}
-class FGTileMgr : public simgear::ModelLoadHelper {
+class FGTileMgr : public SGSubsystem, public simgear::ModelLoadHelper {
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 );
// 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;
*/
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; }