1
0
Fork 0

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:
Peter Sadrozinski 2012-03-04 14:58:01 -05:00 committed by Christian Schmitt
parent f5e1084eb8
commit d0d30fbd52
7 changed files with 485 additions and 389 deletions

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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 )

View file

@ -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,

View file

@ -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 );
}

View file

@ -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 );
}
}
} }
} }