diff --git a/src/Airports/GenAirports850/build.cxx b/src/Airports/GenAirports850/build.cxx index 20d7ac71..08015563 100644 --- a/src/Airports/GenAirports850/build.cxx +++ b/src/Airports/GenAirports850/build.cxx @@ -289,7 +289,8 @@ void build_airport( string airport_id, float alt_m, string_list& runways_raw, string_list& beacons_raw, string_list& towers_raw, - string_list& windsocks_raw, + string_list& windsocks_raw, + string_list& lights_raw, const string& root, const string_list& elev_src ) { @@ -316,7 +317,6 @@ void build_airport( string airport_id, float alt_m, // parse runways and generate the vertex list runway_list runways; runways.clear(); - runway_list taxiways; taxiways.clear(); for ( i = 0; i < (int)runways_raw.size(); ++i ) { ++rwy_count; @@ -395,16 +395,6 @@ void build_airport( string airport_id, float alt_m, rwy.reil1 = atoi( token[16].c_str() ); rwy.reil2 = atoi( token[25].c_str() ); - - if (token.size()>15) { - string vasi_angles = token[15]; - vector vasis = simgear::strutils::split( vasi_angles, "." ); - rwy.gs_angle1 = atof( vasis[0].c_str() ) * 0.01; - rwy.gs_angle2 = atof( vasis[1].c_str() ) * 0.01; - } else { - rwy.gs_angle1 = rwy.gs_angle2 = 3.0; - } - SG_LOG( SG_GENERAL, SG_DEBUG, " no1/2 = " << rwy.rwy_no1 << " " << rwy.rwy_no2); SG_LOG( SG_GENERAL, SG_DEBUG, " lat = " << rwy.lat); SG_LOG( SG_GENERAL, SG_DEBUG, " lon = " << rwy.lon); @@ -422,7 +412,6 @@ void build_airport( string airport_id, float alt_m, runways.push_back( rwy ); } SG_LOG(SG_GENERAL, SG_INFO, "Runway count = " << runways.size() ); - SG_LOG(SG_GENERAL, SG_INFO, "Taxiway count = " << taxiways.size() ); SGBucket b( apt_lon / (double)rwy_count, apt_lat / (double)rwy_count ); SG_LOG(SG_GENERAL, SG_INFO, b.gen_base_path() << "/" << b.gen_index_str()); @@ -492,6 +481,26 @@ void build_airport( string airport_id, float alt_m, } + + // parse all light objects (PAPI/VASI) etc. + light_list lightobj; lightobj.clear(); + for ( i = 0; i < (int)lights_raw.size(); ++i ) { + string light_str = lights_raw[i]; + vector token = simgear::strutils::split( light_str ); + + TGLightobj light; + + light.lat = atof( token[1].c_str() ); + light.lon = atof( token[2].c_str() ); + light.type = atoi( token[3].c_str() ); + light.heading = atof( token[4].c_str() ); + light.glideslope = atof( token[5].c_str() ); + light.rwy_name = token[6]; + lightobj.push_back( light ); + } + + +//TODO: Clean up // First pass: generate the precision runways since these have // precidence for ( i = 0; i < (int)runways.size(); ++i ) { @@ -536,17 +545,6 @@ void build_airport( string airport_id, float alt_m, } } - // 4th pass: generate all taxiways - - /* Ralf Gerlich: Generate Taxiways in specified order from bottom to top */ - for ( i=0; i 360.0 ) { length_hdg -= 360.0; } - flag = rwy_info.rwy_no1 + "-i"; - gs_angle = rwy_info.gs_angle1; - } else { - ref = corner[2]; - length_hdg = rwy_info.heading; - flag = rwy_info.rwy_no1; - gs_angle = rwy_info.gs_angle2; - } + double gs_angle = rwy_light.glideslope; + double left_hdg = rwy_light.heading - 90.0; + + ref.setlat( rwy_light.lat ); + ref.setlon( rwy_light.lon ); - left_hdg = length_hdg - 90.0; if ( left_hdg < 0 ) { left_hdg += 360.0; } - cout << "length hdg = " << length_hdg - << " left heading = " << left_hdg << endl; if ( gs_angle < 0.5 ) { gs_angle = 3.0; } - // offset 950' upwind - geo_direct_wgs_84 ( alt_m, ref.lat(), ref.lon(), length_hdg, - 950 * 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 ); + // Calculate the normal once for all object parts. + // SG takes care of the angle. + + // calculate a second point in the object heading direction + geo_direct_wgs_84 ( rwy_light.lat, rwy_light.lon, rwy_light.heading, + 100, &lat, &lon, &r); + + Point3D end1, end2; + + end1.setlat( lat ); + end1.setlon( lon ); + + end2.setlat( rwy_light.lat); + end2.setlon( rwy_light.lon); + + Point3D cart1 = sgGeodToCart( end1 * SG_DEGREES_TO_RADIANS ); + Point3D cart2 = sgGeodToCart( end2 * SG_DEGREES_TO_RADIANS ); + + Point3D up = cart1; + double length = up.distance3D( Point3D(0.0) ); + up = up / length; + + Point3D obj_vec = cart2 - cart1; + + // angle up specified amount + length = obj_vec.distance3D( Point3D(0.0) ); + double up_length = length * tan( rwy_light.glideslope * SG_DEGREES_TO_RADIANS); + Point3D light_vec = obj_vec + (up * up_length); + + length = light_vec.distance3D( Point3D(0.0) ); + Point3D normal = light_vec / length; + + SG_LOG(SG_GENERAL, SG_DEBUG, "obj_normal = " << normal); + + // We know our normal, now create the lights // unit1 Point3D pt1 = ref; - lights.push_back( pt1 ); - normal = gen_runway_light_vector( rwy_info, gs_angle + 0.5, recip ); + lightobj.push_back( pt1 ); normals.push_back( normal ); // unit2 geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg, 30 * SG_FEET_TO_METER, &lat, &lon, &r ); pt1 = Point3D( lon, lat, 0.0 ); - lights.push_back( pt1 ); - normal = gen_runway_light_vector( rwy_info, gs_angle + 0.167, recip ); + lightobj.push_back( pt1 ); normals.push_back( normal ); // unit3 geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg, 30 * SG_FEET_TO_METER, &lat, &lon, &r ); pt1 = Point3D( lon, lat, 0.0 ); - lights.push_back( pt1 ); - normal = gen_runway_light_vector( rwy_info, gs_angle - 0.167, recip ); + lightobj.push_back( pt1 ); normals.push_back( normal ); // unit4 geo_direct_wgs_84 ( alt_m, pt1.lat(), pt1.lon(), left_hdg, 30 * SG_FEET_TO_METER, &lat, &lon, &r ); pt1 = Point3D( lon, lat, 0.0 ); - lights.push_back( pt1 ); - normal = gen_runway_light_vector( rwy_info, gs_angle - 0.5, recip ); + lightobj.push_back( pt1 ); normals.push_back( normal ); - // grass base + /* // grass base Point3D base_pt = (ref + pt1) / 2.0; TGPolygon obj_base = gen_wgs84_area( base_pt, 15.0, 0.0, 0.0, 30.0, length_hdg, alt_m, false ); - *apt_base = tgPolygonUnion( obj_base, *apt_base ); + *apt_base = tgPolygonUnion( obj_base, *apt_base );*/ TGPolygon lights_poly; lights_poly.erase(); TGPolygon normals_poly; normals_poly.erase(); - lights_poly.add_contour( lights, false ); + lights_poly.add_contour( lightobj, false ); normals_poly.add_contour( normals, false ); TGSuperPoly result; @@ -958,9 +951,7 @@ static TGSuperPoly gen_papi( const TGRunway& rwy_info, float alt_m, result.set_normals( normals_poly ); result.set_material( "RWY_VASI_LIGHTS" ); - result.set_flag( flag ); - - return result; + lights.push_back( result); } @@ -2667,23 +2658,8 @@ void gen_runway_lights( const TGRunway& rwy_info, float alt_m, TGSuperPoly s = gen_reil( rwy_info, alt_m, true ); lights.push_back( s ); } -#if 0 - // VASI/PAPI lighting - if ( vasi1 == 2 /* Has VASI */ ) { - TGSuperPoly s = gen_vasi( rwy_info, alt_m, false, apt_base ); - lights.push_back( s ); - } else if ( vasi1 == 3 /* Has PAPI */ ) { - TGSuperPoly s = gen_papi( rwy_info, alt_m, false, apt_base ); - lights.push_back( s ); - } - if ( vasi2 == 2 /* Has VASI */ ) { - TGSuperPoly s = gen_vasi( rwy_info, alt_m, true, apt_base ); - lights.push_back( s ); - } else if ( vasi2 == 3 /* Has PAPI */ ) { - TGSuperPoly s = gen_papi( rwy_info, alt_m, true, apt_base ); - lights.push_back( s ); - } -#endif + + // Approach lighting //////////////////////////////////////////////////////////// diff --git a/src/Airports/GenAirports850/lights.hxx b/src/Airports/GenAirports850/lights.hxx index 09575900..5d5f3dde 100644 --- a/src/Airports/GenAirports850/lights.hxx +++ b/src/Airports/GenAirports850/lights.hxx @@ -41,4 +41,7 @@ void gen_runway_lights( const TGRunway& rwy_info, float alt_m, void gen_taxiway_lights( const TGRunway& taxiway_info, float alt_m, superpoly_list &lights ); +// generate light objects +void gen_airport_lightobj( const TGLightobj& rwy_light, float alt_m, superpoly_list &lights ); + #endif // _RWY_LIGHTS_HXX diff --git a/src/Airports/GenAirports850/main.cxx b/src/Airports/GenAirports850/main.cxx index ff89e1a6..ed8e6b2f 100644 --- a/src/Airports/GenAirports850/main.cxx +++ b/src/Airports/GenAirports850/main.cxx @@ -251,6 +251,7 @@ int main( int argc, char **argv ) { string_list beacon_list; string_list tower_list; string_list windsock_list; + string_list light_list; vector token; string last_apt_id = ""; @@ -335,6 +336,7 @@ int main( int argc, char **argv ) { beacon_list, tower_list, windsock_list, + light_list, work_dir, elev_src ); } } @@ -367,6 +369,7 @@ int main( int argc, char **argv ) { beacon_list.clear(); tower_list.clear(); windsock_list.clear(); + light_list.clear(); } else if ( token[0] == "100" ) { // runway entry runways_list.push_back(line); @@ -380,7 +383,8 @@ int main( int argc, char **argv ) { // windsock entry windsock_list.push_back(line); } else if ( token[0] == "21" ) { - // light object + // PAPI / VASI list + light_list.push_back(line); } else if ( token[0] == "15" ) { // ignore custom startup locations } else if ( token[0] == "50" || token[0] == "51" || token[0] == "52" @@ -439,6 +443,7 @@ int main( int argc, char **argv ) { beacon_list, tower_list, windsock_list, + light_list, work_dir, elev_src ); } } diff --git a/src/Airports/GenAirports850/runway.hxx b/src/Airports/GenAirports850/runway.hxx index 4ed6aa6b..c08435bb 100644 --- a/src/Airports/GenAirports850/runway.hxx +++ b/src/Airports/GenAirports850/runway.hxx @@ -64,9 +64,6 @@ struct TGRunway { bool dist_remaining; - double gs_angle1; - double gs_angle2; - TGPolygon threshold; TGPolygon tens, tens_margin, ones, ones_margin; TGPolygon letter, letter_margin_left, letter_margin_right; @@ -75,12 +72,24 @@ struct TGRunway { TGPolygon aim_point; bool generated; }; - - typedef std::vector < TGRunway > runway_list; typedef runway_list::iterator runway_list_iterator; typedef runway_list::const_iterator const_runway_list_iterator; +struct TGLightobj { + double lon; + double lat; + int type; + double heading; + double glideslope; + std::string rwy_name; +}; +typedef std::vector < TGLightobj > light_list; +typedef light_list::iterator light_list_iterator; +typedef light_list::const_iterator const_light_list_iterator; + + + // given a runway center point, length, width, and heading, and // altitude (meters) generate the lon and lat 4 corners using wgs84