: center( Point3D( 0.0 ) ),
tile_bucket( b ),
terra_transform( new ssgTransform ),
+ vasi_lights_transform( new ssgTransform ),
rwy_lights_transform( new ssgTransform ),
taxi_lights_transform( new ssgTransform ),
terra_range( new ssgRangeSelector ),
+ vasi_lights_selector( new ssgSelector ),
rwy_lights_selector( new ssgSelector ),
taxi_lights_selector( new ssgSelector ),
loaded(false),
ssgDeRefDelete( gnd_lights_transform );
free_tracker |= GROUND_LIGHTS;
}
+ } else if ( !(free_tracker & VASI_LIGHTS) && vasi_lights_selector ) {
+ // delete the runway lighting branch (this should already have
+ // 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 );
+ free_tracker |= VASI_LIGHTS;
+ }
} else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_selector ) {
// delete the runway lighting branch (this should already have
// been disconnected from the scene graph)
sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() );
terra_transform->setTransform( sgTrans );
+ FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
if ( gnd_lights_transform ) {
// we need to lift the lights above the terrain to avoid
// z-buffer fighting. We do this based on our altitude and
gnd_lights_transform->setTransform( lt_trans );
// select which set of lights based on sun angle
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
if ( sun_angle > 95 ) {
gnd_lights_brightness->select(0x04);
} else if ( sun_angle > 92 ) {
}
}
+ if ( vasi_lights_transform ) {
+ // we need to lift the lights above the terrain to avoid
+ // z-buffer fighting. We do this based on our altitude and
+ // the distance this tile is away from scenery center.
+
+ sgVec3 lift_vec;
+ sgCopyVec3( lift_vec, up );
+
+ // we fudge agl by 30 meters so that the lifting function
+ // doesn't phase in until we are > 30m agl.
+ double agl;
+ agl = globals->get_current_view()->getAltitudeASL_ft()
+ * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev()
+ - 30.0;
+ if ( agl < 0.0 ) {
+ agl = 0.0;
+ }
+
+ if ( general.get_glDepthBits() > 16 ) {
+ sgScaleVec3( lift_vec, 0.0 + agl / 500.0 );
+ } else {
+ sgScaleVec3( lift_vec, 0.0 + agl / 150.0 );
+ }
+
+ sgVec3 lt_trans;
+ sgCopyVec3( lt_trans, sgTrans );
+
+ sgAddVec3( lt_trans, lift_vec );
+ vasi_lights_transform->setTransform( lt_trans );
+
+ // generally, vasi lights are always on
+ vasi_lights_selector->select(0x01);
+ }
+
if ( rwy_lights_transform ) {
// we need to lift the lights above the terrain to avoid
// z-buffer fighting. We do this based on our altitude and
rwy_lights_transform->setTransform( lt_trans );
// turn runway lights on/off based on sun angle and visibility
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
if ( sun_angle > 85 ||
(fgGetDouble("/environment/visibility-m") < 5000.0) ) {
rwy_lights_selector->select(0x01);
taxi_lights_transform->setTransform( lt_trans );
// turn taxi lights on/off based on sun angle and visibility
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
+ float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
if ( sun_angle > 85 ||
(fgGetDouble("/environment/visibility-m") < 5000.0) ) {
taxi_lights_selector->select(0x01);
bool FGTileEntry::obj_load( const string& path,
- ssgBranch* geometry,
- ssgBranch* rwy_lights,
- ssgBranch* taxi_lights,
- ssgVertexArray* ground_lights, bool is_base )
+ ssgBranch *geometry,
+ ssgBranch *vasi_lights,
+ ssgBranch *rwy_lights,
+ ssgBranch *taxi_lights,
+ ssgVertexArray *ground_lights, bool is_base )
{
Point3D c; // returned center point
double br; // returned bounding radius
// try loading binary format
if ( sgBinObjLoad( path, is_base,
&c, &br, globals->get_matlib(), use_random_objects,
- geometry, rwy_lights, taxi_lights, ground_lights ) )
+ geometry, vasi_lights, rwy_lights, taxi_lights,
+ ground_lights ) )
{
if ( is_base ) {
center = c;
ssgBranch* new_tile = new ssgBranch;
unsigned int i = 0;
- while ( i < search.size() && !found_tile_base ) {
+ while ( i < search.size() ) {
+
+ bool has_base = false;
// Generate names for later use
string index_str = tile_bucket.gen_index_str();
while ( ! in.eof() ) {
in >> token;
+ // Load only once (first found)
if ( token == "OBJECT_BASE" ) {
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 );
+ if (!found_tile_base) {
+ found_tile_base = true;
+ has_base = true;
+
+ SGPath custom_path = tile_path;
+ custom_path.append( name );
+
+ ssgBranch *geometry = new ssgBranch;
+ if ( obj_load( custom_path.str(),
+ geometry, NULL, NULL, NULL, light_pts,
+ true ) )
+ {
+ new_tile -> addKid( geometry );
+ } else {
+ delete geometry;
+ }
} else {
- delete geometry;
+ SG_LOG( SG_TERRAIN, SG_INFO, " (skipped)" );
}
- } else if ( token == "OBJECT" ) {
- 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 {
- delete geometry;
- delete rwy_lights;
- delete taxi_lights;
+ // Load only if base is not in another file
+ } else if ( token == "OBJECT" ) {
+ if (!found_tile_base || has_base) {
+ 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 *vasi_lights = new ssgBranch;
+ ssgBranch *rwy_lights = new ssgBranch;
+ ssgBranch *taxi_lights = new ssgBranch;
+ if ( obj_load( custom_path.str(),
+ geometry, vasi_lights, rwy_lights,
+ taxi_lights, NULL, false ) )
+ {
+ if ( geometry -> getNumKids() > 0 ) {
+ 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;
+ }
}
+ // Always OK to load
} else if ( token == "OBJECT_STATIC" ||
token == "OBJECT_SHARED" ) {
// load object info
SGPath custom_path;
if ( token == "OBJECT_STATIC" ) {
custom_path= tile_path;
+ } else {
+ custom_path = globals->get_fg_root();
}
custom_path.append( name );
tile_path.str(),
this, obj_trans );
FGTileMgr::model_ready( dm );
+
+ // Do we even use this one?
} else if ( token == "OBJECT_TAXI_SIGN" ) {
// load object info
double lon, lat, elev, hdg;
obj_trans -> addKid( custom_obj );
}
new_tile->addKid( obj_trans );
+
+ // Do we even use this one?
} else if ( token == "OBJECT_RUNWAY_SIGN" ) {
// load object info
double lon, lat, elev, hdg;
obj_trans -> addKid( custom_obj );
}
new_tile->addKid( obj_trans );
+
+ // I don't think we use this, either
} else if ( token == "RWY_LIGHTS" ) {
double lon, lat, hdg, len, width;
string common, end1, end2;
<< " codes = " << common << " "
<< end1 << " " << end2 );
} else {
- SG_LOG( SG_TERRAIN, SG_ALERT,
+ SG_LOG( SG_TERRAIN, SG_DEBUG,
"Unknown token " << token << " in "
<< stg_name.str() );
in >> ::skipws;
gnd_lights_transform->setTransform( &sgcoord );
}
+ // Update vasi lights transform
+ if ( vasi_lights_transform->getNumKids() > 0 ) {
+ vasi_lights_transform->setTransform( &sgcoord );
+ }
+
// Update runway lights transform
if ( rwy_lights_transform->getNumKids() > 0 ) {
rwy_lights_transform->setTransform( &sgcoord );
void
-FGTileEntry::add_ssg_nodes( ssgBranch* terrain_branch,
- ssgBranch* gnd_lights_branch,
- ssgBranch* rwy_lights_branch,
- ssgBranch* taxi_lights_branch )
+FGTileEntry::add_ssg_nodes( ssgBranch *terrain_branch,
+ ssgBranch *gnd_lights_branch,
+ ssgBranch *vasi_lights_branch,
+ ssgBranch *rwy_lights_branch,
+ ssgBranch *taxi_lights_branch )
{
// bump up the ref count so we can remove this later without
// having ssg try to free the memory.
gnd_lights_branch->addKid( 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 );
+ 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.
}
}
+ // find the vasi lighting branch
+ if ( vasi_lights_transform ) {
+ pcount = vasi_lights_transform->getNumParents();
+ if ( pcount > 0 ) {
+ // find the first parent (should only be one)
+ ssgBranch *parent = vasi_lights_transform->getParent( 0 ) ;
+ if( parent ) {
+ // disconnect the light branch (we previously ref()'d
+ // it so it won't get freed now)
+ parent->removeKid( vasi_lights_transform );
+ } else {
+ SG_LOG( SG_TERRAIN, SG_ALERT,
+ "parent pointer is NULL! Dying" );
+ exit(-1);
+ }
+ } else {
+ SG_LOG( SG_TERRAIN, SG_ALERT,
+ "Parent count is zero for an ssg light tile! Dying" );
+ exit(-1);
+ }
+ }
+
// find the runway lighting branch
if ( rwy_lights_transform ) {
pcount = rwy_lights_transform->getNumParents();