[helipad] Maintenance
This commit is contained in:
parent
95c62c0f30
commit
9a2a4cdb25
2 changed files with 96 additions and 106 deletions
|
@ -17,11 +17,11 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "apt_math.hxx"
|
||||
#include "debug.hxx"
|
||||
#include "global.hxx"
|
||||
#include "helipad.hxx"
|
||||
#include "runway.hxx"
|
||||
#include "debug.hxx"
|
||||
|
||||
|
||||
Helipad::Helipad(char* definition)
|
||||
|
@ -32,22 +32,13 @@ Helipad::Helipad(char* definition)
|
|||
// "H1 21.30433555 -157.85586778 0.00 10.70 10.70 2 0 0 0.25 0\r"
|
||||
|
||||
std::istringstream ss(definition);
|
||||
ss >> heli.designator
|
||||
>> heli.lat
|
||||
>> heli.lon
|
||||
>> heli.heading
|
||||
>> heli.length
|
||||
>> heli.width
|
||||
>> heli.surface
|
||||
>> heli.marking
|
||||
>> heli.shoulder
|
||||
>> heli.smoothness
|
||||
>> heli.edge_lights;
|
||||
ss >> heli.designator >> heli.lat >> heli.lon >> heli.heading >> heli.length >> heli.width >> heli.surface >> heli.marking >> heli.shoulder >> heli.smoothness >> heli.edge_lights;
|
||||
|
||||
TG_LOG(SG_GENERAL, SG_DEBUG, "Read helipad: (" << heli.lon << "," << heli.lat << ") heading: " << heli.heading << " length: " << heli.length << " width: " << heli.width );
|
||||
TG_LOG(SG_GENERAL, SG_DEBUG, "Read helipad: (" << heli.lon << "," << heli.lat << ") heading: " << heli.heading << " length: " << heli.length << " width: " << heli.width);
|
||||
}
|
||||
|
||||
tglightcontour_list Helipad::gen_helipad_lights(double maxsize) {
|
||||
tglightcontour_list Helipad::gen_helipad_lights(double maxsize)
|
||||
{
|
||||
tglightcontour_list result;
|
||||
|
||||
// Vector calculation
|
||||
|
@ -57,30 +48,30 @@ tglightcontour_list Helipad::gen_helipad_lights(double maxsize) {
|
|||
tgContour area = gen_helipad_area_w_extend(0.0, 0.0);
|
||||
tgLightContour yellow;
|
||||
|
||||
yellow.SetType( "RWY_YELLOW_LIGHTS" );
|
||||
for ( unsigned int i = 0; i < area.GetSize(); ++i ) {
|
||||
yellow.SetType("RWY_YELLOW_LIGHTS");
|
||||
for (unsigned int i = 0; i < area.GetSize(); ++i) {
|
||||
double dist, course, cs;
|
||||
SGGeodesy::inverse(area.GetNode(i), area.GetNode(i==3 ? 0 : i+1), course, cs, dist );
|
||||
SGGeodesy::inverse(area.GetNode(i), area.GetNode(i == 3 ? 0 : i + 1), course, cs, dist);
|
||||
int divs = (int)(dist / 5.0);
|
||||
double step = dist/divs;
|
||||
double step = dist / divs;
|
||||
SGGeod pt = area.GetNode(i);
|
||||
for (int j = 0; j < divs; ++j) {
|
||||
pt = SGGeodesy::direct(pt, course, step );
|
||||
yellow.AddLight( pt, vec );
|
||||
pt = SGGeodesy::direct(pt, course, step);
|
||||
yellow.AddLight(pt, vec);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a circle of yellow lights where the white texture circle is
|
||||
for (int deg = 0; deg < 360; deg += 45){
|
||||
yellow.AddLight( SGGeodesy::direct(GetLoc(), deg, maxsize * 0.46), vec );
|
||||
for (int deg = 0; deg < 360; deg += 45) {
|
||||
yellow.AddLight(SGGeodesy::direct(GetLoc(), deg, maxsize * 0.46), vec);
|
||||
}
|
||||
|
||||
result.push_back( yellow );
|
||||
result.push_back(yellow);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Helipad::build_helipad_shoulders( const tgContour& outer_area )
|
||||
void Helipad::build_helipad_shoulders(const tgContour& outer_area)
|
||||
{
|
||||
double shoulder_width, shoulder_heading;
|
||||
std::string shoulder_mat;
|
||||
|
@ -105,25 +96,25 @@ void Helipad::build_helipad_shoulders( const tgContour& outer_area )
|
|||
tgPolygon shoulder_poly;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
shoulder_heading = SGMiscd::normalizePeriodic(0,360,shoulder_heading-90);
|
||||
shoulder_heading = SGMiscd::normalizePeriodic(0, 360, shoulder_heading - 90);
|
||||
shoulder_poly.Erase();
|
||||
shoulder_poly.AddNode( 0, shoulder.GetNode( i ) );
|
||||
shoulder_poly.AddNode( 0, shoulder.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
shoulder_poly.AddNode( 0, outer_area.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
shoulder_poly.AddNode( 0, outer_area.GetNode( i ) );
|
||||
shoulder_poly.SetMaterial( shoulder_mat );
|
||||
shoulder_poly.SetTexParams( shoulder_poly.GetNode(0, 1), shoulder_width, 5.0, shoulder_heading );
|
||||
shoulder_poly.SetTexLimits( 1,1,0,0 );
|
||||
shoulder_poly.SetTexMethod( TG_TEX_BY_TPS_CLIPU, 0.0, 0.0, 1.0, 1.0 );
|
||||
shoulder_poly = tgPolygon::Snap( shoulder_poly, gSnap );
|
||||
shoulder_polys.push_back( shoulder_poly );
|
||||
shoulder_poly.AddNode(0, shoulder.GetNode(i));
|
||||
shoulder_poly.AddNode(0, shoulder.GetNode(i == 3 ? 0 : i + 1));
|
||||
shoulder_poly.AddNode(0, outer_area.GetNode(i == 3 ? 0 : i + 1));
|
||||
shoulder_poly.AddNode(0, outer_area.GetNode(i));
|
||||
shoulder_poly.SetMaterial(shoulder_mat);
|
||||
shoulder_poly.SetTexParams(shoulder_poly.GetNode(0, 1), shoulder_width, 5.0, shoulder_heading);
|
||||
shoulder_poly.SetTexLimits(1, 1, 0, 0);
|
||||
shoulder_poly.SetTexMethod(TG_TEX_BY_TPS_CLIPU, 0.0, 0.0, 1.0, 1.0);
|
||||
shoulder_poly = tgPolygon::Snap(shoulder_poly, gSnap);
|
||||
shoulder_polys.push_back(shoulder_poly);
|
||||
}
|
||||
}
|
||||
|
||||
void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
||||
void Helipad::BuildBtg(tgpolygon_list& rwy_polys,
|
||||
tglightcontour_list& rwy_lights,
|
||||
tgcontour_list& slivers,
|
||||
tgAccumulator& accum )
|
||||
tgAccumulator& accum)
|
||||
{
|
||||
//
|
||||
// Generate the basic helipad outlines
|
||||
|
@ -131,16 +122,16 @@ void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
|||
double heli_size;
|
||||
|
||||
// helipad constructed as a square with width or length added around it
|
||||
if ( heli.width == heli.length ) {
|
||||
if (heli.width == heli.length) {
|
||||
heli_size = heli.length;
|
||||
} else if ( heli.width > heli.length ) {
|
||||
} else if (heli.width > heli.length) {
|
||||
heli_size = heli.length;
|
||||
} else {
|
||||
heli_size = heli.width;
|
||||
}
|
||||
|
||||
tgContour helipad = gen_wgs84_area( GetLoc(), heli_size, 0, 0, heli_size, heli.heading, false);
|
||||
helipad = tgContour::Snap( helipad, gSnap );
|
||||
tgContour helipad = gen_wgs84_area(GetLoc(), heli_size, 0, 0, heli_size, heli.heading, false);
|
||||
helipad = tgContour::Snap(helipad, gSnap);
|
||||
|
||||
std::string heli_mat, extra_mat;
|
||||
if (heli.surface == 1) {
|
||||
|
@ -152,67 +143,66 @@ void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
|||
}
|
||||
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
tgPolygon clipped = accum.Diff( helipad );
|
||||
tgPolygon clipped = accum.Diff(helipad);
|
||||
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
tgPolygon heli_poly = tgPolygon::SplitLongEdges( clipped, 400.0 );
|
||||
tgPolygon heli_poly = tgPolygon::SplitLongEdges(clipped, 400.0);
|
||||
|
||||
accum.Add( helipad );
|
||||
accum.Add(helipad);
|
||||
|
||||
heli_poly.SetMaterial( heli_mat );
|
||||
heli_poly.SetTexParams( helipad.GetNode(0), heli_size, heli_size, heli.heading );
|
||||
heli_poly.SetTexLimits( 0,0,1,1 );
|
||||
heli_poly.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, -1.0, -1.0, 1.0, 1.0 );
|
||||
rwy_polys.push_back( heli_poly );
|
||||
heli_poly.SetMaterial(heli_mat);
|
||||
heli_poly.SetTexParams(helipad.GetNode(0), heli_size, heli_size, heli.heading);
|
||||
heli_poly.SetTexLimits(0, 0, 1, 1);
|
||||
heli_poly.SetTexMethod(TG_TEX_BY_TPS_CLIPUV, -1.0, -1.0, 1.0, 1.0);
|
||||
rwy_polys.push_back(heli_poly);
|
||||
|
||||
// Now generate the actual rectangle, and clip it with the square
|
||||
// need areference point at the origin of the direction, in the middle of width
|
||||
SGGeod ref = SGGeodesy::direct( SGGeod::fromDeg(heli.lon, heli.lat),
|
||||
SGMiscd::normalizePeriodic(0, 360, heli.heading + 180 ),
|
||||
heli.length/2 );
|
||||
// need a reference point at the origin of the direction, in the middle of width
|
||||
SGGeod ref = SGGeodesy::direct(SGGeod::fromDeg(heli.lon, heli.lat),
|
||||
SGMiscd::normalizePeriodic(0, 360, heli.heading + 180),
|
||||
heli.length / 2);
|
||||
|
||||
tgContour outer_area = gen_wgs84_rect( ref, heli.heading, heli.length, heli.width );
|
||||
outer_area = tgContour::Snap( outer_area, gSnap );
|
||||
tgContour outer_area = gen_wgs84_rect(ref, heli.heading, heli.length, heli.width);
|
||||
outer_area = tgContour::Snap(outer_area, gSnap);
|
||||
|
||||
tgPolygon outer_poly = tgContour::Diff( outer_area, heli_poly );
|
||||
clipped = accum.Diff( outer_poly );
|
||||
tgPolygon outer_poly = tgContour::Diff(outer_area, heli_poly);
|
||||
clipped = accum.Diff(outer_poly);
|
||||
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
tgPolygon extra_heli = tgPolygon::SplitLongEdges( clipped, 400.0 );
|
||||
tgPolygon extra_heli = tgPolygon::SplitLongEdges(clipped, 400.0);
|
||||
|
||||
// Create the final output and push on to the runway super_polygon
|
||||
// list
|
||||
extra_heli.SetMaterial( extra_mat );
|
||||
extra_heli.SetTexParams( outer_area.GetNode(0), 5.0, 5.0, heli.heading );
|
||||
extra_heli.SetTexLimits( 1,1,0,0 );
|
||||
extra_heli.SetTexMethod( TG_TEX_BY_TPS_NOCLIP );
|
||||
rwy_polys.push_back( extra_heli );
|
||||
accum.Add( extra_heli );
|
||||
extra_heli.SetMaterial(extra_mat);
|
||||
extra_heli.SetTexParams(outer_area.GetNode(0), 5.0, 5.0, heli.heading);
|
||||
extra_heli.SetTexLimits(1, 1, 0, 0);
|
||||
extra_heli.SetTexMethod(TG_TEX_BY_TPS_NOCLIP);
|
||||
rwy_polys.push_back(extra_heli);
|
||||
accum.Add(extra_heli);
|
||||
|
||||
build_helipad_shoulders( outer_area );
|
||||
build_helipad_shoulders(outer_area);
|
||||
|
||||
if (heli.edge_lights)
|
||||
{
|
||||
if (heli.edge_lights) {
|
||||
// Now generate the helipad lights
|
||||
tglightcontour_list s = gen_helipad_lights(heli_size);
|
||||
for ( unsigned int i = 0; i < s.size(); ++i ) {
|
||||
rwy_lights.push_back( s[i] );
|
||||
for (unsigned int i = 0; i < s.size(); ++i) {
|
||||
rwy_lights.push_back(s[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
||||
void Helipad::BuildBtg(tgpolygon_list& rwy_polys,
|
||||
tglightcontour_list& rwy_lights,
|
||||
tgcontour_list& slivers,
|
||||
tgpolygon_list& apt_base_polys,
|
||||
tgpolygon_list& apt_clearing_polys,
|
||||
tgAccumulator& accum )
|
||||
tgAccumulator& accum)
|
||||
{
|
||||
BuildBtg( rwy_polys, rwy_lights, slivers, accum );
|
||||
BuildBtg(rwy_polys, rwy_lights, slivers, accum);
|
||||
|
||||
// generate area around helipad
|
||||
double length, width;
|
||||
|
@ -221,7 +211,7 @@ void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
|||
|
||||
length = heli.length;
|
||||
width = heli.width;
|
||||
if ( (heli.shoulder == 1) || (heli.shoulder == 2 ) ) {
|
||||
if ((heli.shoulder == 1) || (heli.shoulder == 2)) {
|
||||
length += 12.0;
|
||||
width += 12.0;
|
||||
} else {
|
||||
|
@ -229,42 +219,42 @@ void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
|||
width += 2.0;
|
||||
}
|
||||
|
||||
base_contour = gen_helipad_area_w_extend(length * 0.25 , width * 0.25 );
|
||||
base_contour = tgContour::Snap( base_contour, gSnap );
|
||||
base.AddContour( base_contour );
|
||||
base_contour = gen_helipad_area_w_extend(length * 0.25, width * 0.25);
|
||||
base_contour = tgContour::Snap(base_contour, gSnap);
|
||||
base.AddContour(base_contour);
|
||||
|
||||
// also clear a safe area around the pad
|
||||
safe_base_contour = gen_helipad_area_w_extend( length * 0.5, width * 0.5 );
|
||||
safe_base_contour = tgContour::Snap( safe_base_contour, gSnap );
|
||||
safe_base.AddContour( safe_base_contour );
|
||||
safe_base_contour = gen_helipad_area_w_extend(length * 0.5, width * 0.5);
|
||||
safe_base_contour = tgContour::Snap(safe_base_contour, gSnap);
|
||||
safe_base.AddContour(safe_base_contour);
|
||||
|
||||
// add this to the airport clearing
|
||||
apt_clearing_polys.push_back( safe_base );
|
||||
apt_clearing_polys.push_back(safe_base);
|
||||
|
||||
// and add the clearing to the base
|
||||
apt_base_polys.push_back( base );
|
||||
apt_base_polys.push_back(base);
|
||||
}
|
||||
|
||||
void Helipad::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
void Helipad::BuildShoulder(tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
tgAccumulator& accum )
|
||||
tgAccumulator& accum)
|
||||
{
|
||||
tgPolygon shoulder;
|
||||
|
||||
for (unsigned int i=0; i<shoulder_polys.size(); i++) {
|
||||
for (unsigned int i = 0; i < shoulder_polys.size(); i++) {
|
||||
shoulder = shoulder_polys[i];
|
||||
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
tgPolygon clipped = accum.Diff( shoulder );
|
||||
tgPolygon clipped = accum.Diff(shoulder);
|
||||
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
tgPolygon split = tgPolygon::SplitLongEdges( clipped, 400.0 );
|
||||
tgPolygon split = tgPolygon::SplitLongEdges(clipped, 400.0);
|
||||
shoulder_polys[i] = split;
|
||||
|
||||
rwy_polys.push_back( shoulder_polys[i] );
|
||||
rwy_polys.push_back(shoulder_polys[i]);
|
||||
|
||||
accum.Add( shoulder );
|
||||
accum.Add(shoulder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,12 @@ public:
|
|||
tgpolygon_list& apt_clearing_polys,
|
||||
tgAccumulator& accum);
|
||||
|
||||
SGGeod GetLoc()
|
||||
SGGeod GetLoc() const
|
||||
{
|
||||
return SGGeod::fromDeg(heli.lon, heli.lat);
|
||||
}
|
||||
|
||||
bool GetsShoulder()
|
||||
bool GetsShoulder() const
|
||||
{
|
||||
return (heli.surface < 3) ? true : false;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
private:
|
||||
struct TGRunway {
|
||||
// data for helipad
|
||||
char designator[16];
|
||||
std::string designator;
|
||||
double lat;
|
||||
double lon;
|
||||
double heading;
|
||||
|
@ -74,7 +74,7 @@ private:
|
|||
|
||||
// generate an area for a runway with expansion specified in meters
|
||||
// (return result points in degrees)
|
||||
tgContour gen_helipad_area_w_extend(double length_extend, double width_extend)
|
||||
tgContour gen_helipad_area_w_extend(double length_extend, double width_extend) const
|
||||
{
|
||||
return (gen_wgs84_area(GetLoc(), heli.length + 2.0 * length_extend, 0.0, 0.0, heli.width + 2.0 * width_extend, heli.heading, false));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue