1
0
Fork 0

Beginning work on generating/placing VASI lights.

Ooops, I noticed my light infrastructure is insufficient, I need to add
support for creating multiple groups of lights with different types.
This commit is contained in:
curt 2002-10-08 22:25:01 +00:00
parent 9b63deeb03
commit 4fb0ca1e2b
5 changed files with 276 additions and 37 deletions

View file

@ -347,7 +347,7 @@ void build_runway( const FGRunway& rwy_info,
// build 3d airport
void build_airport( string airport_raw, string_list& runways_raw,
void build_airport( string airport_raw, float alt_m, string_list& runways_raw,
string_list& taxiways_raw, const string& root )
{
int i, j, k;
@ -567,7 +567,7 @@ void build_airport( string airport_raw, string_list& runways_raw,
point_list rwy_lights; rwy_lights.clear();
point_list rwy_light_normals; rwy_light_normals.clear();
for ( i = 0; i < (int)runways.size(); ++i ) {
gen_runway_lights( runways[i], &rwy_lights, &rwy_light_normals );
gen_runway_lights( runways[i], alt_m, &rwy_lights, &rwy_light_normals );
}
// generate convex hull (no longer)

View file

@ -34,7 +34,7 @@
// build 3d airport
void build_airport( string airport, string_list& runways_raw,
void build_airport( string airport, float alt_m, string_list& runways_raw,
string_list& taxiways_raw, const string& root );

View file

@ -27,21 +27,75 @@
#include "lights.hxx"
// calculate the runway light direction vector. I don't want to think
// about matrix transformations tonight, so instead I can take the
// center of one runway end - the center of the other end to get the
// direction of the runway. Combine this with an appropriate portion
// of the local 'up' vector gives the light direction vector for the
// runway.
Point3D gen_runway_light_vector( const FGRunway& rwy_info ) {
// calculate the runway light direction vector. We take the center of
// one runway end - the center of the other end to get the direction
// of the runway. Combine this with an appropriate portion of the
// local 'up' vector based on the provide 'angle' gives the light
// direction vector for the runway.
static Point3D gen_runway_light_vector( const FGRunway& rwy_info,
double angle, bool recip ) {
double length;
// Generate the 4 corners of the runway
FGPolygon poly_corners = gen_runway_area_w_expand( rwy_info, 0.0, 0.0 );
point_list corner;
for ( int i = 0; i < poly_corners.contour_size( 0 ); ++i ) {
corner.push_back( poly_corners.get_pt( 0, i ) );
}
Point3D end1 = (corner[0] + corner[1]) / 2.0;
Point3D end2 = (corner[2] + corner[3]) / 2.0;
Point3D end1, end2;
if ( !recip ) {
end1 = (corner[0] + corner[1]) / 2.0;
end2 = (corner[2] + corner[3]) / 2.0;
} else {
end2 = (corner[0] + corner[1]) / 2.0;
end1 = (corner[2] + corner[3]) / 2.0;
}
Point3D cart1 = sgGeodToCart( end1 * SG_DEGREES_TO_RADIANS );
Point3D cart2 = sgGeodToCart( end2 * SG_DEGREES_TO_RADIANS );
cout << "cart1 = " << cart1 << " cart2 = " << cart2 << endl;
Point3D up = cart1;
length = up.distance3D( Point3D(0.0) );
up = up / length;
Point3D rwy_vec = cart2 - cart1;
cout << "rwy_vec = " << rwy_vec << endl;
// angle up specified amount
length = rwy_vec.distance3D( Point3D(0.0) );
double up_length = length * tan(angle * SG_DEGREES_TO_RADIANS);
Point3D light_vec = rwy_vec + (up * up_length);
length = light_vec.distance3D( Point3D(0.0) );
light_vec = light_vec / length;
return light_vec;
}
// calculate the runway length vector. We take the center of one
// runway end - the center of the other end to get the direction of
// the runway.
static Point3D gen_runway_length_vector( const FGRunway& rwy_info, bool recip )
{
double length;
// Generate the 4 corners of the runway
FGPolygon poly_corners = gen_runway_area_w_expand( rwy_info, 0.0, 0.0 );
point_list corner;
for ( int i = 0; i < poly_corners.contour_size( 0 ); ++i ) {
corner.push_back( poly_corners.get_pt( 0, i ) );
}
Point3D end1, end2;
if ( recip ) {
end2 = (corner[0] + corner[1]) / 2.0;
end1 = (corner[2] + corner[3]) / 2.0;
} else {
end1 = (corner[0] + corner[1]) / 2.0;
end2 = (corner[2] + corner[3]) / 2.0;
}
Point3D cart1 = sgGeodToCart( end1 * SG_DEGREES_TO_RADIANS );
Point3D cart2 = sgGeodToCart( end2 * SG_DEGREES_TO_RADIANS );
cout << "cart1 = " << cart1 << " cart2 = " << cart2 << endl;
@ -49,24 +103,59 @@ Point3D gen_runway_light_vector( const FGRunway& rwy_info ) {
Point3D rwy_vec = cart2 - cart1;
cout << "rwy_vec = " << rwy_vec << endl;
// FIXME
// need to angle up (i.e. 3 degrees)
length = rwy_vec.distance3D( Point3D(0.0) );
rwy_vec = rwy_vec / length;
double length = rwy_vec.distance3D( Point3D(0.0) );
return rwy_vec / length;
return rwy_vec;
}
// calculate a vector orthogonal to the runway direction in the
// surface plane. As you approach the runway, positive will be left.
static Point3D gen_runway_left_vector( const FGRunway& rwy_info, bool recip )
{
double length;
// Generate the 4 corners of the runway
FGPolygon poly_corners = gen_runway_area_w_expand( rwy_info, 0.0, 0.0 );
point_list corner;
for ( int i = 0; i < poly_corners.contour_size( 0 ); ++i ) {
corner.push_back( poly_corners.get_pt( 0, i ) );
}
Point3D end1, end2;
if ( recip ) {
end1 = corner[2];
end2 = corner[3];
} else {
end1 = corner[0];
end2 = corner[1];
}
Point3D cart1 = sgGeodToCart( end1 * SG_DEGREES_TO_RADIANS );
Point3D cart2 = sgGeodToCart( end2 * SG_DEGREES_TO_RADIANS );
cout << "cart1 = " << cart1 << " cart2 = " << cart2 << endl;
Point3D left_vec = cart2 - cart1;
cout << "left_vec = " << left_vec << endl;
length = left_vec.distance3D( Point3D(0.0) );
left_vec = left_vec / length;
return left_vec;
}
// generate runway edge lighting
// 60 meters spacing or the next number down that divides evenly.
void gen_runway_edge_lights( const FGRunway& rwy_info,
point_list *lights, point_list *normals ) {
static void gen_runway_edge_lights( const FGRunway& rwy_info,
point_list *lights, point_list *normals,
bool recip ) {
int i;
double len = rwy_info.length * SG_FEET_TO_METER;
int divs = (int)(len / 60.0) + 1;
Point3D normal = gen_runway_light_vector( rwy_info );
Point3D normal = gen_runway_light_vector( rwy_info, 3.0, recip );
// using FGPolygon is a bit innefficient, but that's what the
// routine returns.
@ -77,11 +166,21 @@ void gen_runway_edge_lights( const FGRunway& rwy_info,
corner.push_back( poly_corners.get_pt( 0, i ) );
}
Point3D inc1 = (corner[3] - corner[0]) / divs;
Point3D inc2 = (corner[2] - corner[1]) / divs;
Point3D inc1, inc2;
Point3D pt1, pt2;
if ( recip ) {
inc1 = (corner[0] - corner[3]) / divs;
inc2 = (corner[1] - corner[2]) / divs;
pt1 = corner[3];
pt2 = corner[2];
} else {
inc1 = (corner[3] - corner[0]) / divs;
inc2 = (corner[2] - corner[1]) / divs;
pt1 = corner[0];
pt2 = corner[1];
}
Point3D pt1 = corner[0];
Point3D pt2 = corner[1];
lights->push_back( pt1 );
normals->push_back( normal );
lights->push_back( pt2 );
@ -98,8 +197,141 @@ void gen_runway_edge_lights( const FGRunway& rwy_info,
}
void gen_runway_lights( const FGRunway& rwy_info,
point_list *lights, point_list *normals ) {
// Make edge lighting
gen_runway_edge_lights( rwy_info, lights, normals );
// generate a simple 2 bar VASI
static void gen_vasi( const FGRunway& rwy_info, float alt_m,
point_list *lights, point_list *normals,
bool recip ) {
int i;
cout << "gen vasi " << rwy_info.rwy_no << endl;
Point3D normal;
// using FGPolygon is a bit innefficient, but that's what the
// routine returns.
FGPolygon poly_corners = gen_runway_area_w_expand( rwy_info, 0.0, 0.0 );
point_list corner;
for ( i = 0; i < poly_corners.contour_size( 0 ); ++i ) {
corner.push_back( poly_corners.get_pt( 0, i ) );
}
// determine the start point.
Point3D ref;
double length_hdg, left_hdg;
double lon, lat, r;
if ( recip ) {
ref = corner[0];
length_hdg = 360.0 - rwy_info.heading;
} else {
ref = corner[2];
length_hdg = rwy_info.heading;
}
left_hdg = length_hdg - 90.0;
if ( left_hdg < 0 ) { left_hdg += 360.0; }
// offset 600' upwind
geo_direct_wgs_84 ( alt_m, ref.lat(), ref.lon(), length_hdg,
600 * SG_FEET_TO_METER, &lat, &lon, &r );
ref = Point3D( lon, lat, 0.0 );
// offset 50' left
geo_direct_wgs_84 ( alt_m, ref.lat(), ref.lon(), left_hdg,
50 * SG_FEET_TO_METER, &lat, &lon, &r );
ref = Point3D( lon, lat, 0.0 );
// downwind bar
normal = gen_runway_light_vector( rwy_info, 2.5, recip );
// unit1
Point3D pt1 = ref;
lights->push_back( pt1 );
normals->push_back( normal );
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
1 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
// unit2
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
16 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
1 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
// unit3
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
16 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
1 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
// upwind bar
normal = gen_runway_light_vector( rwy_info, 3.0, recip );
// unit1
pt1 = ref;
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), length_hdg,
700 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
1 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
// unit2
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
16 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
1 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
// unit3
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
16 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg,
1 * SG_FEET_TO_METER, &lat, &lon, &r );
pt1 = Point3D( lon, lat, 0.0 );
lights->push_back( pt1 );
normals->push_back( normal );
}
void gen_runway_lights( const FGRunway& rwy_info, float alt_m,
point_list *lights, point_list *normals ) {
cout << "gen runway lights " << rwy_info.rwy_no << " " << rwy_info.end1_flags << " " << rwy_info.end2_flags << endl;;
// Approach lighting
if ( rwy_info.end1_flags.substr(2,1) == "V" ) {
gen_vasi( rwy_info, alt_m, lights, normals, false );
}
if ( rwy_info.end2_flags.substr(2,1) == "V" ) {
gen_vasi( rwy_info, alt_m, lights, normals, true );
}
// Make edge lighting
gen_runway_edge_lights( rwy_info, lights, normals, false );
gen_runway_edge_lights( rwy_info, lights, normals, true );
}

View file

@ -34,7 +34,7 @@
// generate runway lighting
void gen_runway_lights( const FGRunway& rwy_info,
void gen_runway_lights( const FGRunway& rwy_info, float alt_m,
point_list *lights, point_list *normals );

View file

@ -175,10 +175,11 @@ int main( int argc, char **argv ) {
if ( !last_airport.empty() ) {
char ctmp, id[32];
float lat, lon;
sscanf( last_airport.c_str(), "%c %s %f %f",
&ctmp, id, &lat, &lon);
SG_LOG(SG_GENERAL, SG_DEBUG, "Airport lat/lon = "
<< lat << ',' << lon);
int alt_ft;
sscanf( last_airport.c_str(), "%c %s %f %f %d",
&ctmp, id, &lat, &lon, &alt_ft);
SG_LOG(SG_GENERAL, SG_DEBUG, "Airport lat/lon/alt = "
<< lat << ',' << lon << "," << alt_ft);
SG_LOG(SG_GENERAL, SG_DEBUG, "Id portion = " << id);
if (lon >= min_lon && lon <= max_lon &&
@ -197,8 +198,8 @@ int main( int argc, char **argv ) {
// process previous record
// process_airport(last_airport, runways_list, argv[2]);
try {
build_airport( last_airport, runways_list, taxiways_list,
work_dir );
build_airport( last_airport, alt_ft * SG_FEET_TO_METER,
runways_list, taxiways_list, work_dir );
} catch (sg_exception &e) {
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to build airport "
<< id);
@ -234,8 +235,13 @@ int main( int argc, char **argv ) {
if ( last_airport.length() ) {
char ctmp, id[32];
sscanf( last_airport.c_str(), "%c %s", &ctmp, id );
SG_LOG(SG_GENERAL, SG_DEBUG, "Id portion = " << id);
float lat, lon;
int alt_ft;
sscanf( last_airport.c_str(), "%c %s %f %f %d",
&ctmp, id, &lat, &lon, &alt_ft);
SG_LOG(SG_GENERAL, SG_DEBUG, "Airport lat/lon/alt = "
<< lat << ',' << lon << "," << alt_ft);
SG_LOG(SG_GENERAL, SG_DEBUG, "Id portion = " << id);
if ( start_id.length() && start_id == id ) {
ready_to_go = true;
@ -244,7 +250,8 @@ int main( int argc, char **argv ) {
if ( ready_to_go ) {
// process previous record
// process_airport(last_airport, runways_list, argv[2]);
build_airport(last_airport, runways_list, taxiways_list, work_dir);
build_airport(last_airport, alt_ft * SG_FEET_TO_METER,
runways_list, taxiways_list, work_dir);
}
}