: 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)
}
}
+ 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
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 *geometry = new ssgBranch;
if ( obj_load( custom_path.str(),
- geometry, NULL, NULL, light_pts, true ) )
+ geometry, NULL, NULL, NULL, light_pts,
+ true ) )
{
new_tile -> addKid( geometry );
} else {
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, rwy_lights, taxi_lights,
- NULL, false ) )
+ 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 {
}
} else {
delete geometry;
+ delete vasi_lights;
delete rwy_lights;
delete taxi_lights;
}
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();
// pointer to ssg transform for this tile
ssgTransform *terra_transform;
+ ssgTransform *vasi_lights_transform;
ssgTransform *rwy_lights_transform;
ssgTransform *taxi_lights_transform;
ssgTransform *gnd_lights_transform;
// via a call back would be nifty, but then the call back needs to
// know about the higher level application's global state which is
// a problem if we move the code into simgear.)
+ ssgSelector *vasi_lights_selector;
ssgSelector *rwy_lights_selector;
ssgSelector *taxi_lights_selector;
bool obj_load( const string& path,
ssgBranch* geometry,
+ ssgBranch* vasi_lights,
ssgBranch* rwy_lights,
ssgBranch* taxi_lights,
ssgVertexArray* gound_lights,
VEC_PTRS = 0x02,
TERRA_NODE = 0x04,
GROUND_LIGHTS = 0x08,
- RWY_LIGHTS = 0x10,
- TAXI_LIGHTS = 0x20,
- LIGHTMAPS = 0x40
+ VASI_LIGHTS = 0x10,
+ RWY_LIGHTS = 0x20,
+ TAXI_LIGHTS = 0x40,
+ LIGHTMAPS = 0x80
};
int free_tracker;
/**
* Add terrain mesh and ground lighting to scene graph.
*/
- void add_ssg_nodes( ssgBranch* terrain_branch,
- ssgBranch* gnd_lights_branch,
- ssgBranch* rwy_lights_branch,
- ssgBranch* taxi_lights_branch );
+ void add_ssg_nodes( ssgBranch *terrain_branch,
+ ssgBranch *gnd_lights_branch,
+ ssgBranch *vasi_lights_branch,
+ ssgBranch *rwy_lights_branch,
+ ssgBranch *taxi_lights_branch );
/**
* disconnect terrain mesh and ground lighting nodes from scene