From b14614987774dc161c7d89565211b966881dc22f Mon Sep 17 00:00:00 2001 From: Christian Schmitt <chris@ilovelinux.de> Date: Wed, 5 Oct 2011 10:56:34 +0200 Subject: [PATCH] Port airport light objects support --- src/Airports/GenAirports850/CMakeLists.txt | 1 + src/Airports/GenAirports850/airport.cxx | 8 ++ src/Airports/GenAirports850/airport.hxx | 7 + src/Airports/GenAirports850/object.cxx | 107 ++++++++++++++ src/Airports/GenAirports850/object.hxx | 32 +++++ src/Airports/GenAirports850/parser.cxx | 2 + src/Airports/GenAirports850/parser.hxx | 1 + src/Airports/GenAirports850/runway.cxx | 155 --------------------- 8 files changed, 158 insertions(+), 155 deletions(-) create mode 100644 src/Airports/GenAirports850/object.cxx create mode 100644 src/Airports/GenAirports850/object.hxx diff --git a/src/Airports/GenAirports850/CMakeLists.txt b/src/Airports/GenAirports850/CMakeLists.txt index f0e909d9..8f0e6b9c 100644 --- a/src/Airports/GenAirports850/CMakeLists.txt +++ b/src/Airports/GenAirports850/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable(genapts850 lights.cxx linearfeature.hxx linearfeature.cxx main.cxx + object.hxx object.cxx parser.hxx parser.cxx point2d.cxx point2d.hxx poly_extra.cxx poly_extra.hxx diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index 7fb1cb9f..0e65617e 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -383,6 +383,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) } } + if (lightobjects.size()) + { + for ( i=0; i<lightobjects.size(); i++ ) + { + lightobjects[i]->BuildBtg( altitude, &rwy_lights ); + } + } + // Build the pavements if (pavements.size()) { diff --git a/src/Airports/GenAirports850/airport.hxx b/src/Airports/GenAirports850/airport.hxx index a8375808..157b0195 100644 --- a/src/Airports/GenAirports850/airport.hxx +++ b/src/Airports/GenAirports850/airport.hxx @@ -5,6 +5,7 @@ #include <stdlib.h> #include "runway.hxx" +#include "object.hxx" #include "closedpoly.hxx" #include "linearfeature.hxx" @@ -20,6 +21,11 @@ public: runways.push_back( runway ); } + void AddObj( LightingObj* lightobj ) + { + lightobjects.push_back( lightobj ); + } + void AddPavement( ClosedPoly* pavement ) { pavements.push_back( pavement ); @@ -51,6 +57,7 @@ private: PavementList pavements; FeatureList features; RunwayList runways; + LightingObjList lightobjects; }; typedef std::vector <Airport *> AirportList; diff --git a/src/Airports/GenAirports850/object.cxx b/src/Airports/GenAirports850/object.cxx new file mode 100644 index 00000000..268bf81e --- /dev/null +++ b/src/Airports/GenAirports850/object.cxx @@ -0,0 +1,107 @@ +#include <simgear/math/sg_geodesy.hxx> +#include <simgear/debug/logstream.hxx> +#include "object.hxx" + +LightingObj::LightingObj( char* definition ) +{ + sscanf(definition, "%lf %lf %d %lf %lf %s", &lat, &lon, &type, &heading, &glideslope, &assoc_rw); + + SG_LOG(SG_GENERAL, SG_DEBUG, "Read lighting object: (" << lon << "," << lat << ") heading: " << heading << " type: " << type ); +} + +void LightingObj::BuildBtg( int alt_m, superpoly_list* lights ) +{ + point_list lightobj; lightobj.clear(); + point_list normals; normals.clear(); + + + + Point3D ref; + double lon2, lat2, r; + double left_hdg = heading - 90.0; + + ref.setlat( lat ); + ref.setlon( lon ); + + if ( left_hdg < 0 ) { left_hdg += 360.0; } + + if ( glideslope < 0.5 ) { + glideslope = 3.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 ( lat, lon, heading, + 100, &lat2, &lon2, &r); + + Point3D end1, end2; + + end1.setlat( lat2 ); + end1.setlon( lon2 ); + + end2.setlat( lat); + end2.setlon( 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( 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 + SG_LOG(SG_GENERAL, SG_DEBUG, "Generating PAPI = " << assoc_rw); + + // unit1 + Point3D pt1 = ref; + 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, &lat2, &lon2, &r ); + pt1 = Point3D( lon2, lat2, 0.0 ); + 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, &lat2, &lon2, &r ); + pt1 = Point3D( lon2, lat2, 0.0 ); + 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, &lat2, &lon2, &r ); + pt1 = Point3D( lon2, lat2, 0.0 ); + lightobj.push_back( pt1 ); + normals.push_back( normal ); + + TGPolygon lights_poly; lights_poly.erase(); + TGPolygon normals_poly; normals_poly.erase(); + lights_poly.add_contour( lightobj, false ); + normals_poly.add_contour( normals, false ); + + TGSuperPoly result; + result.set_poly( lights_poly ); + result.set_normals( normals_poly ); + result.set_material( "RWY_VASI_LIGHTS" ); + + lights->push_back( result); +} diff --git a/src/Airports/GenAirports850/object.hxx b/src/Airports/GenAirports850/object.hxx new file mode 100644 index 00000000..51006e21 --- /dev/null +++ b/src/Airports/GenAirports850/object.hxx @@ -0,0 +1,32 @@ +#ifndef _OBJECT_H_ +#define _OBJECT_H_ + +#include <stdio.h> +#include <stdlib.h> + +#include <Polygon/polygon.hxx> +#include <Polygon/superpoly.hxx> +#include <Geometry/point3d.hxx> + +#include "texparams.hxx" + +using std::string; + +class LightingObj +{ +public: + LightingObj(char* def); + + double lat; + double lon; + int type; + double heading; + double glideslope; + char assoc_rw; + + +void BuildBtg( int alt_m, superpoly_list* lights ); + +}; +typedef std::vector <LightingObj *> LightingObjList; +#endif \ No newline at end of file diff --git a/src/Airports/GenAirports850/parser.cxx b/src/Airports/GenAirports850/parser.cxx index 62411b41..d6a09e42 100644 --- a/src/Airports/GenAirports850/parser.cxx +++ b/src/Airports/GenAirports850/parser.cxx @@ -402,6 +402,8 @@ int Parser::ParseLine(char* line) case LIGHTING_OBJECT: SetState( STATE_PARSE_SIMPLE ); SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line); + cur_object = new LightingObj(line); + cur_airport->AddObj( cur_object ); break; case COMM_FREQ1_CODE: SetState( STATE_PARSE_SIMPLE ); diff --git a/src/Airports/GenAirports850/parser.hxx b/src/Airports/GenAirports850/parser.hxx index a8f9328c..11e8b4e4 100644 --- a/src/Airports/GenAirports850/parser.hxx +++ b/src/Airports/GenAirports850/parser.hxx @@ -89,6 +89,7 @@ private: ClosedPoly* cur_pavement; LinearFeature* cur_feat; BezNode* prev_node; + LightingObj* cur_object; AirportList airports; diff --git a/src/Airports/GenAirports850/runway.cxx b/src/Airports/GenAirports850/runway.cxx index dd2c0121..2736daa9 100644 --- a/src/Airports/GenAirports850/runway.cxx +++ b/src/Airports/GenAirports850/runway.cxx @@ -214,161 +214,6 @@ TGPolygon Runway::gen_runway_w_mid( double alt_m, double length_extend_m, double return result_list; } -#if 0 -void Runway::gen_simple_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, TGPolygon *accum ) -{ - Point3D mp, end[2]; - int i; - - // create the runway in two halves, as markings may be different in each direction - end[0] = GetStart(); - mp = GetMidpoint(); - end[1] = GetEnd(); - - for (i=0; i<2; i++) - { - gen_simple_half( alt_m, mp, end[i], material, rwy_polys, texparams, accum ); - } -} -#endif - -/*void gen_simple_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, TGPolygon *accum ) -{ - int j, k; - - TGPolygon runway = gen_runway_w_mid( alt_m, 0.0, 0.0 ); - - // runway half "a" - TGPolygon runway_a; - runway_a.erase(); - runway_a.add_node( 0, runway.get_pt(0, 0) ); - runway_a.add_node( 0, runway.get_pt(0, 1) ); - runway_a.add_node( 0, runway.get_pt(0, 2) ); - runway_a.add_node( 0, runway.get_pt(0, 5) ); - - // runway half "b" - TGPolygon runway_b; - runway_b.erase(); - runway_b.add_node( 0, runway.get_pt(0, 5) ); - runway_b.add_node( 0, runway.get_pt(0, 2) ); - runway_b.add_node( 0, runway.get_pt(0, 3) ); - runway_b.add_node( 0, runway.get_pt(0, 4) ); - - Point3D p; - SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway pts (a half)"); - for ( j = 0; j < runway_a.contour_size( 0 ); ++j ) - { - p = runway_a.get_pt(0, j); - SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p); - } - SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway pts (b half)"); - for ( j = 0; j < runway_b.contour_size( 0 ); ++j ) - { - p = runway_b.get_pt(0, j); - SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p); - } - - // do this before clipping and generating the base - runway_a = remove_dups( runway_a ); - runway_a = reduce_degeneracy( runway_a ); - - runway_b = remove_dups( runway_b ); - runway_b = reduce_degeneracy( runway_b ); - - TGSuperPoly sp; - TGTexParams tp; - - TGPolygon clipped_a = tgPolygonDiff( runway_a, *accum ); - TGPolygon split_a = tgPolygonSplitLongEdges( clipped_a, 400.0 ); - sp.erase(); - sp.set_poly( split_a ); - sp.set_material( material ); - rwy_polys->push_back( sp ); - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped_a = " << clipped_a.contours()); - *accum = tgPolygonUnion( runway_a, *accum ); - tp = TGTexParams( runway_a.get_pt(0,0), rwy.width, rwy.length/2.0, rwy.heading ); - texparams->push_back( tp ); - - TGPolygon clipped_b = tgPolygonDiff( runway_b, *accum ); - TGPolygon split_b = tgPolygonSplitLongEdges( clipped_b, 400.0 ); - sp.erase(); - sp.set_poly( split_b ); - sp.set_material( material ); - rwy_polys->push_back( sp ); - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped_b = " << clipped_b.contours()); - *accum = tgPolygonUnion( runway_b, *accum ); - tp = TGTexParams( runway_b.get_pt(0,2), rwy.width, rwy.length/2.0, rwy.heading+180.0 ); - texparams->push_back( tp ); - - // print runway points - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped runway pts (a)"); - for ( j = 0; j < clipped_a.contours(); ++j ) - { - for ( k = 0; k < clipped_a.contour_size( j ); ++k ) - { - p = clipped_a.get_pt(j, k); - SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p); - } - } - - // print runway points - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped runway pts (b)"); - for ( j = 0; j < clipped_b.contours(); ++j ) - { - for ( k = 0; k < clipped_b.contour_size( j ); ++k ) - { - p = clipped_b.get_pt(j, k); - SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p); - } - } - -#if 0 - gen_runway_stopway( rwy_info, runway_a, runway_b, - material, - rwy_polys, texparams, accum ); -#endif -}*/ - -#if 0 -void Runway::gen_marked_rwy( double alt_m, const string& material, superpoly_list *rwy_polys, texparams_list *texparams, TGPolygon *accum ) -{ - Point3D mp, end[2]; - int i; - - // create the runway in two halves, as markings may be different in each direction - end[0] = GetStart(); - mp = GetMidpoint(); - end[1] = GetEnd(); - - for (i=0; i<2; i++) - { - // first, create half 'a' - switch( marking[i] ) - { - case 0: - case 1: // Visual - SG_LOG( SG_GENERAL, SG_ALERT, "Half " << i << ": has Visual marking"); - gen_visual_half( alt_m, mp, end[i], material, rwy_polys, texparams, accum ); - break; - - case 2: // non-precision - SG_LOG( SG_GENERAL, SG_ALERT, "Half " << i << ": has Non Precision marking"); - gen_non_precision_half( alt_m, mp, end[i], material, rwy_polys, texparams, accum ); - break; - - case 3: // precision - SG_LOG( SG_GENERAL, SG_ALERT, "Half " << i << ": has Precision marking"); - //gen_precision_half( alt_m, mp, end[i], material, rwy_polys, texparams, accum ); - gen_simple_half( alt_m, mp, end[i], material, rwy_polys, texparams, accum ); - break; - - default: // unknown - SG_LOG( SG_GENERAL, SG_ALERT, "Half " << i << ": has unknown marking"); - break; - } - } -} -#endif int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ) {