More consolidation for runway generation
- remove gen_overrun, and the 'generic' gen_tex functions. - removed rwy_common.cxx NOTE: now, helipads don't share the same generate function as runway sections. Maybe later they can be remerged...
This commit is contained in:
parent
f5e1084eb8
commit
d0d30fbd52
7 changed files with 485 additions and 389 deletions
|
@ -18,7 +18,6 @@ add_executable(genapts850
|
||||||
runway.cxx runway.hxx
|
runway.cxx runway.hxx
|
||||||
rwy_simple.cxx
|
rwy_simple.cxx
|
||||||
rwy_gen.cxx
|
rwy_gen.cxx
|
||||||
rwy_common.cxx
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(genapts850
|
target_link_libraries(genapts850
|
||||||
|
|
|
@ -205,171 +205,3 @@ TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length,
|
||||||
|
|
||||||
return result_list;
|
return result_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a section of texture
|
|
||||||
void gen_tex_section( 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, double width, double length,
|
|
||||||
const string& prefix,
|
|
||||||
const string& material,
|
|
||||||
superpoly_list *rwy_polys,
|
|
||||||
texparams_list *texparams,
|
|
||||||
ClipPolyType *accum,
|
|
||||||
poly_list& slivers ) {
|
|
||||||
|
|
||||||
int j, k;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if ( startl_pct > 0.0 ) {
|
|
||||||
startl_pct -= nudge * SG_EPSILON;
|
|
||||||
}
|
|
||||||
if ( endl_pct < 1.0 ) {
|
|
||||||
endl_pct += nudge * SG_EPSILON;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
#if 0
|
|
||||||
TGPolygon clipped = tgPolygonDiff( section, *accum );
|
|
||||||
#else
|
|
||||||
TGPolygon clipped = tgPolygonDiffClipper( section, *accum );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
*accum = tgPolygonUnion( section, *accum );
|
|
||||||
#else
|
|
||||||
*accum = tgPolygonUnionClipper( section, *accum );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
|
#include "global.hxx"
|
||||||
#include "apt_math.hxx"
|
#include "apt_math.hxx"
|
||||||
#include "helipad.hxx"
|
#include "helipad.hxx"
|
||||||
#include "runway.hxx"
|
#include "runway.hxx"
|
||||||
|
@ -38,6 +39,177 @@ 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 );
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if ( startl_pct > 0.0 ) {
|
||||||
|
startl_pct -= nudge * SG_EPSILON;
|
||||||
|
}
|
||||||
|
if ( endl_pct < 1.0 ) {
|
||||||
|
endl_pct += nudge * SG_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
#if 0
|
||||||
|
TGPolygon clipped = tgPolygonDiff( section, *accum );
|
||||||
|
#else
|
||||||
|
TGPolygon clipped = tgPolygonDiffClipper( section, *accum );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
*accum = tgPolygonUnion( section, *accum );
|
||||||
|
#else
|
||||||
|
*accum = tgPolygonUnionClipper( section, *accum );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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){
|
superpoly_list Helipad::gen_helipad_lights(void){
|
||||||
|
|
||||||
point_list c_lights; c_lights.clear();
|
point_list c_lights; c_lights.clear();
|
||||||
|
@ -106,13 +278,13 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys,
|
||||||
|
|
||||||
start1_pct = 0.5 - percent;
|
start1_pct = 0.5 - percent;
|
||||||
end1_pct = 0.5 + percent;
|
end1_pct = 0.5 + percent;
|
||||||
gen_tex_section( helipad,
|
gen_helipad( helipad,
|
||||||
start1_pct, end1_pct,
|
start1_pct, end1_pct,
|
||||||
0.0, 1.0,
|
0.0, 1.0,
|
||||||
0.0, 1.0, 0.0, 1.0,
|
0.0, 1.0, 0.0, 1.0,
|
||||||
heli.heading, heli.width, heli.length,
|
heli.heading,
|
||||||
"pc_", "heli",
|
"pc_", "heli",
|
||||||
rwy_polys, texparams, accum, slivers );
|
rwy_polys, texparams, accum, slivers );
|
||||||
|
|
||||||
|
|
||||||
// generate area around helipad
|
// generate area around helipad
|
||||||
|
|
|
@ -56,6 +56,19 @@ private:
|
||||||
|
|
||||||
TGRunway heli;
|
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
|
// generate an area for a runway with expansion specified in meters
|
||||||
// (return result points in degrees)
|
// (return result points in degrees)
|
||||||
TGPolygon gen_runway_area_w_extend( double alt_m, double length_extend, double displ1, double displ2, double width_extend )
|
TGPolygon gen_runway_area_w_extend( double alt_m, double length_extend, double displ1, double displ2, double width_extend )
|
||||||
|
|
|
@ -112,29 +112,21 @@ private:
|
||||||
ClipPolyType* accum,
|
ClipPolyType* accum,
|
||||||
poly_list& slivers );
|
poly_list& slivers );
|
||||||
|
|
||||||
// generate the runway overrun area
|
|
||||||
void gen_runway_overrun( const TGPolygon& runway_half,
|
|
||||||
int rwhalf,
|
|
||||||
const std::string& prefix,
|
|
||||||
superpoly_list* rwy_polys,
|
|
||||||
texparams_list* texparams,
|
|
||||||
ClipPolyType* accum,
|
|
||||||
poly_list& slivers );
|
|
||||||
|
|
||||||
// generate a section of runway
|
// generate a section of runway
|
||||||
void gen_runway_section( const TGPolygon& runway,
|
void gen_runway_section( const TGPolygon& runway,
|
||||||
double startl_pct, double endl_pct,
|
double startl_pct, double endl_pct,
|
||||||
double startw_pct, double endw_pct,
|
double startw_pct, double endw_pct,
|
||||||
double minu, double maxu, double minv, double maxv,
|
double minu, double maxu, double minv, double maxv,
|
||||||
double heading,
|
double heading,
|
||||||
const std::string& prefix,
|
const string& prefix,
|
||||||
const std::string& material,
|
const string& material,
|
||||||
superpoly_list* rwy_polys,
|
superpoly_list *rwy_polys,
|
||||||
texparams_list* texparams,
|
texparams_list *texparams,
|
||||||
ClipPolyType* accum,
|
ClipPolyType *accum,
|
||||||
poly_list& slivers );
|
poly_list& slivers );
|
||||||
|
|
||||||
void gen_simple_rwy( const string& material, superpoly_list *rwy_polys, texparams_list *texparams, ClipPolyType *accum, poly_list& slivers );
|
void gen_simple_rwy( const string& material, superpoly_list *rwy_polys, texparams_list *texparams, ClipPolyType *accum, poly_list& slivers );
|
||||||
|
|
||||||
void gen_rwy( const std::string& material,
|
void gen_rwy( const std::string& material,
|
||||||
superpoly_list* rwy_polys,
|
superpoly_list* rwy_polys,
|
||||||
texparams_list* texparams,
|
texparams_list* texparams,
|
||||||
|
|
|
@ -1,190 +0,0 @@
|
||||||
// rwy_common.cxx -- Common runway generation routines
|
|
||||||
//
|
|
||||||
// Written by Curtis Olson, started February 2002.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2002 Curtis L. Olson - http://www.flightgear.org/~curt
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
// $Id: rwy_common.cxx,v 1.12 2004-11-19 22:25:49 curt Exp $
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
|
||||||
#include <simgear/constants.h>
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
|
|
||||||
#include "apt_math.hxx"
|
|
||||||
#include "global.hxx"
|
|
||||||
#include "runway.hxx"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
|
|
||||||
void Runway::gen_rw_designation( const string& material,
|
|
||||||
TGPolygon poly, double heading, string rwname,
|
|
||||||
double &start_pct, double &end_pct,
|
|
||||||
superpoly_list *rwy_polys,
|
|
||||||
texparams_list *texparams,
|
|
||||||
ClipPolyType *accum,
|
|
||||||
poly_list& slivers )
|
|
||||||
{
|
|
||||||
if (rwname != "XX"){ /* Do not create a designation block if the runway name is set to none */
|
|
||||||
string letter = "";
|
|
||||||
double length = rwy.length / 2.0;
|
|
||||||
for ( unsigned int i = 0; i < rwname.length(); ++i ) {
|
|
||||||
string tmp = rwname.substr(i, 1);
|
|
||||||
if ( tmp == "L" || tmp == "R" || tmp == "C" ) {
|
|
||||||
rwname = rwname.substr(0, i);
|
|
||||||
letter = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter = " << letter);
|
|
||||||
|
|
||||||
// create runway designation letter
|
|
||||||
if ( !letter.empty() ) {
|
|
||||||
start_pct = end_pct;
|
|
||||||
end_pct = start_pct + ( 90.0 * SG_FEET_TO_METER / length );
|
|
||||||
gen_runway_section( poly,
|
|
||||||
start_pct, end_pct,
|
|
||||||
0.0, 1.0,
|
|
||||||
0.0, 1.0, 0.0, 1.0,
|
|
||||||
heading,
|
|
||||||
material, letter,
|
|
||||||
rwy_polys, texparams, accum, slivers );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// create runway designation number(s)
|
|
||||||
if (rwname == "0")
|
|
||||||
rwname = "36";
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation = " << rwname);
|
|
||||||
|
|
||||||
char tex1[32]; tex1[0] = '\0';
|
|
||||||
char tex2[32]; tex2[0] = '\0';
|
|
||||||
|
|
||||||
start_pct = end_pct;
|
|
||||||
end_pct = start_pct + ( 80.0 * SG_FEET_TO_METER / length );
|
|
||||||
|
|
||||||
if (rwname.length() == 2) {
|
|
||||||
sprintf( tex1, "%c%c", rwname[0], 'l');
|
|
||||||
sprintf( tex2, "%c%c", rwname[1], 'r');
|
|
||||||
|
|
||||||
gen_runway_section( poly,
|
|
||||||
start_pct, end_pct,
|
|
||||||
0.0, 0.5,
|
|
||||||
0.0, 1.0, 0.0, 1.0,
|
|
||||||
heading,
|
|
||||||
material, tex1,
|
|
||||||
rwy_polys, texparams, accum, slivers );
|
|
||||||
gen_runway_section( poly,
|
|
||||||
start_pct, end_pct,
|
|
||||||
0.5, 1.0,
|
|
||||||
0.0, 1.0, 0.0, 1.0,
|
|
||||||
heading,
|
|
||||||
material, tex2,
|
|
||||||
rwy_polys, texparams, accum, slivers );
|
|
||||||
|
|
||||||
} else if (rwname.length() == 1) {
|
|
||||||
sprintf( tex1, "%c%c", rwname[0], 'c');
|
|
||||||
|
|
||||||
gen_runway_section( poly,
|
|
||||||
start_pct, end_pct,
|
|
||||||
0.0, 1.0,
|
|
||||||
0.0, 1.0, 0.0, 1.0,
|
|
||||||
heading,
|
|
||||||
material, tex1,
|
|
||||||
rwy_polys, texparams, accum, slivers );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate the runway overrun area
|
|
||||||
void Runway::gen_runway_overrun( const TGPolygon& runway_half,
|
|
||||||
int rwhalf,
|
|
||||||
const string& prefix,
|
|
||||||
superpoly_list *rwy_polys,
|
|
||||||
texparams_list *texparams,
|
|
||||||
ClipPolyType* accum,
|
|
||||||
poly_list& slivers ) {
|
|
||||||
const float length = rwy.length / 2.0 + 2.0 * SG_FEET_TO_METER;
|
|
||||||
double start1_pct = 0.0;
|
|
||||||
double end1_pct = 0.0;
|
|
||||||
double part_len = 0.0;
|
|
||||||
double heading = 0.0;
|
|
||||||
double overrun = 0.0;
|
|
||||||
|
|
||||||
int count=0;
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
if (rwhalf == 0) {
|
|
||||||
heading = rwy.heading + 180.0;
|
|
||||||
overrun = rwy.overrun[0];
|
|
||||||
}
|
|
||||||
else if (rwhalf == 1) {
|
|
||||||
heading = rwy.heading;
|
|
||||||
overrun = rwy.overrun[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overrun > 0.0) {
|
|
||||||
/* Generate approach end overrun */
|
|
||||||
count = (int) (overrun * 2.0/ rwy.width);
|
|
||||||
if(count < 1) count = 1;
|
|
||||||
part_len = overrun / (double) count;
|
|
||||||
for(i=0;i<count;i++)
|
|
||||||
{
|
|
||||||
start1_pct=end1_pct;
|
|
||||||
end1_pct = start1_pct + ( part_len / length );
|
|
||||||
gen_runway_section( runway_half,
|
|
||||||
- end1_pct, -start1_pct,
|
|
||||||
0.0, 1.0,
|
|
||||||
0.0, 1.0, 0.0, 1.0, //last number is lengthwise
|
|
||||||
heading,
|
|
||||||
prefix,
|
|
||||||
"stopway",
|
|
||||||
rwy_polys,
|
|
||||||
texparams,
|
|
||||||
accum,
|
|
||||||
slivers );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// call the generic build function with runway-specific parameters
|
|
||||||
void Runway::gen_runway_section( 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 ) {
|
|
||||||
gen_tex_section( runway,
|
|
||||||
startl_pct, endl_pct,
|
|
||||||
startw_pct, endw_pct,
|
|
||||||
minu, maxu, minv, maxv,
|
|
||||||
heading, rwy.width, rwy.length,
|
|
||||||
prefix,
|
|
||||||
material,
|
|
||||||
rwy_polys,
|
|
||||||
texparams,
|
|
||||||
accum,
|
|
||||||
slivers );
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
|
#include "global.hxx"
|
||||||
#include "beznode.hxx"
|
#include "beznode.hxx"
|
||||||
#include "runway.hxx"
|
#include "runway.hxx"
|
||||||
|
|
||||||
|
@ -84,11 +85,259 @@ static const struct sections nprec[] = {
|
||||||
{ "aim", 400 * SG_FEET_TO_METER }
|
{ "aim", 400 * SG_FEET_TO_METER }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// generate a section of texture
|
||||||
|
void Runway::gen_runway_section( 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 = rwy.width;
|
||||||
|
double length = rwy.length;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if ( startl_pct > 0.0 ) {
|
||||||
|
startl_pct -= nudge * SG_EPSILON;
|
||||||
|
}
|
||||||
|
if ( endl_pct < 1.0 ) {
|
||||||
|
endl_pct += nudge * SG_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
#if 0
|
||||||
|
TGPolygon clipped = tgPolygonDiff( section, *accum );
|
||||||
|
#else
|
||||||
|
TGPolygon clipped = tgPolygonDiffClipper( section, *accum );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
*accum = tgPolygonUnion( section, *accum );
|
||||||
|
#else
|
||||||
|
*accum = tgPolygonUnionClipper( section, *accum );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runway::gen_rw_designation( const string& material,
|
||||||
|
TGPolygon poly, double heading, string rwname,
|
||||||
|
double &start_pct, double &end_pct,
|
||||||
|
superpoly_list *rwy_polys,
|
||||||
|
texparams_list *texparams,
|
||||||
|
ClipPolyType *accum,
|
||||||
|
poly_list& slivers )
|
||||||
|
{
|
||||||
|
if (rwname != "XX") { /* Do not create a designation block if the runway name is set to none */
|
||||||
|
string letter = "";
|
||||||
|
double length = rwy.length / 2.0;
|
||||||
|
for ( unsigned int i = 0; i < rwname.length(); ++i ) {
|
||||||
|
string tmp = rwname.substr(i, 1);
|
||||||
|
if ( tmp == "L" || tmp == "R" || tmp == "C" ) {
|
||||||
|
rwname = rwname.substr(0, i);
|
||||||
|
letter = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation letter = " << letter);
|
||||||
|
|
||||||
|
// create runway designation letter
|
||||||
|
if ( !letter.empty() ) {
|
||||||
|
start_pct = end_pct;
|
||||||
|
end_pct = start_pct + ( 90.0 * SG_FEET_TO_METER / length );
|
||||||
|
gen_runway_section( poly,
|
||||||
|
start_pct, end_pct,
|
||||||
|
0.0, 1.0,
|
||||||
|
0.0, 1.0, 0.0, 1.0,
|
||||||
|
heading,
|
||||||
|
material, letter,
|
||||||
|
rwy_polys, texparams, accum, slivers );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create runway designation number(s)
|
||||||
|
if (rwname == "0")
|
||||||
|
rwname = "36";
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Runway designation = " << rwname);
|
||||||
|
|
||||||
|
char tex1[32]; tex1[0] = '\0';
|
||||||
|
char tex2[32]; tex2[0] = '\0';
|
||||||
|
|
||||||
|
start_pct = end_pct;
|
||||||
|
end_pct = start_pct + ( 80.0 * SG_FEET_TO_METER / length );
|
||||||
|
|
||||||
|
if (rwname.length() == 2) {
|
||||||
|
sprintf( tex1, "%c%c", rwname[0], 'l');
|
||||||
|
sprintf( tex2, "%c%c", rwname[1], 'r');
|
||||||
|
|
||||||
|
gen_runway_section( poly,
|
||||||
|
start_pct, end_pct,
|
||||||
|
0.0, 0.5,
|
||||||
|
0.0, 1.0, 0.0, 1.0,
|
||||||
|
heading,
|
||||||
|
material, tex1,
|
||||||
|
rwy_polys, texparams, accum, slivers );
|
||||||
|
gen_runway_section( poly,
|
||||||
|
start_pct, end_pct,
|
||||||
|
0.5, 1.0,
|
||||||
|
0.0, 1.0, 0.0, 1.0,
|
||||||
|
heading,
|
||||||
|
material, tex2,
|
||||||
|
rwy_polys, texparams, accum, slivers );
|
||||||
|
|
||||||
|
} else if (rwname.length() == 1) {
|
||||||
|
sprintf( tex1, "%c%c", rwname[0], 'c');
|
||||||
|
|
||||||
|
gen_runway_section( poly,
|
||||||
|
start_pct, end_pct,
|
||||||
|
0.0, 1.0,
|
||||||
|
0.0, 1.0, 0.0, 1.0,
|
||||||
|
heading,
|
||||||
|
material, tex1,
|
||||||
|
rwy_polys, texparams, accum, slivers );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generate a runway. The routine modifies
|
// generate a runway. The routine modifies
|
||||||
// rwy_polys, texparams, and accum. For specific details and
|
// rwy_polys, texparams, and accum. For specific details and
|
||||||
// dimensions of precision runway markings, please refer to FAA
|
// dimensions of precision runway markings, please refer to FAA
|
||||||
// document AC 150/5340-1H
|
// document AC 150/5340-1H
|
||||||
|
|
||||||
void Runway::gen_rwy( const string& material,
|
void Runway::gen_rwy( const string& material,
|
||||||
superpoly_list *rwy_polys,
|
superpoly_list *rwy_polys,
|
||||||
texparams_list *texparams,
|
texparams_list *texparams,
|
||||||
|
@ -300,9 +549,38 @@ void Runway::gen_rwy( const string& material,
|
||||||
rwy_polys, texparams, accum, slivers );
|
rwy_polys, texparams, accum, slivers );
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_runway_overrun( runway_half, rwhalf,
|
length = rwy.length / 2.0 + 2.0 * SG_FEET_TO_METER;
|
||||||
material,
|
start1_pct = 0.0;
|
||||||
rwy_polys, texparams, accum, slivers );
|
end1_pct = 0.0;
|
||||||
|
|
||||||
|
double part_len = 0.0;
|
||||||
|
int count=0;
|
||||||
|
|
||||||
|
if (rwy.overrun[rwhalf] > 0.0) {
|
||||||
|
/* Generate approach end overrun */
|
||||||
|
count = (int) (rwy.overrun[rwhalf] * 2.0/ rwy.width);
|
||||||
|
if(count < 1) {
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
part_len = rwy.overrun[rwhalf] / (double)count;
|
||||||
|
for(int i=0; i<count; i++) {
|
||||||
|
start1_pct=end1_pct;
|
||||||
|
end1_pct = start1_pct + ( part_len / length );
|
||||||
|
|
||||||
|
gen_runway_section( runway_half,
|
||||||
|
-end1_pct, -start1_pct,
|
||||||
|
0.0, 1.0,
|
||||||
|
0.0, 1.0, 0.0, 1.0, //last number is lengthwise
|
||||||
|
heading,
|
||||||
|
material,
|
||||||
|
"stopway",
|
||||||
|
rwy_polys,
|
||||||
|
texparams,
|
||||||
|
accum,
|
||||||
|
slivers );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue