diff --git a/src/Airports/GenAirports850/helipad.cxx b/src/Airports/GenAirports850/helipad.cxx index 732b9cdc..dab462ee 100644 --- a/src/Airports/GenAirports850/helipad.cxx +++ b/src/Airports/GenAirports850/helipad.cxx @@ -14,7 +14,6 @@ // #include -#include #include #include @@ -41,197 +40,37 @@ Helipad::Helipad(char* definition) SG_LOG(SG_GENERAL, SG_DEBUG, "Read helipad: (" << heli.lon << "," << heli.lat << ") heading: " << heli.heading << " length: " << heli.length << " width: " << heli.width ); } -// generate a section of texture -void Helipad::gen_helipad( const TGPolygon& runway, - double startl_pct, double endl_pct, - double startw_pct, double endw_pct, - double minu, double maxu, double minv, double maxv, - double heading, - const string& prefix, - const string& material, - superpoly_list *rwy_polys, - texparams_list *texparams, - ClipPolyType *accum, - poly_list& slivers ) -{ - int j, k; - double width = heli.width; - double length = heli.length; +superpoly_list Helipad::gen_helipad_lights(double maxsize){ - Point3D a0 = runway.get_pt(0, 1); - Point3D a1 = runway.get_pt(0, 2); - Point3D a2 = runway.get_pt(0, 0); - Point3D a3 = runway.get_pt(0, 3); + point_list g_lights; g_lights.clear(); + point_list g_normals; g_normals.clear(); - if ( startl_pct > 0.0 ) { - startl_pct -= nudge * SG_EPSILON; - } - if ( endl_pct < 1.0 ) { - endl_pct += nudge * SG_EPSILON; + //vector calculation + Point3D vec = sgGeodToCart( GetLoc() * SG_DEGREES_TO_RADIANS ); + double length = vec.distance3D( Point3D(0.0) ); + vec = vec / length; + + // Create green edge lights + TGPolygon area = gen_runway_area_w_extend(0.0, 0.0, 0.0, 0.0, 0.0); + for ( int i = 0; i < area.contour_size( 0 ); ++i ) { + g_lights.push_back( area.get_pt( 0, i ) ); + g_normals.push_back( vec ); } - if ( startl_pct < 0.0 ) { - startl_pct = 0.0; - } - - if ( endl_pct > 1.0 ) { - endl_pct = 1.0; - } - - // partial "w" percentages could introduce "T" intersections which - // we compensate for later, but could still cause problems now - // with our polygon clipping code. This attempts to compensate - // for that by nudging the areas a bit bigger so we don't end up - // with polygon slivers. - if ( startw_pct > 0.0 || endw_pct < 1.0 ) { - if ( startw_pct > 0.0 ) { - startw_pct -= nudge * SG_EPSILON; - } - if ( endw_pct < 1.0 ) { - endw_pct += nudge * SG_EPSILON; - } - } - - SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct - << " end len % = " << endl_pct); - - double dlx, dly; - - dlx = a1.x() - a0.x(); - dly = a1.y() - a0.y(); - - Point3D t0 = Point3D( a0.x() + dlx * startl_pct, - a0.y() + dly * startl_pct, 0); - Point3D t1 = Point3D( a0.x() + dlx * endl_pct, - a0.y() + dly * endl_pct, 0); - - dlx = a3.x() - a2.x(); - dly = a3.y() - a2.y(); - - Point3D t2 = Point3D( a2.x() + dlx * startl_pct, - a2.y() + dly * startl_pct, 0); - - Point3D t3 = Point3D( a2.x() + dlx * endl_pct, - a2.y() + dly * endl_pct, 0); - - SG_LOG(SG_GENERAL, SG_DEBUG, "start wid % = " << startw_pct - << " end wid % = " << endw_pct); - - double dwx, dwy; - - dwx = t0.x() - t2.x(); - dwy = t0.y() - t2.y(); - - Point3D p0 = Point3D( t2.x() + dwx * startw_pct, - t2.y() + dwy * startw_pct, 0); - - Point3D p1 = Point3D( t2.x() + dwx * endw_pct, - t2.y() + dwy * endw_pct, 0); - - dwx = t1.x() - t3.x(); - dwy = t1.y() - t3.y(); - - Point3D p2 = Point3D( t3.x() + dwx * startw_pct, - t3.y() + dwy * startw_pct, 0); - - Point3D p3 = Point3D( t3.x() + dwx * endw_pct, - t3.y() + dwy * endw_pct, 0); - - TGPolygon section; - section.erase(); - - section.add_node( 0, p2 ); - section.add_node( 0, p0 ); - section.add_node( 0, p1 ); - section.add_node( 0, p3 ); - section = snap( section, gSnap ); - - // print runway points - SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << prefix << material); - for ( j = 0; j < section.contours(); ++j ) { - for ( k = 0; k < section.contour_size( j ); ++k ) { - Point3D p = section.get_pt(j, k); - SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p); - } - } - - // Clip the new polygon against what ever has already been created. - TGPolygon clipped = tgPolygonDiffClipper( section, *accum ); - tgPolygonFindSlivers( clipped, slivers ); - - // Split long edges to create an object that can better flow with - // the surface terrain - TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 ); - - // Create the final output and push on to the runway super_polygon - // list - TGSuperPoly sp; - sp.erase(); - sp.set_poly( split ); - sp.set_material( prefix + material ); - rwy_polys->push_back( sp ); - SG_LOG(SG_GENERAL, SG_DEBUG, "section = " << clipped.contours()); - - *accum = tgPolygonUnionClipper( section, *accum ); - - // Store away what we need to know for texture coordinate - // calculation. (CLO 10/20/02: why can't we calculate texture - // coordinates here? Oh, becuase later we need to massage the - // polygons to avoid "T" intersections and clean up other - // potential artifacts and we may add or remove points and need to - // do new texture coordinate calcs later. - - double len = length / 2.0; - double sect_len = len * ( endl_pct - startl_pct ); - - double sect_wid = width * ( endw_pct - startw_pct ); - - TGTexParams tp; - tp = TGTexParams( p0, - sect_wid, - sect_len, - heading ); - tp.set_minu( minu ); - tp.set_maxu( maxu ); - tp.set_minv( minv ); - tp.set_maxv( maxv ); - texparams->push_back( tp ); - - // print runway points - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped runway pts " << prefix + material); - for ( j = 0; j < clipped.contours(); ++j ) { - for ( k = 0; k < clipped.contour_size( j ); ++k ) { - Point3D p = clipped.get_pt(j, k); - SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p); - } - } -} - - -superpoly_list Helipad::gen_helipad_lights(void){ - - point_list c_lights; c_lights.clear(); - point_list c_normals; c_normals.clear(); - double lat2 = 0, lon2 = 0, az2; - - // Create a circle of lights approx. where the white circle is - for (int deg=0; deg<360; deg+=10){ + // Create a circle of lights approx. where the white texture circle is + double lat = heli.lat, lon = heli.lon, az; + for (int deg = 0; deg < 360; deg += 10){ geo_direct_wgs_84(0, heli.lat, heli.lon, deg , - heli.width * 0.46 , &lat2, &lon2, &az2 ); + maxsize * 0.46 , &lat, &lon, &az ); - c_lights.push_back( Point3D( lon2, lat2, 0.0 ) ); - - Point3D tmp = Point3D( lon2, lat2, 0.0 ); - Point3D vec = sgGeodToCart( tmp * SG_DEGREES_TO_RADIANS ); - double length = vec.distance3D( Point3D(0.0) ); - vec = vec / length; - c_normals.push_back( vec ); + g_lights.push_back( Point3D( lon, lat, 0.0 ) ); + g_normals.push_back( vec ); } TGPolygon lights_poly; lights_poly.erase(); TGPolygon normals_poly; normals_poly.erase(); - lights_poly.add_contour( c_lights, false ); - normals_poly.add_contour( c_normals, false ); + lights_poly.add_contour( g_lights, false ); + normals_poly.add_contour( g_normals, false ); TGSuperPoly green; green.set_poly( lights_poly ); @@ -253,47 +92,61 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys, TGPolygon* apt_base, TGPolygon* apt_clearing ) { - SG_LOG( SG_GENERAL, SG_INFO, "Building helipad = " << heli.designator ); - // // Generate the basic helipad outlines // - Point3D helicenter = Point3D( heli.lon, heli.lat, 0.0); - - TGPolygon helipad = gen_wgs84_area( helicenter, heli.length, 0, 0, heli.width, heli.heading, false); - - double start1_pct = 0.0; - double end1_pct = 0.0; double maxsize = heli.width - heli.length; - if (maxsize <= 0) maxsize = heli.width; - else if (maxsize > 0) + else maxsize = heli.length; - double percent = (maxsize / heli.length) /2; + TGPolygon helipad = gen_wgs84_area( GetLoc(), maxsize, 0, 0, maxsize, heli.heading, false); + helipad = snap( helipad, gSnap ); - start1_pct = 0.5 - percent; - end1_pct = 0.5 + percent; - gen_helipad( helipad, - start1_pct, end1_pct, - 0.0, 1.0, - 0.0, 1.0, 0.0, 1.0, - heli.heading, - "pc_", "heli", - rwy_polys, texparams, accum, slivers ); + string material; + if (heli.surface == 1) + material = "pa_"; + else + material = "pc_"; + + // Clip the new polygon against what ever has already been created. + TGPolygon clipped = tgPolygonDiffClipper( helipad, *accum ); + tgPolygonFindSlivers( clipped, slivers ); + + // Split long edges to create an object that can better flow with + // the surface terrain + TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 ); + + // Create the final output and push on to the runway super_polygon + // list + TGSuperPoly sp; + sp.erase(); + sp.set_poly( split ); + sp.set_material( material + "heli" ); + rwy_polys->push_back( sp ); + + *accum = tgPolygonUnionClipper( helipad, *accum ); + + TGTexParams tp; + tp = TGTexParams( helipad.get_pt(0,0), maxsize, maxsize, heli.heading ); + tp.set_minu( 1 ); + tp.set_maxu( 0 ); + tp.set_minv( 1 ); + tp.set_maxv( 0 ); + texparams->push_back( tp ); // generate area around helipad if (apt_base) { TGPolygon base, safe_base; - base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 ); + base = gen_runway_area_w_extend( 0.0, heli.length * 0.25 , 0.0, 0.0, heli.width * 0.25 ); base = snap( base, gSnap ); // also clear a safe area around the pad - safe_base = gen_runway_area_w_extend( 0.0, maxsize * 0.5, 0.0, 0.0, maxsize * 0.5 ); + safe_base = gen_runway_area_w_extend( 0.0, heli.length * 0.5, 0.0, 0.0, heli.width * 0.5 ); safe_base = snap( safe_base, gSnap ); // add this to the airport clearing @@ -306,7 +159,7 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys, if (heli.edge_lights) { // Now generate the helipad lights - superpoly_list s = gen_helipad_lights(); + superpoly_list s = gen_helipad_lights(maxsize); for ( unsigned int i = 0; i < s.size(); ++i ) { rwy_lights->push_back( s[i] ); } diff --git a/src/Airports/GenAirports850/helipad.hxx b/src/Airports/GenAirports850/helipad.hxx index e168cc61..3f435e44 100644 --- a/src/Airports/GenAirports850/helipad.hxx +++ b/src/Airports/GenAirports850/helipad.hxx @@ -16,9 +16,6 @@ #ifndef _HELIPAD_HXX #define _HELIPAD_HXX -#include -#include - #include #include #include @@ -36,47 +33,31 @@ public: private: struct TGRunway { - // data for whole runway - int surface; - int shoulder; - int edge_lights; - - double width; - double length; - double heading; - double smoothness; - - // data for each end + // data for helipad char designator[16]; double lat; double lon; - + double heading; + double length; + double width; + int surface; int marking; + int shoulder; + double smoothness; + int edge_lights; }; TGRunway heli; - void gen_helipad( const TGPolygon& runway, - double startl_pct, double endl_pct, - double startw_pct, double endw_pct, - double minu, double maxu, double minv, double maxv, - double heading, - const string& prefix, - const string& material, - superpoly_list *rwy_polys, - texparams_list *texparams, - ClipPolyType *accum, - poly_list& slivers ); - // generate an area for a runway with expansion specified in meters // (return result points in degrees) TGPolygon gen_runway_area_w_extend( double alt_m, double length_extend, double displ1, double displ2, double width_extend ) { - return ( gen_wgs84_area(Point3D(heli.lon, heli.lat, 0.0f), heli.length + 2.0*length_extend, displ1, displ2, heli.width + 2.0*width_extend, heli.heading, false) ); + return ( gen_wgs84_area( GetLoc(), heli.length + 2.0*length_extend, displ1, displ2, heli.width + 2.0*width_extend, heli.heading, false) ); } - superpoly_list gen_helipad_lights(void); + superpoly_list gen_helipad_lights(double maxsize); };