diff --git a/src/Scenery/tilecache.cxx b/src/Scenery/tilecache.cxx index 69b135757..4a4c907ed 100644 --- a/src/Scenery/tilecache.cxx +++ b/src/Scenery/tilecache.cxx @@ -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(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(it->second); + } else { + return NULL; + } +} diff --git a/src/Scenery/tilecache.hxx b/src/Scenery/tilecache.hxx index 79fec4170..de127e659 100644 --- a/src/Scenery/tilecache.hxx +++ b/src/Scenery/tilecache.hxx @@ -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; } diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index 566af52ba..53ffc40aa 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -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 () +{ +} + diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 934e89ffa..1866e33c8 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -56,10 +56,11 @@ public: SGBucket tile_bucket; std::string tileFileName; -private: - +protected: // pointer to ssg range selector for this tile osg::ref_ptr _node; + +private: // Reference to DatabaseRequest object set and used by the // osgDB::DatabasePager. osg::ref_ptr _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 diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 0918a740e..27f1f8313 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -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(); } diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index 810a1d7dc..5a52c8cac 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -91,6 +91,7 @@ private: /// is caching of expired tiles enabled or not? bool _enableCache; + bool _use_vpb; public: FGTileMgr(); ~FGTileMgr();