Rewrote the tile scheme to use a "map" structure rather than "vector"
structure. The new approach is simpler, more flexible, and more dynamics. We can now dynamically size the tile cache up and down. Also, the range of tiles to load is now dependent on visibility and is calculated to always bring in enough tiles.
This commit is contained in:
parent
11987d96c3
commit
39632b90b8
8 changed files with 567 additions and 336 deletions
|
@ -2,8 +2,8 @@ noinst_LIBRARIES = libScenery.a
|
|||
|
||||
libScenery_a_SOURCES = \
|
||||
hitlist.cxx hitlist.hxx \
|
||||
newcache.cxx newcache.hxx \
|
||||
scenery.cxx scenery.hxx \
|
||||
tilecache.cxx tilecache.hxx \
|
||||
tileentry.cxx tileentry.hxx \
|
||||
tilemgr.cxx tilemgr.hxx
|
||||
|
||||
|
|
290
src/Scenery/newcache.cxx
Normal file
290
src/Scenery/newcache.cxx
Normal file
|
@ -0,0 +1,290 @@
|
|||
// newcache.cxx -- routines to handle scenery tile caching
|
||||
//
|
||||
// Written by Curtis Olson, started December 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <simgear/xgl/xgl.h>
|
||||
|
||||
#include <plib/ssg.h> // plib include
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
|
||||
#include <Main/globals.hxx>
|
||||
#include <Objects/obj.hxx>
|
||||
#include <Scenery/scenery.hxx> // for scenery.center
|
||||
|
||||
#include "newcache.hxx"
|
||||
#include "tileentry.hxx"
|
||||
|
||||
FG_USING_NAMESPACE(std);
|
||||
|
||||
// a cheesy hack (to be fixed later)
|
||||
extern ssgBranch *terrain;
|
||||
extern ssgEntity *penguin;
|
||||
|
||||
|
||||
// the tile cache
|
||||
FGNewCache global_tile_cache;
|
||||
|
||||
|
||||
// Constructor
|
||||
FGNewCache::FGNewCache( void ) {
|
||||
tile_cache.clear();
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
FGNewCache::~FGNewCache( void ) {
|
||||
}
|
||||
|
||||
|
||||
// Free a tile cache entry
|
||||
void FGNewCache::entry_free( long cache_index ) {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "FREEING CACHE ENTRY = " << cache_index );
|
||||
FGTileEntry *e = tile_cache[cache_index];
|
||||
e->free_tile();
|
||||
delete( e );
|
||||
tile_cache.erase( cache_index );
|
||||
}
|
||||
|
||||
|
||||
// Initialize the tile cache subsystem
|
||||
void FGNewCache::init( void ) {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "Initializing the tile cache." );
|
||||
|
||||
// expand cache if needed. For best results ... i.e. to avoid
|
||||
// tile load problems and blank areas:
|
||||
max_cache_size = 50; // a random number to start with
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, " max cache size = "
|
||||
<< max_cache_size );
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, " current cache size = "
|
||||
<< tile_cache.size() );
|
||||
|
||||
tile_map_iterator current = tile_cache.begin();
|
||||
tile_map_iterator end = tile_cache.end();
|
||||
|
||||
for ( ; current != end; ++current ) {
|
||||
long index = current->first;
|
||||
cout << "clearing " << index << endl;
|
||||
FGTileEntry *e = current->second;
|
||||
e->tile_bucket.make_bad();
|
||||
entry_free(index);
|
||||
}
|
||||
|
||||
// and ... just in case we missed something ...
|
||||
terrain->removeAllKids();
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, " done with init()" );
|
||||
}
|
||||
|
||||
|
||||
// Search for the specified "bucket" in the cache
|
||||
bool FGNewCache::exists( const FGBucket& b ) {
|
||||
long tile_index = b.gen_index();
|
||||
tile_map_iterator it = tile_cache.find( tile_index );
|
||||
|
||||
return ( it != tile_cache.end() );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void print_refs( ssgSelector *sel, ssgTransform *trans,
|
||||
ssgRangeSelector *range)
|
||||
{
|
||||
cout << "selector -> " << sel->getRef()
|
||||
<< " transform -> " << trans->getRef()
|
||||
<< " range -> " << range->getRef() << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Fill in a tile cache entry with real data for the specified bucket
|
||||
void FGNewCache::fill_in( const FGBucket& b ) {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "FILL IN CACHE ENTRY = " << b.gen_index() );
|
||||
|
||||
// clear out a distant entry in the cache if needed.
|
||||
make_space();
|
||||
|
||||
// create the entry
|
||||
FGTileEntry *e = new FGTileEntry;
|
||||
|
||||
// register it in the cache
|
||||
long tile_index = b.gen_index();
|
||||
tile_cache[tile_index] = e;
|
||||
|
||||
// update the contents
|
||||
e->center = Point3D( 0.0 );
|
||||
if ( e->vec3_ptrs.size() || e->vec2_ptrs.size() || e->index_ptrs.size() ) {
|
||||
FG_LOG( FG_TERRAIN, FG_ALERT,
|
||||
"Attempting to overwrite existing or"
|
||||
<< " not properly freed leaf data." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
e->select_ptr = new ssgSelector;
|
||||
e->transform_ptr = new ssgTransform;
|
||||
e->range_ptr = new ssgRangeSelector;
|
||||
e->tile_bucket = b;
|
||||
|
||||
FGPath tile_path;
|
||||
if ( globals->get_options()->get_fg_scenery() != "" ) {
|
||||
tile_path.set( globals->get_options()->get_fg_scenery() );
|
||||
} else {
|
||||
tile_path.set( globals->get_options()->get_fg_root() );
|
||||
tile_path.append( "Scenery" );
|
||||
}
|
||||
tile_path.append( b.gen_base_path() );
|
||||
|
||||
// Load the appropriate data file
|
||||
FGPath tile_base = tile_path;
|
||||
tile_base.append( b.gen_index_str() );
|
||||
ssgBranch *new_tile = fgObjLoad( tile_base.str(), e, true );
|
||||
|
||||
if ( new_tile != NULL ) {
|
||||
e->range_ptr->addKid( new_tile );
|
||||
}
|
||||
|
||||
// load custom objects
|
||||
cout << "CUSTOM OBJECTS" << endl;
|
||||
|
||||
FGPath index_path = tile_path;
|
||||
index_path.append( b.gen_index_str() );
|
||||
index_path.concat( ".ind" );
|
||||
|
||||
cout << "Looking in " << index_path.str() << endl;
|
||||
|
||||
fg_gzifstream in( index_path.str() );
|
||||
|
||||
if ( in.is_open() ) {
|
||||
string token, name;
|
||||
|
||||
while ( ! in.eof() ) {
|
||||
in >> token;
|
||||
in >> name;
|
||||
#if defined ( macintosh ) || defined ( _MSC_VER )
|
||||
in >> ::skipws;
|
||||
#else
|
||||
in >> skipws;
|
||||
#endif
|
||||
cout << "token = " << token << " name = " << name << endl;
|
||||
|
||||
FGPath custom_path = tile_path;
|
||||
custom_path.append( name );
|
||||
ssgBranch *custom_obj = fgObjLoad( custom_path.str(), e, false );
|
||||
if ( (new_tile != NULL) && (custom_obj != NULL) ) {
|
||||
new_tile -> addKid( custom_obj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e->transform_ptr->addKid( e->range_ptr );
|
||||
|
||||
// calculate initial tile offset
|
||||
e->SetOffset( scenery.center );
|
||||
sgCoord sgcoord;
|
||||
sgSetCoord( &sgcoord,
|
||||
e->offset.x(), e->offset.y(), e->offset.z(),
|
||||
0.0, 0.0, 0.0 );
|
||||
e->transform_ptr->setTransform( &sgcoord );
|
||||
|
||||
e->select_ptr->addKid( e->transform_ptr );
|
||||
terrain->addKid( e->select_ptr );
|
||||
|
||||
e->select_ptr->select(1);
|
||||
}
|
||||
|
||||
|
||||
// Ensure at least one entry is free in the cache
|
||||
void FGNewCache::make_space() {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "Make space in cache" );
|
||||
|
||||
|
||||
cout << "cache size = " << tile_cache.size() << endl;
|
||||
cout << "max size = " << max_cache_size << endl;
|
||||
|
||||
if ( (int)tile_cache.size() < max_cache_size ) {
|
||||
// space in the cache, return
|
||||
return;
|
||||
}
|
||||
|
||||
while ( (int)tile_cache.size() >= max_cache_size ) {
|
||||
sgdVec3 abs_view_pos;
|
||||
float dist;
|
||||
float max_dist = 0.0;
|
||||
int max_index = -1;
|
||||
|
||||
// we need to free the furthest entry
|
||||
tile_map_iterator current = tile_cache.begin();
|
||||
tile_map_iterator end = tile_cache.end();
|
||||
|
||||
for ( ; current != end; ++current ) {
|
||||
long index = current->first;
|
||||
FGTileEntry *e = current->second;
|
||||
|
||||
// calculate approximate distance from view point
|
||||
sgdCopyVec3( abs_view_pos,
|
||||
globals->get_current_view()->get_abs_view_pos() );
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "DIST Abs view pos = "
|
||||
<< abs_view_pos[0] << ","
|
||||
<< abs_view_pos[1] << ","
|
||||
<< abs_view_pos[2] );
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
" ref point = " << e->center );
|
||||
|
||||
sgdVec3 center;
|
||||
sgdSetVec3( center, e->center.x(), e->center.y(), e->center.z() );
|
||||
dist = sgdDistanceVec3( center, abs_view_pos );
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, " distance = " << dist );
|
||||
|
||||
if ( dist > max_dist ) {
|
||||
max_dist = dist;
|
||||
max_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
// If we made it this far, then there were no open cache entries.
|
||||
// We will instead free the furthest cache entry and return it's
|
||||
// index.
|
||||
|
||||
if ( max_index >= 0 ) {
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, " max_dist = " << max_dist );
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, " index = " << max_index );
|
||||
entry_free( max_index );
|
||||
} else {
|
||||
FG_LOG( FG_TERRAIN, FG_ALERT, "WHOOPS!!! Dying in next_avail()" );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
}
|
129
src/Scenery/newcache.hxx
Normal file
129
src/Scenery/newcache.hxx
Normal file
|
@ -0,0 +1,129 @@
|
|||
// newcache.hxx -- routines to handle scenery tile caching
|
||||
//
|
||||
// Written by Curtis Olson, started December 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _NEWCACHE_HXX
|
||||
#define _NEWCACHE_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
#include "tileentry.hxx"
|
||||
|
||||
FG_USING_STD(map);
|
||||
|
||||
|
||||
typedef map < long, FGTileEntry * > tile_map;
|
||||
typedef tile_map::iterator tile_map_iterator;
|
||||
typedef tile_map::const_iterator const_tile_map_iterator;
|
||||
|
||||
|
||||
// A class to store and manage a pile of tiles
|
||||
class FGNewCache {
|
||||
|
||||
// cache storage space
|
||||
tile_map tile_cache;
|
||||
|
||||
// maximum cache size
|
||||
int max_cache_size;
|
||||
|
||||
// pointers to allow an external linear traversal of cache entries
|
||||
tile_map_iterator current;
|
||||
|
||||
// Free a tile cache entry
|
||||
void FGNewCache::entry_free( long cache_index );
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGNewCache( void );
|
||||
|
||||
// Destructor
|
||||
~FGNewCache( void );
|
||||
|
||||
// Initialize the tile cache subsystem
|
||||
void init( void );
|
||||
|
||||
// Check if the specified "bucket" exists in the cache
|
||||
bool exists( const FGBucket& b );
|
||||
|
||||
// Ensure at least one entry is free in the cache
|
||||
void FGNewCache::make_space();
|
||||
|
||||
// Fill in a tile cache entry with real data for the specified bucket
|
||||
void fill_in( const FGBucket& b );
|
||||
|
||||
// Return a pointer to the specified tile cache entry
|
||||
inline FGTileEntry *get_tile( const long tile_index ) {
|
||||
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 FGTileEntry *get_tile( const FGBucket& b ) {
|
||||
return get_tile( b.gen_index() );
|
||||
}
|
||||
|
||||
// Return the cache size
|
||||
inline size_t get_size() const { return tile_cache.size(); }
|
||||
|
||||
// External linear traversal of cache
|
||||
inline void reset_traversal() { current = tile_cache.begin(); }
|
||||
inline bool at_end() { return current == tile_cache.end(); }
|
||||
inline FGTileEntry *get_current() {
|
||||
// cout << "index = " << current->first << endl;
|
||||
return current->second;
|
||||
}
|
||||
inline void next() { ++current; }
|
||||
|
||||
inline int get_max_cache_size() const { return max_cache_size; }
|
||||
inline void set_max_cache_size( int m ) { max_cache_size = m; }
|
||||
};
|
||||
|
||||
|
||||
// the tile cache
|
||||
extern FGNewCache global_tile_cache;
|
||||
|
||||
|
||||
#endif // _NEWCACHE_HXX
|
|
@ -62,6 +62,9 @@ public:
|
|||
// Constructor
|
||||
FGTileCache( void );
|
||||
|
||||
// Destructor
|
||||
~FGTileCache( void );
|
||||
|
||||
// Initialize the tile cache subsystem
|
||||
void init( void );
|
||||
|
||||
|
@ -84,9 +87,6 @@ public:
|
|||
|
||||
// Return the cache size
|
||||
inline size_t get_size() const { return tile_cache.size(); }
|
||||
|
||||
// Destructor
|
||||
~FGTileCache( void );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -40,9 +40,8 @@ FG_USING_STD(mem_fun_ref);
|
|||
|
||||
|
||||
// Constructor
|
||||
FGTileEntry::FGTileEntry ( void )
|
||||
: ncount(0),
|
||||
state(Unused)
|
||||
FGTileEntry::FGTileEntry ()
|
||||
: ncount(0)
|
||||
{
|
||||
nodes.clear();
|
||||
select_ptr = NULL;
|
||||
|
@ -50,7 +49,7 @@ FGTileEntry::FGTileEntry ( void )
|
|||
|
||||
|
||||
// Destructor
|
||||
FGTileEntry::~FGTileEntry ( void ) {
|
||||
FGTileEntry::~FGTileEntry () {
|
||||
// cout << "nodes = " << nodes.size() << endl;;
|
||||
// delete[] nodes;
|
||||
}
|
||||
|
@ -81,9 +80,6 @@ void FGTileEntry::free_tile() {
|
|||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
"FREEING TILE = (" << tile_bucket << ")" );
|
||||
|
||||
// mark tile unused
|
||||
mark_unused();
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
" deleting " << nodes.size() << " nodes" );
|
||||
nodes.clear();
|
||||
|
@ -142,21 +138,6 @@ void FGTileEntry::free_tile() {
|
|||
// when a tile is still in the cache, but not in the immediate draw
|
||||
// list, it can still remain in the scene graph, but we use a range
|
||||
// selector to disable it from ever being drawn.
|
||||
void
|
||||
FGTileEntry::ssg_disable() {
|
||||
// cout << "TILE STATE = " << state << endl;
|
||||
if ( state == Scheduled_for_use ) {
|
||||
state = Scheduled_for_cache;
|
||||
} else if ( state == Scheduled_for_cache ) {
|
||||
// do nothing
|
||||
} else if ( (state == Loaded) || (state == Cached) ) {
|
||||
state = Cached;
|
||||
// cout << "DISABLING SSG NODE" << endl;
|
||||
select_ptr->select(0);
|
||||
} else {
|
||||
FG_LOG( FG_TERRAIN, FG_ALERT,
|
||||
"Trying to disable an unused tile! Dying" );
|
||||
exit(-1);
|
||||
}
|
||||
// cout << "TILE STATE = " << state << endl;
|
||||
void FGTileEntry::ssg_disable() {
|
||||
select_ptr->select(0);
|
||||
}
|
||||
|
|
|
@ -66,25 +66,12 @@ typedef point_list::const_iterator const_point_list_iterator;
|
|||
// Scenery tile class
|
||||
class FGTileEntry {
|
||||
|
||||
private:
|
||||
|
||||
// Tile state
|
||||
enum tile_state {
|
||||
Unused = 0,
|
||||
Scheduled_for_use = 1,
|
||||
Scheduled_for_cache = 2,
|
||||
Loaded = 3,
|
||||
Cached = 4
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef vector < sgVec3 * > free_vec3_list;
|
||||
typedef vector < sgVec2 * > free_vec2_list;
|
||||
typedef vector < unsigned short * > free_index_list;
|
||||
|
||||
public:
|
||||
|
||||
// node list
|
||||
point_list nodes;
|
||||
int ncount;
|
||||
|
@ -97,9 +84,6 @@ public:
|
|||
// this tile's official location in the world
|
||||
FGBucket tile_bucket;
|
||||
|
||||
// the tile cache will keep track here if the tile is being used
|
||||
tile_state state;
|
||||
|
||||
// list of pointers to memory chunks that need to be freed when
|
||||
// tile entry goes away
|
||||
free_vec3_list vec3_ptrs;
|
||||
|
@ -130,10 +114,10 @@ public:
|
|||
public:
|
||||
|
||||
// Constructor
|
||||
FGTileEntry ( void );
|
||||
FGTileEntry();
|
||||
|
||||
// Destructor
|
||||
~FGTileEntry ( void );
|
||||
~FGTileEntry();
|
||||
|
||||
// Clean up the memory used by this tile and delete the arrays
|
||||
// used by ssg as well as the whole ssg branch
|
||||
|
@ -146,23 +130,27 @@ public:
|
|||
}
|
||||
|
||||
// Return this tile's offset
|
||||
inline Point3D get_offset( void ) const { return offset; }
|
||||
|
||||
inline bool is_unused() const { return state == Unused; }
|
||||
inline bool is_scheduled_for_use() const {
|
||||
return state == Scheduled_for_use;
|
||||
}
|
||||
inline bool is_scheduled_for_cache() const {
|
||||
return state == Scheduled_for_cache;
|
||||
}
|
||||
inline bool is_loaded() const { return state == Loaded; }
|
||||
inline bool is_cached() const { return state == Cached; }
|
||||
inline Point3D get_offset() const { return offset; }
|
||||
|
||||
inline void mark_unused() { state = Unused; }
|
||||
inline void mark_scheduled_for_use() { state = Scheduled_for_use; }
|
||||
inline void mark_scheduled_for_cache() { state = Scheduled_for_use; }
|
||||
inline void mark_loaded() { state = Loaded; }
|
||||
// Update the ssg transform node for this tile so it can be
|
||||
// properly drawn relative to our (0,0,0) point
|
||||
inline void prep_ssg_node( const Point3D& p, float vis) {
|
||||
SetOffset( p );
|
||||
|
||||
// #define USE_UP_AND_COMING_PLIB_FEATURE
|
||||
#ifdef USE_UP_AND_COMING_PLIB_FEATURE
|
||||
range_ptr->setRange( 0, SG_ZERO );
|
||||
range_ptr->setRange( 1, vis + bounding_radius );
|
||||
#else
|
||||
float ranges[2];
|
||||
ranges[0] = SG_ZERO;
|
||||
ranges[1] = vis + bounding_radius;
|
||||
range_ptr->setRanges( ranges, 2 );
|
||||
#endif
|
||||
sgVec3 sgTrans;
|
||||
sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() );
|
||||
transform_ptr->setTransform( sgTrans );
|
||||
}
|
||||
|
||||
// when a tile is still in the cache, but not in the immediate
|
||||
// draw l ist, it can still remain in the scene graph, but we use
|
||||
|
@ -171,9 +159,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
typedef vector < FGTileEntry > tile_list;
|
||||
typedef tile_list::iterator tile_list_iterator;
|
||||
typedef tile_list::const_iterator const_tile_list_iterator;
|
||||
|
||||
|
||||
#endif // _TILEENTRY_HXX
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/math/vector.hxx>
|
||||
|
||||
// #include <Aircraft/aircraft.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Objects/obj.hxx>
|
||||
|
||||
|
@ -49,8 +48,8 @@
|
|||
# include <Weather/weather.hxx>
|
||||
#endif
|
||||
|
||||
#include "newcache.hxx"
|
||||
#include "scenery.hxx"
|
||||
#include "tilecache.hxx"
|
||||
#include "tilemgr.hxx"
|
||||
|
||||
#define TEST_LAST_HIT_CACHE
|
||||
|
@ -70,19 +69,19 @@ static inline Point3D operator + (const Point3D& a, const sgdVec3 b)
|
|||
|
||||
|
||||
// Constructor
|
||||
FGTileMgr::FGTileMgr ( void ):
|
||||
FGTileMgr::FGTileMgr():
|
||||
state( Start )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
FGTileMgr::~FGTileMgr ( void ) {
|
||||
FGTileMgr::~FGTileMgr() {
|
||||
}
|
||||
|
||||
|
||||
// Initialize the Tile Manager subsystem
|
||||
int FGTileMgr::init( void ) {
|
||||
int FGTileMgr::init() {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "Initializing Tile Manager subsystem." );
|
||||
|
||||
if ( state != Start ) {
|
||||
|
@ -92,22 +91,16 @@ int FGTileMgr::init( void ) {
|
|||
} else {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO,
|
||||
"... First time through." );
|
||||
global_tile_cache.init();
|
||||
}
|
||||
|
||||
global_tile_cache.init();
|
||||
hit_list.clear();
|
||||
|
||||
state = Inited;
|
||||
|
||||
tile_diameter = globals->get_options()->get_tile_diameter();
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "Tile Diameter = " << tile_diameter);
|
||||
|
||||
previous_bucket.make_bad();
|
||||
current_bucket.make_bad();
|
||||
|
||||
scroll_direction = SCROLL_INIT;
|
||||
tile_index = -9999;
|
||||
|
||||
longitude = latitude = -1000.0;
|
||||
last_longitude = last_latitude = -1000.0;
|
||||
|
||||
|
@ -116,40 +109,32 @@ int FGTileMgr::init( void ) {
|
|||
|
||||
|
||||
// schedule a tile for loading
|
||||
int FGTileMgr::sched_tile( const FGBucket& b ) {
|
||||
void FGTileMgr::sched_tile( const FGBucket& b ) {
|
||||
// see if tile already exists in the cache
|
||||
int cache_index = global_tile_cache.exists( b );
|
||||
FGTileEntry *t = global_tile_cache.get_tile( b );
|
||||
|
||||
if ( cache_index >= 0 ) {
|
||||
if ( t != NULL ) {
|
||||
// tile exists in cache, reenable it.
|
||||
// cout << "REENABLING DISABLED TILE" << endl;
|
||||
FGTileEntry *t = global_tile_cache.get_tile( cache_index );
|
||||
t->select_ptr->select( 1 );
|
||||
t->mark_loaded();
|
||||
} else {
|
||||
// find the next available cache entry and mark it as
|
||||
// scheduled
|
||||
cache_index = global_tile_cache.next_avail();
|
||||
FGTileEntry *t = global_tile_cache.get_tile( cache_index );
|
||||
t->mark_scheduled_for_use();
|
||||
|
||||
// register a load request
|
||||
FGLoadRec request;
|
||||
request.b = b;
|
||||
request.cache_index = cache_index;
|
||||
load_queue.push_back( request );
|
||||
load_queue.push_back( b );
|
||||
}
|
||||
|
||||
return cache_index;
|
||||
}
|
||||
|
||||
|
||||
// load a tile
|
||||
void FGTileMgr::load_tile( const FGBucket& b, int cache_index) {
|
||||
void FGTileMgr::load_tile( const FGBucket& b ) {
|
||||
// see if tile already exists in the cache
|
||||
FGTileEntry *t = global_tile_cache.get_tile( b );
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "Loading tile " << b );
|
||||
global_tile_cache.fill_in(cache_index, b);
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "Loaded for cache index: " << cache_index );
|
||||
if ( t == NULL ) {
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "Loading tile " << b );
|
||||
global_tile_cache.fill_in( b );
|
||||
} else {
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "Tile already in cache " << b );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,89 +199,65 @@ bool FGTileMgr::current_elev_ssg( sgdVec3 abs_view_pos, sgVec3 view_pos,
|
|||
}
|
||||
|
||||
|
||||
FGBucket FGTileMgr::BucketOffset( int dx, int dy )
|
||||
{
|
||||
double clat, clon, span;
|
||||
if( scroll_direction == SCROLL_INIT ) {
|
||||
// use current latitude and longitude
|
||||
// walk dy units in the lat direction
|
||||
clat = current_bucket.get_center_lat() + dy * FG_BUCKET_SPAN;
|
||||
// schedule a needed buckets for loading
|
||||
void FGTileMgr::schedule_needed() {
|
||||
double vis;
|
||||
|
||||
// find the lon span for the new latitude
|
||||
span = bucket_span( clat );
|
||||
|
||||
// walk dx units in the lon direction
|
||||
clon = longitude + dx * span;
|
||||
} else {
|
||||
// use previous latitude and longitude
|
||||
// walk dy units in the lat direction
|
||||
clat = previous_bucket.get_center_lat() + dy * FG_BUCKET_SPAN;
|
||||
|
||||
// find the lon span for the new latitude
|
||||
span = bucket_span( clat );
|
||||
|
||||
// walk dx units in the lon direction
|
||||
clon = last_longitude + dx * span;
|
||||
}
|
||||
|
||||
while ( clon < -180.0 ) clon += 360.0;
|
||||
while ( clon >= 180.0 ) clon -= 360.0;
|
||||
pending.set_bucket( clon, clat );
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, " fgBucketOffset " << pending );
|
||||
return pending;
|
||||
}
|
||||
|
||||
|
||||
// schedule a tile row(column) for loading
|
||||
void FGTileMgr::scroll( void )
|
||||
{
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "schedule_row: Scrolling" );
|
||||
|
||||
int i, dw, dh;
|
||||
|
||||
switch( scroll_direction ) {
|
||||
case SCROLL_NORTH:
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
" (North) Loading " << tile_diameter << " tiles" );
|
||||
dw = tile_diameter / 2;
|
||||
dh = dw + 1;
|
||||
for ( i = 0; i < tile_diameter; i++ ) {
|
||||
sched_tile( BucketOffset( i - dw, dh ) );
|
||||
}
|
||||
break;
|
||||
case SCROLL_EAST:
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
" (East) Loading " << tile_diameter << " tiles" );
|
||||
dh = tile_diameter / 2;
|
||||
dw = dh + 1;
|
||||
for ( i = 0; i < tile_diameter; i++ ) {
|
||||
sched_tile( BucketOffset( dw, i - dh ) );
|
||||
}
|
||||
break;
|
||||
case SCROLL_SOUTH:
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
" (South) Loading " << tile_diameter << " tiles" );
|
||||
dw = tile_diameter / 2;
|
||||
dh = -dw - 1;
|
||||
for ( i = 0; i < tile_diameter; i++ ) {
|
||||
sched_tile( BucketOffset( i - dw, dh ) );
|
||||
}
|
||||
break;
|
||||
case SCROLL_WEST:
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
" (West) Loading " << tile_diameter << " tiles" );
|
||||
dh = tile_diameter / 2;
|
||||
dw = -dh - 1;
|
||||
for ( i = 0; i < tile_diameter; i++ ) {
|
||||
sched_tile( BucketOffset( dw, i - dh ) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FG_LOG( FG_TERRAIN, FG_WARN, "UNKNOWN SCROLL DIRECTION in schedule_row" );
|
||||
;
|
||||
#ifndef FG_OLD_WEATHER
|
||||
if ( WeatherDatabase != NULL ) {
|
||||
vis = WeatherDatabase->getWeatherVisibility();
|
||||
} else {
|
||||
vis = 16000;
|
||||
}
|
||||
#else
|
||||
vis = current_weather.get_visibility();
|
||||
#endif
|
||||
cout << "visibility = " << vis << endl;
|
||||
|
||||
double clat = (int)current_bucket.get_center_lat();
|
||||
if ( clat > 0 ) {
|
||||
clat = (int)clat + 0.5;
|
||||
} else {
|
||||
clat = (int)clat - 0.5;
|
||||
}
|
||||
double clat_rad = clat * DEG_TO_RAD;
|
||||
double cos_lat = cos( clat_rad );
|
||||
double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * FG_PI;
|
||||
double degree_width = local_perimeter / 360.0;
|
||||
|
||||
// cout << "clat = " << clat << endl;
|
||||
// cout << "clat (radians) = " << clat_rad << endl;
|
||||
// cout << "cos(lat) = " << cos_lat << endl;
|
||||
// cout << "local_radius = " << local_radius << endl;
|
||||
// cout << "local_perimeter = " << local_perimeter << endl;
|
||||
cout << "degree_width = " << degree_width << endl;
|
||||
|
||||
double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
|
||||
double degree_height = perimeter / 360.0;
|
||||
cout << "degree_height = " << degree_height << endl;
|
||||
|
||||
double tile_width = current_bucket.get_width() * degree_width;
|
||||
double tile_height = current_bucket.get_height() * degree_height;
|
||||
cout << "tile width = " << tile_width << " tile_height = " << tile_height
|
||||
<< endl;
|
||||
|
||||
xrange = (int)(vis / tile_width) + 1;
|
||||
yrange = (int)(vis / tile_height) + 1;
|
||||
if ( xrange < 1 ) { xrange = 1; }
|
||||
if ( yrange < 1 ) { yrange = 1; }
|
||||
cout << "xrange = " << xrange << " yrange = " << yrange << endl;
|
||||
|
||||
global_tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) );
|
||||
|
||||
for ( int x = -xrange; x <= xrange; ++x ) {
|
||||
for ( int y = -yrange; y <= yrange; ++y ) {
|
||||
FGBucket b = fgBucketOffset( longitude, latitude, x, y );
|
||||
if ( ! global_tile_cache.exists( b ) ) {
|
||||
sched_tile( b );
|
||||
}
|
||||
}
|
||||
}
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "\tschedule_row returns" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,15 +267,14 @@ void FGTileMgr::initialize_queue()
|
|||
// system and load all relavant tiles
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << current_bucket );
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, " Updating Tile list for " << current_bucket );
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, " Loading "
|
||||
<< tile_diameter * tile_diameter << " tiles" );
|
||||
<< xrange * yrange << " tiles" );
|
||||
cout << "tile cache size = " << global_tile_cache.get_size() << endl;
|
||||
|
||||
int i;
|
||||
scroll_direction = SCROLL_INIT;
|
||||
|
||||
// wipe/initialize tile cache
|
||||
global_tile_cache.init();
|
||||
// global_tile_cache.init();
|
||||
previous_bucket.make_bad();
|
||||
|
||||
// build the local area list and schedule tiles for loading
|
||||
|
@ -322,29 +282,7 @@ void FGTileMgr::initialize_queue()
|
|||
// start with the center tile and work out in concentric
|
||||
// "rings"
|
||||
|
||||
sched_tile( current_bucket );
|
||||
|
||||
for ( i = 3; i <= tile_diameter; i = i + 2 ) {
|
||||
int j;
|
||||
int span = i / 2;
|
||||
|
||||
// bottom row
|
||||
for ( j = -span; j <= span; ++j ) {
|
||||
sched_tile( BucketOffset( j, -span ) );
|
||||
}
|
||||
|
||||
// top row
|
||||
for ( j = -span; j <= span; ++j ) {
|
||||
sched_tile( BucketOffset( j, span ) );
|
||||
}
|
||||
|
||||
// middle rows
|
||||
for ( j = -span + 1; j <= span - 1; ++j ) {
|
||||
sched_tile( BucketOffset( -span, j ) );
|
||||
sched_tile( BucketOffset( span, j ) );
|
||||
}
|
||||
|
||||
}
|
||||
schedule_needed();
|
||||
|
||||
// Now force a load of the center tile and inner ring so we
|
||||
// have something to see in our first frame.
|
||||
|
@ -353,9 +291,9 @@ void FGTileMgr::initialize_queue()
|
|||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||
"Load queue not empty, loading a tile" );
|
||||
|
||||
FGLoadRec pending = load_queue.front();
|
||||
FGBucket pending = load_queue.front();
|
||||
load_queue.pop_front();
|
||||
load_tile( pending.b, pending.cache_index );
|
||||
load_tile( pending );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -366,19 +304,7 @@ void FGTileMgr::initialize_queue()
|
|||
// tile_cache -- which actually handles all the
|
||||
// (de)allocations
|
||||
void FGTileMgr::destroy_queue() {
|
||||
while( load_queue.size() ) {
|
||||
FG_LOG( FG_TERRAIN, FG_INFO,
|
||||
"Load queue not empty, popping a tile" );
|
||||
FGLoadRec pending = load_queue.front();
|
||||
load_queue.pop_front();
|
||||
FGTileEntry *t = global_tile_cache.get_tile( pending.cache_index );
|
||||
// just t->mark_unused() should be enough
|
||||
// but a little paranoia doesn't hurt us here
|
||||
if(t->is_scheduled_for_use())
|
||||
t->mark_unused();
|
||||
else
|
||||
load_tile( pending.b, pending.cache_index );
|
||||
}
|
||||
load_queue.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -386,7 +312,7 @@ void FGTileMgr::destroy_queue() {
|
|||
// chunks. If the chunk isn't already in the cache, then read it from
|
||||
// disk.
|
||||
int FGTileMgr::update( double lon, double lat ) {
|
||||
// FG_LOG( FG_TERRAIN, FG_DEBUG, "FGTileMgr::update()" );
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "FGTileMgr::update()" );
|
||||
|
||||
// FGInterface *f = current_aircraft.fdm_state;
|
||||
|
||||
|
@ -401,67 +327,31 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
current_bucket.set_bucket( longitude, latitude );
|
||||
// FG_LOG( FG_TERRAIN, FG_DEBUG, "Updating Tile list for " << current_bucket );
|
||||
|
||||
tile_index = global_tile_cache.exists(current_bucket);
|
||||
// FG_LOG( FG_TERRAIN, FG_DEBUG, "tile index " << tile_index );
|
||||
|
||||
if ( tile_index >= 0 ) {
|
||||
current_tile = global_tile_cache.get_tile(tile_index);
|
||||
if ( global_tile_cache.exists( current_bucket ) ) {
|
||||
current_tile = global_tile_cache.get_tile( current_bucket );
|
||||
scenery.next_center = current_tile->center;
|
||||
} else {
|
||||
FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found (Ok if initializing)" );
|
||||
}
|
||||
|
||||
if ( state == Running ) {
|
||||
if( current_bucket == previous_bucket) {
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "Same bucket as last time" );
|
||||
scroll_direction = SCROLL_NONE;
|
||||
} else {
|
||||
// We've moved to a new bucket, we need to scroll our
|
||||
// structures, and load in the new tiles
|
||||
// CURRENTLY THIS ASSUMES WE CAN ONLY MOVE TO ADJACENT TILES.
|
||||
// AT ULTRA HIGH SPEEDS THIS ASSUMPTION MAY NOT BE VALID IF
|
||||
// THE AIRCRAFT CAN SKIP A TILE IN A SINGLE ITERATION.
|
||||
|
||||
if ( (current_bucket.get_lon() > previous_bucket.get_lon()) ||
|
||||
( (current_bucket.get_lon() == previous_bucket.get_lon()) &&
|
||||
(current_bucket.get_x() > previous_bucket.get_x()) ) )
|
||||
{
|
||||
scroll_direction = SCROLL_EAST;
|
||||
}
|
||||
else if ( (current_bucket.get_lon() < previous_bucket.get_lon()) ||
|
||||
( (current_bucket.get_lon() == previous_bucket.get_lon()) &&
|
||||
(current_bucket.get_x() < previous_bucket.get_x()) ) )
|
||||
{
|
||||
scroll_direction = SCROLL_WEST;
|
||||
}
|
||||
|
||||
if ( (current_bucket.get_lat() > previous_bucket.get_lat()) ||
|
||||
( (current_bucket.get_lat() == previous_bucket.get_lat()) &&
|
||||
(current_bucket.get_y() > previous_bucket.get_y()) ) )
|
||||
{
|
||||
scroll_direction = SCROLL_NORTH;
|
||||
}
|
||||
else if ( (current_bucket.get_lat() < previous_bucket.get_lat()) ||
|
||||
( (current_bucket.get_lat() == previous_bucket.get_lat()) &&
|
||||
(current_bucket.get_y() < previous_bucket.get_y()) ) )
|
||||
{
|
||||
scroll_direction = SCROLL_SOUTH;
|
||||
}
|
||||
|
||||
scroll();
|
||||
if( current_bucket != previous_bucket) {
|
||||
// We've moved to a new bucket, we need to schedule any
|
||||
// needed tiles for loading.
|
||||
schedule_needed();
|
||||
}
|
||||
|
||||
} else if ( state == Start || state == Inited ) {
|
||||
initialize_queue();
|
||||
state = Running;
|
||||
}
|
||||
|
||||
if ( load_queue.size() ) {
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "Load queue not empty, loading a tile" );
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "Load queue size = " << load_queue.size()
|
||||
<< " loading a tile" );
|
||||
|
||||
FGLoadRec pending = load_queue.front();
|
||||
FGBucket pending = load_queue.front();
|
||||
load_queue.pop_front();
|
||||
load_tile( pending.b, pending.cache_index );
|
||||
load_tile( pending );
|
||||
}
|
||||
|
||||
if ( scenery.center == Point3D(0.0) ) {
|
||||
|
@ -509,20 +399,12 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Prepare the ssg nodes ... for each tile, set it's proper
|
||||
// transform and update it's range selector based on current
|
||||
// visibilty
|
||||
void FGTileMgr::prep_ssg_node( int idx ) {
|
||||
}
|
||||
|
||||
void FGTileMgr::prep_ssg_nodes( void ) {
|
||||
FGTileEntry *t;
|
||||
float ranges[2];
|
||||
ranges[0] = 0.0f;
|
||||
double vis = 0.0;
|
||||
void FGTileMgr::prep_ssg_nodes() {
|
||||
float vis = 0.0;
|
||||
|
||||
#ifndef FG_OLD_WEATHER
|
||||
if ( WeatherDatabase != NULL ) {
|
||||
if ( WeatherDatabase ) {
|
||||
vis = WeatherDatabase->getWeatherVisibility();
|
||||
} else {
|
||||
vis = 16000;
|
||||
|
@ -534,25 +416,18 @@ void FGTileMgr::prep_ssg_nodes( void ) {
|
|||
|
||||
// traverse the potentially viewable tile list and update range
|
||||
// selector and transform
|
||||
for ( int i = 0; i < (int)global_tile_cache.get_size(); i++ ) {
|
||||
t = global_tile_cache.get_tile( i );
|
||||
|
||||
if ( t->is_loaded() ) {
|
||||
// set range selector (LOD trick) to be distance to center
|
||||
// of tile + bounding radius
|
||||
FGTileEntry *e;
|
||||
Point3D p = scenery.center;
|
||||
global_tile_cache.reset_traversal();
|
||||
|
||||
ranges[1] = vis + t->bounding_radius;
|
||||
t->range_ptr->setRanges( ranges, 2 );
|
||||
|
||||
// calculate tile offset
|
||||
t->SetOffset( scenery.center );
|
||||
|
||||
// calculate ssg transform
|
||||
sgCoord sgcoord;
|
||||
sgSetCoord( &sgcoord,
|
||||
t->offset.x(), t->offset.y(), t->offset.z(),
|
||||
0.0, 0.0, 0.0 );
|
||||
t->transform_ptr->setTransform( &sgcoord );
|
||||
while ( ! global_tile_cache.at_end() ) {
|
||||
// cout << "processing a tile" << endl;
|
||||
if ( (e = global_tile_cache.get_current()) ) {
|
||||
e->prep_ssg_node( p, vis);
|
||||
} else {
|
||||
cout << "warning ... empty tile in cache" << endl;
|
||||
}
|
||||
}
|
||||
global_tile_cache.next();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
FG_USING_STD(list);
|
||||
|
||||
|
||||
#define FG_LOCAL_X_Y 81 // max(o->tile_diameter) ** 2
|
||||
|
||||
#define FG_SQUARE( X ) ( (X) * (X) )
|
||||
|
||||
#if defined(USE_MEM) || defined(WIN32)
|
||||
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
|
||||
#else
|
||||
|
@ -57,15 +53,6 @@ FG_USING_STD(list);
|
|||
class FGTileEntry;
|
||||
|
||||
|
||||
class FGLoadRec {
|
||||
|
||||
public:
|
||||
|
||||
FGBucket b;
|
||||
int cache_index;
|
||||
};
|
||||
|
||||
|
||||
class FGTileMgr {
|
||||
|
||||
private:
|
||||
|
@ -79,19 +66,8 @@ private:
|
|||
|
||||
load_state state;
|
||||
|
||||
enum SCROLL_DIRECTION {
|
||||
SCROLL_INIT = -1,
|
||||
SCROLL_NONE = 0,
|
||||
SCROLL_NORTH,
|
||||
SCROLL_EAST,
|
||||
SCROLL_SOUTH,
|
||||
SCROLL_WEST,
|
||||
};
|
||||
|
||||
SCROLL_DIRECTION scroll_direction;
|
||||
|
||||
// pending tile load queue
|
||||
list < FGLoadRec > load_queue;
|
||||
list < FGBucket > load_queue;
|
||||
|
||||
// initialize the cache
|
||||
void initialize_queue();
|
||||
|
@ -101,16 +77,14 @@ private:
|
|||
// handles all the (de)allocations
|
||||
void destroy_queue();
|
||||
|
||||
FGBucket BucketOffset( int dx, int dy );
|
||||
|
||||
// schedule a tile for loading
|
||||
int sched_tile( const FGBucket& b );
|
||||
void sched_tile( const FGBucket& b );
|
||||
|
||||
// load a tile
|
||||
void load_tile( const FGBucket& b, int cache_index );
|
||||
void load_tile( const FGBucket& b );
|
||||
|
||||
// schedule a tile row(column) for loading
|
||||
void scroll( void );
|
||||
// schedule a needed buckets for loading
|
||||
void FGTileMgr::schedule_needed();
|
||||
|
||||
// see comment at prep_ssg_nodes()
|
||||
void prep_ssg_node( int idx );
|
||||
|
@ -127,9 +101,8 @@ private:
|
|||
|
||||
FGTileEntry *current_tile;
|
||||
|
||||
// index of current tile in tile cache;
|
||||
long int tile_index;
|
||||
int tile_diameter;
|
||||
// x and y distance of tiles to load/draw
|
||||
int xrange, yrange;
|
||||
|
||||
// current longitude latitude
|
||||
double longitude;
|
||||
|
@ -140,13 +113,13 @@ private:
|
|||
public:
|
||||
|
||||
// Constructor
|
||||
FGTileMgr ( void );
|
||||
FGTileMgr();
|
||||
|
||||
// Destructor
|
||||
~FGTileMgr ( void );
|
||||
~FGTileMgr();
|
||||
|
||||
// Initialize the Tile Manager subsystem
|
||||
int init( void );
|
||||
int init();
|
||||
|
||||
// given the current lon/lat (in degrees), fill in the array of
|
||||
// local chunks. If the chunk isn't already in the cache, then
|
||||
|
@ -171,7 +144,7 @@ public:
|
|||
// Prepare the ssg nodes ... for each tile, set it's proper
|
||||
// transform and update it's range selector based on current
|
||||
// visibilty
|
||||
void prep_ssg_nodes( void );
|
||||
void prep_ssg_nodes();
|
||||
|
||||
inline int queue_size() const { return load_queue.size(); }
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue