1
0
Fork 0

Add runway shoulders support.

This was harder than expected as the shoulders were often partially
covered by runway polygons. This was caused by inaccuracies introduced
by the calculation of dimensions from the runway center.

Now we create shoulders if set in apt.dat. If no shoulders are set,
a 1m broad stripe is added to concrete and asphalt runways to make
the blending runway-airport surface more visually appealing.
This commit is contained in:
Christian Schmitt 2011-10-14 17:50:56 +02:00
parent 09352611d5
commit 16ff1e89cc
3 changed files with 96 additions and 1 deletions

View file

@ -438,6 +438,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "no pavements");
}
// Build runway shoulders here
for (i=0; i<runways.size(); i++ )
{
if ( runways[i]->GetsShoulder() )
{
runways[i]->BuildShoulder( altitude, &rwy_polys, &rwy_tps, &accum );
}
}
// build the base and clearing if there's a boundary
if (boundary)
{

View file

@ -39,7 +39,18 @@ public:
return ( Point3D( (rwy.lon[0]+rwy.lon[1])/2.0f, (rwy.lat[0]+rwy.lat[1])/2.0f, 0.0f) );
}
bool GetsShoulder()
{
if (rwy.surface < 3 || rwy.shoulder > 0)
return true;
else return false;
}
int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, ClipPolyType* accum, TGPolygon* apt_base, TGPolygon* apt_clearing );
void BuildShoulder( float alt_m,
superpoly_list *rwy_polys,
texparams_list *texparams,
ClipPolyType *accum );
private:
struct TGRunway {
@ -84,7 +95,6 @@ private:
return ( gen_wgs84_area( Point3D(GetStart()), Point3D(GetEnd()), rwy.length + 2.0*length_extend, displ1, displ2, rwy.width + 2.0*width_extend, rwy.heading, alt_m, false) );
}
void gen_rw_designation( const std::string& material,
TGPolygon poly, double heading, string rwname,
double &start_pct, double &end_pct,

View file

@ -22,6 +22,7 @@
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include "runway.hxx"
#include <stdlib.h>
@ -332,3 +333,78 @@ for ( int rwhalf=0; rwhalf<2; ++rwhalf ){
}
}
void Runway::BuildShoulder( float alt_m,
superpoly_list *rwy_polys,
texparams_list *texparams,
ClipPolyType *accum )
{
string shoulder_surface = "";
double shoulder_width;
if (rwy.shoulder > 0){ // Add a shoulder to the runway
shoulder_width = rwy.width * 0.15;
if (shoulder_width > 8.0){
shoulder_width = 8.0;
}
if (rwy.shoulder == 1){
shoulder_surface = "pa_shoulder";
} else if (rwy.shoulder == 2){
shoulder_surface = "pc_shoulder";
} else SG_LOG(SG_GENERAL, SG_ALERT, "Unknown shoulder surface code = " << rwy.shoulder );
} else if (rwy.shoulder == 0){ // We add a fake shoulder if the runway has an asphalt or concrete surface
shoulder_width = 1;
if (rwy.surface == 1){
shoulder_surface = "pa_shoulder_f";
} else if (rwy.surface == 2){
shoulder_surface = "pc_shoulder_f";
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Shoulder width = " << shoulder_width );
SG_LOG(SG_GENERAL, SG_DEBUG, "Shoulder surface is: " << shoulder_surface );
double lat, lon,r;
// Create both shoulder sides
for (int i=0; i<2; ++i){
double step;
double lat, lon,r;
if (i == 0){
step= (rwy.width + shoulder_width)*0.5;
} else if (i == 1) {
step= -(rwy.width + shoulder_width)*0.5;
}
double left_hdg = rwy.heading - 90.0;
if ( left_hdg < 0 ) { left_hdg += 360.0; }
geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg,
step, &lat, &lon, &r );
Point3D shoulder1 = Point3D( lon, lat, 0.0f );
geo_direct_wgs_84 ( alt_m, rwy.lat[1], rwy.lon[1], left_hdg,
step, &lat, &lon, &r );
Point3D shoulder2 = Point3D( lon, lat, 0.0f );
TGPolygon shoulder = gen_wgs84_area( shoulder1, shoulder2, 0.0, 0.0, 0.0, shoulder_width, rwy.heading, alt_m, false);
TGSuperPoly sp;
TGTexParams tp;
TGPolygon clipped = tgPolygonDiff( shoulder, *accum );
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
sp.erase();
sp.set_poly( split );
sp.set_material( shoulder_surface );
rwy_polys->push_back( sp );
*accum = tgPolygonUnion( shoulder, *accum );
tp = TGTexParams( shoulder.get_pt(0,0), shoulder_width , rwy.length + 2, rwy.heading );
if (i == 1){
tp.set_maxu(0);
tp.set_minu(1);
}
texparams->push_back( tp );
}
}