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:
parent
c8a3f60245
commit
c1fc71066b
6 changed files with 155 additions and 27 deletions
|
@ -75,13 +75,21 @@ void TileCache::init( void ) {
|
|||
|
||||
|
||||
// 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();
|
||||
const_tile_map_iterator it = tile_cache.find( tile_index );
|
||||
|
||||
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
|
||||
// nothing available to be removed.
|
||||
|
@ -191,7 +199,7 @@ void TileCache::clear_cache() {
|
|||
/**
|
||||
* 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
|
||||
long tile_index = e->get_tile_bucket().gen_index();
|
||||
tile_cache[tile_index] = e;
|
||||
|
@ -200,6 +208,19 @@ bool TileCache::insert_tile( TileEntry *e ) {
|
|||
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
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,8 @@ public:
|
|||
void init( void );
|
||||
|
||||
// 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
|
||||
// nothing available to be removed.
|
||||
|
@ -88,18 +89,16 @@ public:
|
|||
|
||||
// Return a pointer to the specified tile cache entry
|
||||
inline TileEntry *get_tile( const long tile_index ) const {
|
||||
const_tile_map_iterator it = tile_cache.find( tile_index );
|
||||
if ( it != tile_cache.end() ) {
|
||||
return it->second;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
const_tile_map_iterator it = tile_cache.find( tile_index );
|
||||
if ( it != tile_cache.end() ) {
|
||||
return it->second;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Return a pointer to the specified tile cache entry
|
||||
inline TileEntry *get_tile( const SGBucket& b ) const {
|
||||
return get_tile( b.gen_index() );
|
||||
}
|
||||
STGTileEntry* get_stg_tile( const SGBucket& b ) const;
|
||||
VPBTileEntry* get_vpb_tile( const SGBucket& b ) const;
|
||||
|
||||
// Return the cache size
|
||||
inline size_t get_size() const { return tile_cache.size(); }
|
||||
|
@ -121,7 +120,8 @@ public:
|
|||
* @param b
|
||||
* @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; }
|
||||
double get_current_time() const { return current_time; }
|
||||
|
|
|
@ -37,10 +37,9 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
// Constructor
|
||||
// Base constructor
|
||||
TileEntry::TileEntry ( const SGBucket& b )
|
||||
: tile_bucket( b ),
|
||||
tileFileName(b.gen_index_str()),
|
||||
_node( new osg::LOD ),
|
||||
_priority(-FLT_MAX),
|
||||
_current_view(false),
|
||||
|
@ -48,8 +47,6 @@ TileEntry::TileEntry ( const SGBucket& b )
|
|||
{
|
||||
_create_orthophoto();
|
||||
|
||||
tileFileName += ".stg";
|
||||
_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.
|
||||
|
@ -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 ()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -56,10 +56,11 @@ public:
|
|||
SGBucket tile_bucket;
|
||||
std::string tileFileName;
|
||||
|
||||
private:
|
||||
|
||||
protected:
|
||||
// pointer to ssg range selector for this tile
|
||||
osg::ref_ptr<osg::LOD> _node;
|
||||
|
||||
private:
|
||||
// Reference to DatabaseRequest object set and used by the
|
||||
// osgDB::DatabasePager.
|
||||
osg::ref_ptr<osg::Referenced> _databaseRequest;
|
||||
|
@ -82,12 +83,12 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
// Constructor.
|
||||
TileEntry( const SGBucket& b );
|
||||
TileEntry( const TileEntry& t );
|
||||
|
||||
// Destructor
|
||||
~TileEntry();
|
||||
virtual ~TileEntry() = 0;
|
||||
|
||||
// Update the ssg transform node for this tile so it can be
|
||||
// properly drawn relative to our (0,0,0) point
|
||||
|
@ -148,6 +149,27 @@ public:
|
|||
{
|
||||
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
|
||||
|
|
|
@ -146,7 +146,8 @@ FGTileMgr::FGTileMgr():
|
|||
_scenery_loaded(fgGetNode("/sim/sceneryloaded", true)),
|
||||
_scenery_override(fgGetNode("/sim/sceneryloaded-override", true)),
|
||||
_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 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);
|
||||
_use_vpb = fgGetBool("/scenery/use-vpb");
|
||||
|
||||
_options->setPluginStringData("SimGear::LOD_RANGE_BARE", std::to_string(bare));
|
||||
_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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// create a new entry
|
||||
t = new TileEntry( b );
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, "sched_tile: new tile entry for:" << b );
|
||||
|
||||
t = new STGTileEntry( 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
|
||||
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
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ private:
|
|||
|
||||
/// is caching of expired tiles enabled or not?
|
||||
bool _enableCache;
|
||||
bool _use_vpb;
|
||||
public:
|
||||
FGTileMgr();
|
||||
~FGTileMgr();
|
||||
|
|
Loading…
Reference in a new issue