//
// 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.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
// is intended to spread the load of freeing a complex tile out over
// several frames.
static int fgPartialFreeSSGtree( ssgBranch *b, int n ) {
-
-#if 0
- // for testing: we could call the following two lines and replace
- // the functionality of this entire function and everything will
- // get properly freed, but it will happen all at once and could
- // cause a huge frame rate hit.
- ssgDeRefDelete( b );
- return 0;
-#endif
-
int num_deletes = 0;
if ( n > 0 ) {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" );
if ( fgPartialFreeSSGtree( terra_transform, delete_size ) == 0 ) {
- ssgDeRefDelete( terra_transform );
+ terra_transform = 0;
free_tracker |= TERRA_NODE;
}
} else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform ) {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING gnd_lights_transform" );
if ( fgPartialFreeSSGtree( gnd_lights_transform, delete_size ) == 0 ) {
- ssgDeRefDelete( gnd_lights_transform );
+ gnd_lights_transform = 0;
free_tracker |= GROUND_LIGHTS;
}
} else if ( !(free_tracker & VASI_LIGHTS) && vasi_lights_selector ) {
// been disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING vasi_lights_selector" );
if ( fgPartialFreeSSGtree( vasi_lights_selector, delete_size ) == 0 ) {
- ssgDeRefDelete( vasi_lights_selector );
+ vasi_lights_selector = 0;
free_tracker |= VASI_LIGHTS;
}
} else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_selector ) {
// been disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_selector" );
if ( fgPartialFreeSSGtree( rwy_lights_selector, delete_size ) == 0 ) {
- ssgDeRefDelete( rwy_lights_selector );
+ rwy_lights_selector = 0;
free_tracker |= RWY_LIGHTS;
}
} else if ( !(free_tracker & TAXI_LIGHTS) && taxi_lights_selector ) {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING taxi_lights_selector" );
if ( fgPartialFreeSSGtree( taxi_lights_selector, delete_size ) == 0 ) {
- ssgDeRefDelete( taxi_lights_selector );
+ taxi_lights_selector = 0;
free_tracker |= TAXI_LIGHTS;
}
} else if ( !(free_tracker & LIGHTMAPS) ) {
// storage class for deferred object processing in FGTileEntry::load()
struct Object {
- Object(object_type t, string& token, const SGPath& p, istream& in)
+ Object(object_type t, const string& token, const SGPath& p, istream& in)
: type(t), path(p)
{
in >> name;
in >> ::skipeol;
if (type == OBJECT)
- SG_LOG(SG_TERRAIN, SG_INFO, token << " " << name);
+ SG_LOG(SG_TERRAIN, SG_INFO, " " << token << " " << name);
else
- SG_LOG(SG_TERRAIN, SG_INFO, token << " " << name << " lon=" << lon
- << " lat=" << lat << " elev=" << elev << " hdg=" << hdg);
+ SG_LOG(SG_TERRAIN, SG_INFO, " " << token << " " << name << " lon=" <<
+ lon << " lat=" << lat << " elev=" << elev << " hdg=" << hdg);
}
object_type type;
string name;
SGPath object_base;
vector<const Object*> objects;
+ string index_str = tile_bucket.gen_index_str();
+ SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << index_str );
+
// scan and parse all files and store information
- for (int i = 0; i < path_list.size(); i++) {
+ for (unsigned int i = 0; i < path_list.size(); i++) {
+ // If we found a terrain tile in Terrain/, we have to process the
+ // Objects/ dir in the same group, too, before we can stop scanning.
+ // FGGlobals::set_fg_scenery() inserts an empty string to path_list
+ // as marker.
+ if (path_list[i].empty()) {
+ if (found_tile_base)
+ break;
+ else
+ continue;
+ }
bool has_base = false;
- // Generate names for later use
- string index_str = tile_bucket.gen_index_str();
-
SGPath tile_path = path_list[i];
tile_path.append( tile_bucket.gen_base_path() );
SGPath basename = tile_path;
basename.append( index_str );
- SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << basename.str() );
+ SG_LOG( SG_TERRAIN, SG_INFO, " Trying " << basename.str() );
// Check for master .stg (scene terra gear) file
if ( token == "OBJECT_BASE" ) {
string name;
in >> name >> ::skipws;
- SG_LOG( SG_TERRAIN, SG_INFO, token << " " << name );
+ SG_LOG( SG_TERRAIN, SG_INFO, " " << token << " " << name );
if (!found_tile_base) {
found_tile_base = true;
object_base.append(name);
} else
- SG_LOG(SG_TERRAIN, SG_INFO, " (skipped)");
+ SG_LOG(SG_TERRAIN, SG_INFO, " (skipped)");
// Load only if base is not in another file
} else if ( token == "OBJECT" ) {
else {
string name;
in >> name >> ::skipeol;
- SG_LOG(SG_TERRAIN, SG_INFO, token << " " << name << " (skipped)");
+ SG_LOG(SG_TERRAIN, SG_INFO, " " << token << " "
+ << name << " (skipped)");
}
// Always OK to load
if (found_tile_base) {
// load tile if found ...
- ssgBranch *geometry = new ssgBranch;
+ ssgSharedPtr<ssgBranch> geometry = new ssgBranch;
if ( obj_load( object_base.str(), geometry,
NULL, NULL, NULL, light_pts, true ) ) {
geometry->getKid( 0 )->setTravCallback(SSG_CALLBACK_PRETRAV,
&FGTileMgr::tile_filter_cb);
new_tile -> addKid( geometry );
- } else {
- delete geometry;
}
} else {
// ... or generate an ocean tile on the fly
- ssgBranch *geometry = new ssgBranch;
+ SG_LOG(SG_TERRAIN, SG_INFO, " Generating ocean tile");
+ ssgSharedPtr<ssgBranch> geometry = new ssgBranch;
Point3D c;
double br;
if ( sgGenTile( path_list[0], tile_bucket, &c, &br,
bounding_radius = br;
new_tile -> addKid( geometry );
} else {
- delete geometry;
SG_LOG( SG_TERRAIN, SG_ALERT,
"Warning: failed to generate ocean tile!" );
}
// now that we have a valid center, process all the objects
- for (int j = 0; j < objects.size(); j++) {
+ for (unsigned int j = 0; j < objects.size(); j++) {
const Object *obj = objects[j];
if (obj->type == OBJECT) {
SGPath custom_path = obj->path;
custom_path.append( obj->name );
- ssgBranch *geometry = new ssgBranch;
- ssgBranch *vasi_lights = new ssgBranch;
- ssgBranch *rwy_lights = new ssgBranch;
- ssgBranch *taxi_lights = new ssgBranch;
+ ssgSharedPtr<ssgBranch> geometry = new ssgBranch;
+ ssgSharedPtr<ssgBranch> vasi_lights = new ssgBranch;
+ ssgSharedPtr<ssgBranch> rwy_lights = new ssgBranch;
+ ssgSharedPtr<ssgBranch> taxi_lights = new ssgBranch;
if ( obj_load( custom_path.str(),
geometry, vasi_lights, rwy_lights,
SSG_CALLBACK_PRETRAV,
&FGTileMgr::tile_filter_cb );
new_tile -> addKid( geometry );
- } else {
- delete geometry;
}
if ( vasi_lights -> getNumKids() > 0 )
vasi_lights_transform -> addKid( vasi_lights );
- else
- delete vasi_lights;
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 {
- delete geometry;
- delete vasi_lights;
- delete rwy_lights;
- delete taxi_lights;
}
= new FGDeferredModel( custom_path.str(),
obj->path.str(),
tile_bucket,
- this, obj_trans );
+ this, obj_trans,
+ obj->type == OBJECT_SHARED );
FGTileMgr::model_ready( dm );
}
#endif
- terra_transform->ref();
terrain_branch->addKid( terra_transform );
globals->get_scenery()->register_placement_transform(terra_transform);
if ( gnd_lights_transform != NULL ) {
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
- gnd_lights_transform->ref();
gnd_lights_branch->addKid( gnd_lights_transform );
globals->get_scenery()->register_placement_transform(gnd_lights_transform);
}
if ( vasi_lights_transform != NULL ) {
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
- vasi_lights_selector->ref();
vasi_lights_selector->addKid( vasi_lights_transform );
globals->get_scenery()->register_placement_transform(vasi_lights_transform);
vasi_lights_branch->addKid( vasi_lights_selector );
if ( rwy_lights_transform != NULL ) {
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
- rwy_lights_selector->ref();
rwy_lights_selector->addKid( rwy_lights_transform );
globals->get_scenery()->register_placement_transform(rwy_lights_transform);
rwy_lights_branch->addKid( rwy_lights_selector );
if ( taxi_lights_transform != NULL ) {
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
- taxi_lights_selector->ref();
taxi_lights_selector->addKid( taxi_lights_transform );
globals->get_scenery()->register_placement_transform(taxi_lights_transform);
taxi_lights_branch->addKid( taxi_lights_selector );