Add support for specifying a ";" delimited list of scenery locations to
search when loading scenery tiles. (I am not set on using ";" as the delimiter because it is a command separator in unix, but ":" is a critical part of the windows file naming scheme (c:\foo\bar) so that is even worse.) Example: --fg-scenery=/stage/fgfs04/curt/Scenery-0.9.1/Scenery;/stage/helio1/curt/Scenery -0.7.9
This commit is contained in:
parent
85feefa59f
commit
b206ef0a4b
4 changed files with 187 additions and 178 deletions
|
@ -92,12 +92,14 @@ FGTileLoader::add( FGTileEntry* tile )
|
||||||
static bool beenhere = false;
|
static bool beenhere = false;
|
||||||
if (!beenhere)
|
if (!beenhere)
|
||||||
{
|
{
|
||||||
|
SGPath tmp;
|
||||||
if ( !globals->get_fg_scenery().empty() ) {
|
if ( !globals->get_fg_scenery().empty() ) {
|
||||||
tile_path.set( globals->get_fg_scenery() );
|
tmp.set( globals->get_fg_scenery() );
|
||||||
} else {
|
} else {
|
||||||
tile_path.set( globals->get_fg_root() );
|
tmp.set( globals->get_fg_root() );
|
||||||
tile_path.append( "Scenery" );
|
tile_path.append( "Scenery" );
|
||||||
}
|
}
|
||||||
|
tile_path = tmp.str();
|
||||||
beenhere = true;
|
beenhere = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Base name of directory containing tile data file.
|
* Base name of directory containing tile data file.
|
||||||
*/
|
*/
|
||||||
SGPath tile_path;
|
string tile_path;
|
||||||
|
|
||||||
#ifdef ENABLE_THREADS
|
#ifdef ENABLE_THREADS
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -557,17 +557,6 @@ bool FGTileEntry::obj_load( const string& path,
|
||||||
center = c;
|
center = c;
|
||||||
bounding_radius = br;
|
bounding_radius = br;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// default to an ocean tile
|
|
||||||
if ( sgGenTile( path, tile_bucket, &c, &br,
|
|
||||||
globals->get_matlib(), geometry ) )
|
|
||||||
{
|
|
||||||
center = c;
|
|
||||||
bounding_radius = br;
|
|
||||||
} else {
|
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT,
|
|
||||||
"Warning: failed to generate ocean tile!" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (geometry != NULL);
|
return (geometry != NULL);
|
||||||
|
@ -575,212 +564,230 @@ bool FGTileEntry::obj_load( const string& path,
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FGTileEntry::load( const SGPath& base, bool is_base )
|
FGTileEntry::load( const string &base_path, bool is_base )
|
||||||
{
|
{
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "load() base = " << base.str() );
|
SG_LOG( SG_TERRAIN, SG_INFO, "load() base search path = "
|
||||||
|
<< base_path );
|
||||||
|
|
||||||
// Generate names for later use
|
bool found_tile_base = false;
|
||||||
string index_str = tile_bucket.gen_index_str();
|
|
||||||
|
|
||||||
SGPath tile_path = base;
|
string_list search = sgPathSplit( base_path );
|
||||||
tile_path.append( tile_bucket.gen_base_path() );
|
|
||||||
|
|
||||||
SGPath basename = tile_path;
|
|
||||||
basename.append( index_str );
|
|
||||||
// string path = basename.str();
|
|
||||||
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << basename.str() );
|
|
||||||
|
|
||||||
#define FG_MAX_LIGHTS 1000
|
|
||||||
|
|
||||||
// obj_load() will generate ground lighting for us ...
|
// obj_load() will generate ground lighting for us ...
|
||||||
ssgVertexArray *light_pts = new ssgVertexArray( 100 );
|
ssgVertexArray *light_pts = new ssgVertexArray( 100 );
|
||||||
|
|
||||||
ssgBranch* new_tile = new ssgBranch;
|
ssgBranch* new_tile = new ssgBranch;
|
||||||
|
|
||||||
// Check for master .stg (scene terra gear) file
|
unsigned int i = 0;
|
||||||
SGPath stg_name = basename;
|
while ( i < search.size() && !found_tile_base ) {
|
||||||
stg_name.concat( ".stg" );
|
|
||||||
|
|
||||||
sg_gzifstream in( stg_name.str() );
|
// Generate names for later use
|
||||||
|
string index_str = tile_bucket.gen_index_str();
|
||||||
|
|
||||||
if ( in.is_open() ) {
|
SGPath tile_path = search[i];
|
||||||
string token, name;
|
tile_path.append( tile_bucket.gen_base_path() );
|
||||||
|
|
||||||
while ( ! in.eof() ) {
|
SGPath basename = tile_path;
|
||||||
in >> token;
|
basename.append( index_str );
|
||||||
|
// string path = basename.str();
|
||||||
|
|
||||||
if ( token == "OBJECT_BASE" ) {
|
SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << basename.str() );
|
||||||
in >> name >> ::skipws;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
|
||||||
<< " name = " << name );
|
|
||||||
|
|
||||||
SGPath custom_path = tile_path;
|
#define FG_MAX_LIGHTS 1000
|
||||||
custom_path.append( name );
|
|
||||||
|
|
||||||
ssgBranch *geometry = new ssgBranch;
|
// Check for master .stg (scene terra gear) file
|
||||||
if ( obj_load( custom_path.str(),
|
SGPath stg_name = basename;
|
||||||
geometry, NULL, NULL, light_pts, true ) )
|
stg_name.concat( ".stg" );
|
||||||
{
|
|
||||||
new_tile -> addKid( geometry );
|
|
||||||
} else {
|
|
||||||
delete geometry;
|
|
||||||
}
|
|
||||||
} else if ( token == "OBJECT" ) {
|
|
||||||
in >> name >> ::skipws;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
|
||||||
<< " name = " << name );
|
|
||||||
|
|
||||||
SGPath custom_path = tile_path;
|
sg_gzifstream in( stg_name.str() );
|
||||||
custom_path.append( name );
|
|
||||||
|
|
||||||
ssgBranch *geometry = new ssgBranch;
|
if ( in.is_open() ) {
|
||||||
ssgBranch *rwy_lights = new ssgBranch;
|
string token, name;
|
||||||
ssgBranch *taxi_lights = new ssgBranch;
|
|
||||||
if ( obj_load( custom_path.str(),
|
while ( ! in.eof() ) {
|
||||||
geometry, rwy_lights, taxi_lights,
|
in >> token;
|
||||||
NULL, false ) )
|
|
||||||
{
|
if ( token == "OBJECT_BASE" ) {
|
||||||
if ( geometry -> getNumKids() > 0 ) {
|
in >> name >> ::skipws;
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
||||||
|
<< " name = " << name );
|
||||||
|
|
||||||
|
found_tile_base = true;
|
||||||
|
|
||||||
|
SGPath custom_path = tile_path;
|
||||||
|
custom_path.append( name );
|
||||||
|
|
||||||
|
ssgBranch *geometry = new ssgBranch;
|
||||||
|
if ( obj_load( custom_path.str(),
|
||||||
|
geometry, NULL, NULL, light_pts, true ) )
|
||||||
|
{
|
||||||
new_tile -> addKid( geometry );
|
new_tile -> addKid( geometry );
|
||||||
} else {
|
} else {
|
||||||
delete geometry;
|
delete geometry;
|
||||||
}
|
}
|
||||||
if ( rwy_lights -> getNumKids() > 0 ) {
|
} else if ( token == "OBJECT" ) {
|
||||||
rwy_lights_transform -> addKid( rwy_lights );
|
in >> name >> ::skipws;
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
||||||
|
<< " name = " << name );
|
||||||
|
|
||||||
|
SGPath custom_path = tile_path;
|
||||||
|
custom_path.append( name );
|
||||||
|
|
||||||
|
ssgBranch *geometry = new ssgBranch;
|
||||||
|
ssgBranch *rwy_lights = new ssgBranch;
|
||||||
|
ssgBranch *taxi_lights = new ssgBranch;
|
||||||
|
if ( obj_load( custom_path.str(),
|
||||||
|
geometry, rwy_lights, taxi_lights,
|
||||||
|
NULL, false ) )
|
||||||
|
{
|
||||||
|
if ( geometry -> getNumKids() > 0 ) {
|
||||||
|
new_tile -> addKid( geometry );
|
||||||
|
} else {
|
||||||
|
delete geometry;
|
||||||
|
}
|
||||||
|
if ( rwy_lights -> getNumKids() > 0 ) {
|
||||||
|
rwy_lights_transform -> addKid( rwy_lights );
|
||||||
|
} else {
|
||||||
|
delete rwy_lights;
|
||||||
|
}
|
||||||
|
if ( taxi_lights -> getNumKids() > 0 ) {
|
||||||
|
taxi_lights_transform -> addKid( taxi_lights );
|
||||||
|
} else {
|
||||||
|
delete taxi_lights;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
delete geometry;
|
||||||
delete rwy_lights;
|
delete rwy_lights;
|
||||||
}
|
|
||||||
if ( taxi_lights -> getNumKids() > 0 ) {
|
|
||||||
taxi_lights_transform -> addKid( taxi_lights );
|
|
||||||
} else {
|
|
||||||
delete taxi_lights;
|
delete taxi_lights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if ( token == "OBJECT_STATIC" ||
|
||||||
|
token == "OBJECT_SHARED" ) {
|
||||||
|
// load object info
|
||||||
|
double lon, lat, elev, hdg;
|
||||||
|
in >> name >> lon >> lat >> elev >> hdg >> ::skipws;
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
||||||
|
<< " name = " << name
|
||||||
|
<< " pos = " << lon << ", " << lat
|
||||||
|
<< " elevation = " << elev
|
||||||
|
<< " heading = " << hdg );
|
||||||
|
|
||||||
|
// object loading is deferred to main render thread,
|
||||||
|
// but lets figure out the paths right now.
|
||||||
|
SGPath custom_path;
|
||||||
|
if ( token == "OBJECT_STATIC" ) {
|
||||||
|
custom_path= tile_path;
|
||||||
|
}
|
||||||
|
custom_path.append( name );
|
||||||
|
|
||||||
|
sgCoord obj_pos;
|
||||||
|
WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg );
|
||||||
|
|
||||||
|
ssgTransform *obj_trans = new ssgTransform;
|
||||||
|
obj_trans->setTransform( &obj_pos );
|
||||||
|
|
||||||
|
// wire as much of the scene graph together as we can
|
||||||
|
new_tile->addKid( obj_trans );
|
||||||
|
|
||||||
|
// bump up the pending models count
|
||||||
|
pending_models++;
|
||||||
|
|
||||||
|
// push an entry onto the model load queue
|
||||||
|
FGDeferredModel *dm
|
||||||
|
= new FGDeferredModel( custom_path.str(),
|
||||||
|
tile_path.str(),
|
||||||
|
this, obj_trans );
|
||||||
|
FGTileMgr::model_ready( dm );
|
||||||
|
} else if ( token == "OBJECT_TAXI_SIGN" ) {
|
||||||
|
// load object info
|
||||||
|
double lon, lat, elev, hdg;
|
||||||
|
in >> name >> lon >> lat >> elev >> hdg >> ::skipws;
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
||||||
|
<< " name = " << name
|
||||||
|
<< " pos = " << lon << ", " << lat
|
||||||
|
<< " elevation = " << elev
|
||||||
|
<< " heading = " << hdg );
|
||||||
|
|
||||||
|
// load the object itself
|
||||||
|
SGPath custom_path = tile_path;
|
||||||
|
custom_path.append( name );
|
||||||
|
|
||||||
|
sgCoord obj_pos;
|
||||||
|
WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg );
|
||||||
|
|
||||||
|
ssgTransform *obj_trans = new ssgTransform;
|
||||||
|
obj_trans->setTransform( &obj_pos );
|
||||||
|
|
||||||
|
ssgBranch *custom_obj
|
||||||
|
= sgMakeTaxiSign( globals->get_matlib(),
|
||||||
|
custom_path.str(), name );
|
||||||
|
|
||||||
|
// wire the pieces together
|
||||||
|
if ( custom_obj != NULL ) {
|
||||||
|
obj_trans -> addKid( custom_obj );
|
||||||
|
}
|
||||||
|
new_tile->addKid( obj_trans );
|
||||||
|
} else if ( token == "OBJECT_RUNWAY_SIGN" ) {
|
||||||
|
// load object info
|
||||||
|
double lon, lat, elev, hdg;
|
||||||
|
in >> name >> lon >> lat >> elev >> hdg >> ::skipws;
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
||||||
|
<< " name = " << name
|
||||||
|
<< " pos = " << lon << ", " << lat
|
||||||
|
<< " elevation = " << elev
|
||||||
|
<< " heading = " << hdg );
|
||||||
|
|
||||||
|
// load the object itself
|
||||||
|
SGPath custom_path = tile_path;
|
||||||
|
custom_path.append( name );
|
||||||
|
|
||||||
|
sgCoord obj_pos;
|
||||||
|
WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg );
|
||||||
|
|
||||||
|
ssgTransform *obj_trans = new ssgTransform;
|
||||||
|
obj_trans->setTransform( &obj_pos );
|
||||||
|
|
||||||
|
ssgBranch *custom_obj
|
||||||
|
= sgMakeRunwaySign( globals->get_matlib(),
|
||||||
|
custom_path.str(), name );
|
||||||
|
|
||||||
|
// wire the pieces together
|
||||||
|
if ( custom_obj != NULL ) {
|
||||||
|
obj_trans -> addKid( custom_obj );
|
||||||
|
}
|
||||||
|
new_tile->addKid( obj_trans );
|
||||||
|
} else if ( token == "RWY_LIGHTS" ) {
|
||||||
|
double lon, lat, hdg, len, width;
|
||||||
|
string common, end1, end2;
|
||||||
|
in >> lon >> lat >> hdg >> len >> width
|
||||||
|
>> common >> end1 >> end2;
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
||||||
|
<< " pos = " << lon << ", " << lat
|
||||||
|
<< " hdg = " << hdg
|
||||||
|
<< " size = " << len << ", " << width
|
||||||
|
<< " codes = " << common << " "
|
||||||
|
<< end1 << " " << end2 );
|
||||||
} else {
|
} else {
|
||||||
delete geometry;
|
SG_LOG( SG_TERRAIN, SG_ALERT,
|
||||||
delete rwy_lights;
|
"Unknown token " << token << " in "
|
||||||
delete taxi_lights;
|
<< stg_name.str() );
|
||||||
|
in >> ::skipws;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ( token == "OBJECT_STATIC" ||
|
|
||||||
token == "OBJECT_SHARED" ) {
|
|
||||||
// load object info
|
|
||||||
double lon, lat, elev, hdg;
|
|
||||||
in >> name >> lon >> lat >> elev >> hdg >> ::skipws;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
|
||||||
<< " name = " << name
|
|
||||||
<< " pos = " << lon << ", " << lat
|
|
||||||
<< " elevation = " << elev
|
|
||||||
<< " heading = " << hdg );
|
|
||||||
|
|
||||||
// object loading is deferred to main render thread,
|
|
||||||
// but lets figure out the paths right now.
|
|
||||||
SGPath custom_path;
|
|
||||||
if ( token == "OBJECT_STATIC" )
|
|
||||||
custom_path= tile_path;
|
|
||||||
custom_path.append( name );
|
|
||||||
|
|
||||||
sgCoord obj_pos;
|
|
||||||
WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg );
|
|
||||||
|
|
||||||
ssgTransform *obj_trans = new ssgTransform;
|
|
||||||
obj_trans->setTransform( &obj_pos );
|
|
||||||
|
|
||||||
// wire as much of the scene graph together as we can
|
|
||||||
new_tile->addKid( obj_trans );
|
|
||||||
|
|
||||||
// bump up the pending models count
|
|
||||||
pending_models++;
|
|
||||||
|
|
||||||
// push an entry onto the model load queue
|
|
||||||
FGDeferredModel *dm
|
|
||||||
= new FGDeferredModel( custom_path.str(), tile_path.str(),
|
|
||||||
this, obj_trans );
|
|
||||||
FGTileMgr::model_ready( dm );
|
|
||||||
} else if ( token == "OBJECT_TAXI_SIGN" ) {
|
|
||||||
// load object info
|
|
||||||
double lon, lat, elev, hdg;
|
|
||||||
in >> name >> lon >> lat >> elev >> hdg >> ::skipws;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
|
||||||
<< " name = " << name
|
|
||||||
<< " pos = " << lon << ", " << lat
|
|
||||||
<< " elevation = " << elev
|
|
||||||
<< " heading = " << hdg );
|
|
||||||
|
|
||||||
// load the object itself
|
|
||||||
SGPath custom_path = tile_path;
|
|
||||||
custom_path.append( name );
|
|
||||||
|
|
||||||
sgCoord obj_pos;
|
|
||||||
WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg );
|
|
||||||
|
|
||||||
ssgTransform *obj_trans = new ssgTransform;
|
|
||||||
obj_trans->setTransform( &obj_pos );
|
|
||||||
|
|
||||||
ssgBranch *custom_obj
|
|
||||||
= sgMakeTaxiSign( globals->get_matlib(),
|
|
||||||
custom_path.str(), name );
|
|
||||||
|
|
||||||
// wire the pieces together
|
|
||||||
if ( custom_obj != NULL ) {
|
|
||||||
obj_trans -> addKid( custom_obj );
|
|
||||||
}
|
|
||||||
new_tile->addKid( obj_trans );
|
|
||||||
} else if ( token == "OBJECT_RUNWAY_SIGN" ) {
|
|
||||||
// load object info
|
|
||||||
double lon, lat, elev, hdg;
|
|
||||||
in >> name >> lon >> lat >> elev >> hdg >> ::skipws;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
|
||||||
<< " name = " << name
|
|
||||||
<< " pos = " << lon << ", " << lat
|
|
||||||
<< " elevation = " << elev
|
|
||||||
<< " heading = " << hdg );
|
|
||||||
|
|
||||||
// load the object itself
|
|
||||||
SGPath custom_path = tile_path;
|
|
||||||
custom_path.append( name );
|
|
||||||
|
|
||||||
sgCoord obj_pos;
|
|
||||||
WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg );
|
|
||||||
|
|
||||||
ssgTransform *obj_trans = new ssgTransform;
|
|
||||||
obj_trans->setTransform( &obj_pos );
|
|
||||||
|
|
||||||
ssgBranch *custom_obj
|
|
||||||
= sgMakeRunwaySign( globals->get_matlib(),
|
|
||||||
custom_path.str(), name );
|
|
||||||
|
|
||||||
// wire the pieces together
|
|
||||||
if ( custom_obj != NULL ) {
|
|
||||||
obj_trans -> addKid( custom_obj );
|
|
||||||
}
|
|
||||||
new_tile->addKid( obj_trans );
|
|
||||||
} else if ( token == "RWY_LIGHTS" ) {
|
|
||||||
double lon, lat, hdg, len, width;
|
|
||||||
string common, end1, end2;
|
|
||||||
in >> lon >> lat >> hdg >> len >> width
|
|
||||||
>> common >> end1 >> end2;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
|
|
||||||
<< " pos = " << lon << ", " << lat
|
|
||||||
<< " hdg = " << hdg
|
|
||||||
<< " size = " << len << ", " << width
|
|
||||||
<< " codes = " << common << " "
|
|
||||||
<< end1 << " " << end2 );
|
|
||||||
} else {
|
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT,
|
|
||||||
"Unknown token " << token << " in "
|
|
||||||
<< stg_name.str() );
|
|
||||||
in >> ::skipws;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// no .stg file, generate an ocean tile on the fly for this
|
i++;
|
||||||
// area
|
}
|
||||||
|
|
||||||
|
if ( !found_tile_base ) {
|
||||||
|
// no tile base found, generate an ocean tile on the fly for
|
||||||
|
// this area
|
||||||
ssgBranch *geometry = new ssgBranch;
|
ssgBranch *geometry = new ssgBranch;
|
||||||
Point3D c;
|
Point3D c;
|
||||||
double br;
|
double br;
|
||||||
if ( sgGenTile( basename.str(), tile_bucket, &c, &br,
|
if ( sgGenTile( search[0], tile_bucket, &c, &br,
|
||||||
globals->get_matlib(), geometry ) ) {
|
globals->get_matlib(), geometry ) )
|
||||||
|
{
|
||||||
center = c;
|
center = c;
|
||||||
bounding_radius = br;
|
bounding_radius = br;
|
||||||
new_tile -> addKid( geometry );
|
new_tile -> addKid( geometry );
|
||||||
|
|
|
@ -212,7 +212,7 @@ public:
|
||||||
* @param base name of directory containing tile data file.
|
* @param base name of directory containing tile data file.
|
||||||
* @param is_base is this a base terrain object for which we should generate
|
* @param is_base is this a base terrain object for which we should generate
|
||||||
* random ground light points */
|
* random ground light points */
|
||||||
void load( const SGPath& base, bool is_base );
|
void load( const string &base_path, bool is_base );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the tile entry is loaded, otherwise return false
|
* Return true if the tile entry is loaded, otherwise return false
|
||||||
|
|
Loading…
Reference in a new issue