1
0
Fork 0

WS30 Move VPB tile loading to the tile manager

Previously VPB tiles were loaded by the STG file loader.

This was not ideal as the VPB tile granularity is 1x1 degree
while the STG file loader is 20x20km.

This change makes the tile manager load VPB tiles explicitly
on range, and allows better prioritization of the underlying
terrain.
This commit is contained in:
Stuart Buchanan 2021-10-20 23:39:59 +01:00
parent c8a3f60245
commit c1fc71066b
6 changed files with 155 additions and 27 deletions

View file

@ -75,13 +75,21 @@ void TileCache::init( void ) {
// Search for the specified "bucket" in the cache // Search for the specified "bucket" in the cache
bool TileCache::exists( const SGBucket& b ) const { bool TileCache::exists_stg( const SGBucket& b ) const {
long tile_index = b.gen_index(); long tile_index = b.gen_index();
const_tile_map_iterator it = tile_cache.find( tile_index ); const_tile_map_iterator it = tile_cache.find( tile_index );
return ( it != tile_cache.end() ); return ( it != tile_cache.end() );
} }
bool TileCache::exists_vpb( const SGBucket& b ) const {
// VPB tiles are stored with negative index to avoid clash with STG index
long tile_index = - b.gen_vpb_index();
const_tile_map_iterator it = tile_cache.find( tile_index );
return ( it != tile_cache.end() );
}
// Return the index of a tile to be dropped from the cache, return -1 if // Return the index of a tile to be dropped from the cache, return -1 if
// nothing available to be removed. // nothing available to be removed.
@ -191,7 +199,7 @@ void TileCache::clear_cache() {
/** /**
* Create a new tile and schedule it for loading. * Create a new tile and schedule it for loading.
*/ */
bool TileCache::insert_tile( TileEntry *e ) { bool TileCache::insert_tile( STGTileEntry *e ) {
// register tile in the cache // register tile in the cache
long tile_index = e->get_tile_bucket().gen_index(); long tile_index = e->get_tile_bucket().gen_index();
tile_cache[tile_index] = e; tile_cache[tile_index] = e;
@ -200,6 +208,19 @@ bool TileCache::insert_tile( TileEntry *e ) {
return true; return true;
} }
/**
* Create a new tile and schedule it for loading. VPB version, with negative index.
*/
bool TileCache::insert_tile( VPBTileEntry *e ) {
// register tile in the cache
long tile_index = - e->get_tile_bucket().gen_vpb_index();
tile_cache[tile_index] = e;
e->update_time_expired(current_time);
return true;
}
// update tile's priority and expiry time according to current request // update tile's priority and expiry time according to current request
void TileCache::request_tile(TileEntry* t,float priority,bool current_view,double request_time) void TileCache::request_tile(TileEntry* t,float priority,bool current_view,double request_time)
{ {
@ -223,3 +244,31 @@ void TileCache::request_tile(TileEntry* t,float priority,bool current_view,doubl
t->update_time_expired( current_time+request_time ); t->update_time_expired( current_time+request_time );
} }
} }
// Return a pointer to the specified tile cache entry
STGTileEntry* TileCache::get_stg_tile( const SGBucket& b ) const {
const_tile_map_iterator it = std::find_if(tile_cache.begin(), tile_cache.end(),
[b](auto &t) {
return ((b.gen_index() == t.first) && (t.second->getExtension() == TileEntry::Extension::STG));
});
if ( it != tile_cache.end() ) {
return dynamic_cast<STGTileEntry*>(it->second);
} else {
return NULL;
}
}
// Return a pointer to the specified tile cache entry
VPBTileEntry* TileCache::get_vpb_tile( const SGBucket& b ) const {
const_tile_map_iterator it = std::find_if(tile_cache.begin(), tile_cache.end(),
[b](auto &t) {
// Negative indices are used for the VPB tiles.
return (( - b.gen_vpb_index() == t.first) && (t.second->getExtension() == TileEntry::Extension::VPB));
});
if ( it != tile_cache.end() ) {
return dynamic_cast<VPBTileEntry*>(it->second);
} else {
return NULL;
}
}

View file

@ -68,7 +68,8 @@ public:
void init( void ); void init( void );
// Check if the specified "bucket" exists in the cache // Check if the specified "bucket" exists in the cache
bool exists( const SGBucket& b ) const; bool exists_stg( const SGBucket& b ) const;
bool exists_vpb( const SGBucket& b ) const;
// Return the index of a tile to be dropped from the cache, return -1 if // Return the index of a tile to be dropped from the cache, return -1 if
// nothing available to be removed. // nothing available to be removed.
@ -88,18 +89,16 @@ public:
// Return a pointer to the specified tile cache entry // Return a pointer to the specified tile cache entry
inline TileEntry *get_tile( const long tile_index ) const { inline TileEntry *get_tile( const long tile_index ) const {
const_tile_map_iterator it = tile_cache.find( tile_index ); const_tile_map_iterator it = tile_cache.find( tile_index );
if ( it != tile_cache.end() ) { if ( it != tile_cache.end() ) {
return it->second; return it->second;
} else { } else {
return NULL; return NULL;
} }
} }
// Return a pointer to the specified tile cache entry STGTileEntry* get_stg_tile( const SGBucket& b ) const;
inline TileEntry *get_tile( const SGBucket& b ) const { VPBTileEntry* get_vpb_tile( const SGBucket& b ) const;
return get_tile( b.gen_index() );
}
// Return the cache size // Return the cache size
inline size_t get_size() const { return tile_cache.size(); } inline size_t get_size() const { return tile_cache.size(); }
@ -121,7 +120,8 @@ public:
* @param b * @param b
* @return success/failure * @return success/failure
*/ */
bool insert_tile( TileEntry* e ); bool insert_tile( STGTileEntry* e );
bool insert_tile( VPBTileEntry* e );
void set_current_time(double val) { current_time = val; } void set_current_time(double val) { current_time = val; }
double get_current_time() const { return current_time; } double get_current_time() const { return current_time; }

View file

@ -37,10 +37,9 @@
using std::string; using std::string;
// Constructor // Base constructor
TileEntry::TileEntry ( const SGBucket& b ) TileEntry::TileEntry ( const SGBucket& b )
: tile_bucket( b ), : tile_bucket( b ),
tileFileName(b.gen_index_str()),
_node( new osg::LOD ), _node( new osg::LOD ),
_priority(-FLT_MAX), _priority(-FLT_MAX),
_current_view(false), _current_view(false),
@ -48,8 +47,6 @@ TileEntry::TileEntry ( const SGBucket& b )
{ {
_create_orthophoto(); _create_orthophoto();
tileFileName += ".stg";
_node->setName(tileFileName);
// Give a default LOD range so that traversals that traverse // Give a default LOD range so that traversals that traverse
// active children (like the groundcache lookup) will work before // active children (like the groundcache lookup) will work before
// tile manager has had a chance to update this node. // tile manager has had a chance to update this node.
@ -131,3 +128,31 @@ TileEntry::removeFromSceneGraph()
} }
} }
// Constructor - STG Variant
STGTileEntry::STGTileEntry ( const SGBucket& b ) : TileEntry(b)
{
tileFileName = b.gen_index_str() + ".stg";
_node->setName(tileFileName);
}
// Destructor - STG Variant
STGTileEntry::~STGTileEntry ()
{
}
// Constructur - VPB version
VPBTileEntry::VPBTileEntry ( const SGBucket& b ) : TileEntry(b)
{
tileFileName = "vpb/" + b.gen_vpb_base() + ".osgb";
_node->setName(tileFileName);
// Give a default LOD range so that traversals that traverse
// active children (like the groundcache lookup) will work before
// tile manager has had a chance to update this node.
_node->setRange(0, 0.0, 160000.0);
}
// Destructor - VPB Variant
VPBTileEntry::~VPBTileEntry ()
{
}

View file

@ -56,10 +56,11 @@ public:
SGBucket tile_bucket; SGBucket tile_bucket;
std::string tileFileName; std::string tileFileName;
private: protected:
// pointer to ssg range selector for this tile // pointer to ssg range selector for this tile
osg::ref_ptr<osg::LOD> _node; osg::ref_ptr<osg::LOD> _node;
private:
// Reference to DatabaseRequest object set and used by the // Reference to DatabaseRequest object set and used by the
// osgDB::DatabasePager. // osgDB::DatabasePager.
osg::ref_ptr<osg::Referenced> _databaseRequest; osg::ref_ptr<osg::Referenced> _databaseRequest;
@ -82,12 +83,12 @@ private:
public: public:
// Constructor // Constructor.
TileEntry( const SGBucket& b ); TileEntry( const SGBucket& b );
TileEntry( const TileEntry& t ); TileEntry( const TileEntry& t );
// Destructor // Destructor
~TileEntry(); virtual ~TileEntry() = 0;
// Update the ssg transform node for this tile so it can be // Update the ssg transform node for this tile so it can be
// properly drawn relative to our (0,0,0) point // properly drawn relative to our (0,0,0) point
@ -148,6 +149,27 @@ public:
{ {
return _databaseRequest; return _databaseRequest;
} }
enum Extension {
STG, VPB
};
virtual TileEntry::Extension getExtension() = 0;
}; };
class STGTileEntry : public TileEntry {
public:
STGTileEntry ( const SGBucket& b );
~STGTileEntry();
inline TileEntry::Extension getExtension() { return TileEntry::Extension::STG; };
};
class VPBTileEntry : public TileEntry {
public:
VPBTileEntry ( const SGBucket& b );
~VPBTileEntry();
inline TileEntry::Extension getExtension() { return TileEntry::Extension::VPB; };
};
#endif // _TILEENTRY_HXX #endif // _TILEENTRY_HXX

View file

@ -146,7 +146,8 @@ FGTileMgr::FGTileMgr():
_scenery_loaded(fgGetNode("/sim/sceneryloaded", true)), _scenery_loaded(fgGetNode("/sim/sceneryloaded", true)),
_scenery_override(fgGetNode("/sim/sceneryloaded-override", true)), _scenery_override(fgGetNode("/sim/sceneryloaded-override", true)),
_pager(FGScenery::getPagerSingleton()), _pager(FGScenery::getPagerSingleton()),
_enableCache(true) _enableCache(true),
_use_vpb(false)
{ {
} }
@ -206,6 +207,7 @@ void FGTileMgr::reinit()
double rough = fgGetDouble("/sim/rendering/static-lod/rough-delta", SG_OBJECT_RANGE_ROUGH) + detailed; double rough = fgGetDouble("/sim/rendering/static-lod/rough-delta", SG_OBJECT_RANGE_ROUGH) + detailed;
double bare = fgGetDouble("/sim/rendering/static-lod/bare", SG_OBJECT_RANGE_BARE) + rough; double bare = fgGetDouble("/sim/rendering/static-lod/bare", SG_OBJECT_RANGE_BARE) + rough;
double tile_min_expiry = fgGetDouble("/sim/rendering/plod-minimum-expiry-time-secs", SG_TILE_MIN_EXPIRY); double tile_min_expiry = fgGetDouble("/sim/rendering/plod-minimum-expiry-time-secs", SG_TILE_MIN_EXPIRY);
_use_vpb = fgGetBool("/scenery/use-vpb");
_options->setPluginStringData("SimGear::LOD_RANGE_BARE", std::to_string(bare)); _options->setPluginStringData("SimGear::LOD_RANGE_BARE", std::to_string(bare));
_options->setPluginStringData("SimGear::LOD_RANGE_ROUGH", std::to_string(rough)); _options->setPluginStringData("SimGear::LOD_RANGE_ROUGH", std::to_string(rough));
@ -275,13 +277,12 @@ void FGTileMgr::materialLibChanged()
bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_view, double duration) bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_view, double duration)
{ {
// see if tile already exists in the cache // see if tile already exists in the cache
TileEntry *t = tile_cache.get_tile( b ); STGTileEntry *t = tile_cache.get_stg_tile( b );
if (!t) if (!t)
{ {
// create a new entry // create a new entry
t = new TileEntry( b ); t = new STGTileEntry( b );
SG_LOG( SG_TERRAIN, SG_INFO, "sched_tile: new tile entry for:" << b ); SG_LOG( SG_TERRAIN, SG_INFO, "sched_tile: new STG tile entry for:" << b );
// insert the tile into the cache, update will generate load request // insert the tile into the cache, update will generate load request
if ( tile_cache.insert_tile( t ) ) if ( tile_cache.insert_tile( t ) )
@ -303,6 +304,36 @@ bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_vie
// update tile's properties // update tile's properties
tile_cache.request_tile(t,priority,current_view,duration); tile_cache.request_tile(t,priority,current_view,duration);
if (_use_vpb) {
VPBTileEntry *v = tile_cache.get_vpb_tile( b );
if (!v)
{
// create a new entry
v = new VPBTileEntry( b );
SG_LOG( SG_TERRAIN, SG_INFO, "sched_tile: new VPB tile entry for:" << b );
// insert the tile into the cache, update will generate load request
if ( tile_cache.insert_tile( v ) )
{
// Attach to scene graph
v->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
} else {
// insert failed (cache full with no available entries to
// delete.) Try again later
delete v;
return false;
}
SG_LOG( SG_TERRAIN, SG_DEBUG, " New tile cache size " << (int)tile_cache.get_size() );
}
// update tile's properties. We ensure VPB tiles have maximum priority - priority is calcualated as
// _negative_ the square of the distance from the viewer to the tile.
// so by multiplying by 0.1 we increase the number towards 0.
tile_cache.request_tile(v,priority * 0.1,current_view,duration);
}
return t->is_loaded(); return t->is_loaded();
} }

View file

@ -91,6 +91,7 @@ private:
/// is caching of expired tiles enabled or not? /// is caching of expired tiles enabled or not?
bool _enableCache; bool _enableCache;
bool _use_vpb;
public: public:
FGTileMgr(); FGTileMgr();
~FGTileMgr(); ~FGTileMgr();