genapts port complete - time to debug
This commit is contained in:
parent
820c9a6b5d
commit
608057596b
27 changed files with 4034 additions and 2284 deletions
File diff suppressed because it is too large
Load diff
|
@ -110,7 +110,7 @@ public:
|
|||
tm = cleanup_time;
|
||||
}
|
||||
|
||||
void merge_slivers( superpoly_list& polys, poly_list& slivers );
|
||||
void merge_slivers( tgpolygon_list& polys, tgcontour_list& slivers );
|
||||
void BuildBtg( const string& root, const string_list& elev_src );
|
||||
|
||||
void SetDebugPolys( int rwy, int taxi, int pvmt, int feat, int base );
|
||||
|
|
|
@ -18,149 +18,123 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
#include <Geometry/poly_support.hxx>
|
||||
|
||||
#include "apt_math.hxx"
|
||||
#include "global.hxx"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
TGPolygon gen_wgs84_area( SGGeod origin,
|
||||
tgContour gen_wgs84_area( SGGeod origin,
|
||||
double length_m,
|
||||
double displ1, double displ2,
|
||||
double width_m,
|
||||
double heading_deg,
|
||||
bool add_mid )
|
||||
{
|
||||
TGPolygon result_list;
|
||||
tgContour result;
|
||||
double length_hdg = heading_deg;
|
||||
double left_hdg = length_hdg - 90.0;
|
||||
if ( left_hdg < 0 ) { left_hdg += 360.0; }
|
||||
double left_hdg = SGMiscd::normalizePeriodic(0, 360, length_hdg - 90.0);
|
||||
|
||||
// move to the +l end/center of the runway
|
||||
SGGeod ref = SGGeodesy::direct( origin, length_hdg, length_m / 2.0 - displ2 );
|
||||
|
||||
// move to the l,-w corner (then we add points in a clockwise direction)
|
||||
SGGeod p = SGGeodesy::direct( ref, left_hdg, -width_m / 2.0) ;
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( ref, left_hdg, -width_m / 2.0) );
|
||||
|
||||
// move to the l,w corner
|
||||
p = SGGeodesy::direct( ref, left_hdg, width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( ref, left_hdg, width_m / 2.0 ) );
|
||||
|
||||
if ( add_mid ) {
|
||||
// move to the 0,w point (then we add points in a clockwise direction)
|
||||
p = SGGeodesy::direct( origin, left_hdg, width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( origin, left_hdg, width_m / 2.0 ) );
|
||||
}
|
||||
|
||||
// move to the -l end/center of the runway
|
||||
ref = SGGeodesy::direct( origin, length_hdg, displ1 - length_m/2.0);
|
||||
|
||||
// move to the -l,w corner (then we add points in a clockwise direction)
|
||||
p = SGGeodesy::direct( ref, left_hdg, width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( ref, left_hdg, width_m / 2.0 ) );
|
||||
|
||||
// move to the -l,-w corner
|
||||
p = SGGeodesy::direct( ref, left_hdg, -width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( ref, left_hdg, -width_m / 2.0 ) );
|
||||
|
||||
if ( add_mid ) {
|
||||
// move to the 0,-w point (then we add points in a clockwise direction)
|
||||
p = SGGeodesy::direct( origin, left_hdg, -width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( origin, left_hdg, -width_m / 2.0 ) );
|
||||
}
|
||||
|
||||
return result_list;
|
||||
result.SetHole( false );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
TGPolygon gen_wgs84_area( SGGeod end1, SGGeod end2,
|
||||
tgContour gen_wgs84_area( SGGeod end1, SGGeod end2,
|
||||
double length_m,
|
||||
double displ1, double displ2,
|
||||
double width_m,
|
||||
double heading_deg,
|
||||
bool add_mid )
|
||||
{
|
||||
TGPolygon result_list;
|
||||
double left_hdg = heading_deg - 90.0;
|
||||
if ( left_hdg < 0 ) { left_hdg += 360.0; }
|
||||
|
||||
tgContour result;
|
||||
double left_hdg = SGMiscd::normalizePeriodic( 0, 360, heading_deg - 90.0 );
|
||||
double course1, course2, distance;
|
||||
|
||||
SGGeodesy::inverse(end1, end2, course1, course2, distance);
|
||||
|
||||
// Calc the center
|
||||
SGGeod center = SGGeodesy::direct(end1, course1, distance/2 );
|
||||
|
||||
// move from end2 to the displaced threshold
|
||||
SGGeod ref = SGGeodesy::direct( end2, heading_deg, length_m / 2.0 - displ2);
|
||||
|
||||
|
||||
// move to the l,-w corner
|
||||
SGGeod p = SGGeodesy::direct(ref, left_hdg, -width_m / 2.0);
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct(ref, left_hdg, -width_m / 2.0) );
|
||||
|
||||
// move to the l,w corner
|
||||
p = SGGeodesy::direct(ref, left_hdg, width_m / 2.0);
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct(ref, left_hdg, width_m / 2.0) );
|
||||
|
||||
if ( add_mid ) {
|
||||
// move to the 0,w point
|
||||
p = SGGeodesy::direct( center, left_hdg, width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( center, left_hdg, width_m / 2.0 ) );
|
||||
}
|
||||
|
||||
// move to the end1 center to the displ. threshold
|
||||
ref = SGGeodesy::direct( end1, heading_deg, displ1 - length_m / 2.0 );
|
||||
|
||||
// move to the -l,w corner
|
||||
p = SGGeodesy::direct( ref, left_hdg, width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( ref, left_hdg, width_m / 2.0 ) );
|
||||
|
||||
// move to the -l,-w corner
|
||||
p = SGGeodesy::direct( ref, left_hdg, -width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( ref, left_hdg, -width_m / 2.0 ) );
|
||||
|
||||
if ( add_mid ) {
|
||||
// move to the 0,-w point
|
||||
p = SGGeodesy::direct( center, left_hdg, -width_m / 2.0 );
|
||||
result_list.add_node( 0, Point3D::fromSGGeod(p) );
|
||||
result.AddNode( SGGeodesy::direct( center, left_hdg, -width_m / 2.0 ) );
|
||||
}
|
||||
|
||||
return result_list;
|
||||
return result;
|
||||
}
|
||||
|
||||
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width )
|
||||
tgContour gen_wgs84_rect( double lat, double lon, double heading, double length, double width )
|
||||
{
|
||||
TGPolygon result_list;
|
||||
double ptlat = 0.0f;
|
||||
double ptlon = 0.0f;
|
||||
double r = 0.0f;
|
||||
Point3D p;
|
||||
tgContour result;
|
||||
SGGeod ref = SGGeod::fromDeg(lon, lat);
|
||||
SGGeod p;
|
||||
|
||||
// starting point is in the middle of the rectangle width, at the beginning - stretch to heading
|
||||
|
||||
// Point 1 is -90deg, 1/2 width away
|
||||
double left_hdg = heading -90;
|
||||
if ( left_hdg < 0 ) { left_hdg += 360.0; }
|
||||
|
||||
geo_direct_wgs_84 ( 0.0, lat, lon, left_hdg, width / 2.0, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
double left_hdg = SGMiscd::normalizePeriodic(0, 360, heading -90 );
|
||||
p = SGGeodesy::direct( ref, left_hdg, width / 2.0 );
|
||||
result.AddNode( p );
|
||||
|
||||
// Point 2 is heading, length away from point 1
|
||||
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, length, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
p = SGGeodesy::direct( p, heading, length );
|
||||
result.AddNode( p );
|
||||
|
||||
// Point 3 is -90deg, -width away from point 2
|
||||
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, left_hdg, -width, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
p = SGGeodesy::direct( p, left_hdg, -width );
|
||||
result.AddNode( p );
|
||||
|
||||
// last point is heading, -length from point 3
|
||||
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, -length, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
p = SGGeodesy::direct( p, heading, -length );
|
||||
result.AddNode( p );
|
||||
|
||||
return result_list;
|
||||
result.SetHole( false );
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
TGPolygon gen_wgs84_area( SGGeod origin,
|
||||
tgContour gen_wgs84_area( SGGeod origin,
|
||||
double length_m,
|
||||
double displ1,
|
||||
double displ2,
|
||||
|
@ -20,28 +20,14 @@ TGPolygon gen_wgs84_area( SGGeod origin,
|
|||
double heading_deg,
|
||||
bool add_mid );
|
||||
|
||||
// This function uses the 2 runway end points for calculation, which
|
||||
// yields a higher precision
|
||||
TGPolygon gen_wgs84_area( SGGeod end1, SGGeod end2,
|
||||
tgContour gen_wgs84_area( SGGeod end1, SGGeod end2,
|
||||
double length_m,
|
||||
double displ1, double displ2,
|
||||
double width_m,
|
||||
double heading_deg,
|
||||
bool add_mid );
|
||||
|
||||
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width );
|
||||
tgContour gen_wgs84_rect( double lat, double lon, double heading, double length, double width );
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -135,7 +135,7 @@ void ClosedPoly::CloseCurContour()
|
|||
}
|
||||
}
|
||||
|
||||
void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
||||
void ClosedPoly::ConvertContour( BezContour* src, tgContour& dst )
|
||||
{
|
||||
BezNode* curNode;
|
||||
BezNode* nextNode;
|
||||
|
@ -152,7 +152,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes");
|
||||
|
||||
// clear anything in this point list
|
||||
dst->empty();
|
||||
dst.Erase();
|
||||
|
||||
// iterate through each bezier node in the contour
|
||||
for (unsigned int i = 0; i <= src->size()-1; i++)
|
||||
|
@ -273,7 +273,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
// add the pavement vertex
|
||||
// convert from lat/lon to geo
|
||||
// (maybe later) - check some simgear objects...
|
||||
dst->push_back( Point3D::fromSGGeod(curLoc) );
|
||||
dst.AddNode( curLoc );
|
||||
|
||||
if (p==0)
|
||||
{
|
||||
|
@ -298,7 +298,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
nextLoc = CalculateLinearLocation( curNode->GetLoc(), nextNode->GetLoc(), (1.0f/num_segs) * (p+1) );
|
||||
|
||||
// add the feature vertex
|
||||
dst->push_back( Point3D::fromSGGeod(curLoc) );
|
||||
dst.AddNode( curLoc );
|
||||
|
||||
if (p==0)
|
||||
{
|
||||
|
@ -318,7 +318,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
nextLoc = nextNode->GetLoc();
|
||||
|
||||
// just add the one vertex - dist is small
|
||||
dst->push_back( Point3D::fromSGGeod(curLoc) );
|
||||
dst.AddNode( curLoc );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at " << curLoc );
|
||||
|
||||
|
@ -331,7 +331,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
// finish the poly - convert to TGPolygon, and tesselate
|
||||
void ClosedPoly::Finish()
|
||||
{
|
||||
point_list dst_contour;
|
||||
tgContour dst_contour;
|
||||
|
||||
// error handling
|
||||
if (boundary == NULL)
|
||||
|
@ -340,25 +340,27 @@ void ClosedPoly::Finish()
|
|||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Converting a poly with " << holes.size() << " holes");
|
||||
|
||||
|
||||
if (boundary != NULL)
|
||||
{
|
||||
// create the boundary
|
||||
ConvertContour( boundary, &dst_contour );
|
||||
|
||||
ConvertContour( boundary, dst_contour );
|
||||
dst_contour.SetHole( false );
|
||||
|
||||
// and add it to the geometry
|
||||
pre_tess.add_contour( dst_contour, 0 );
|
||||
pre_tess.AddContour( dst_contour );
|
||||
|
||||
// Then convert the hole contours
|
||||
for (unsigned int i=0; i<holes.size(); i++)
|
||||
{
|
||||
dst_contour.clear();
|
||||
ConvertContour( holes[i], &dst_contour );
|
||||
pre_tess.add_contour( dst_contour, 1 );
|
||||
ConvertContour( holes[i], dst_contour );
|
||||
dst_contour.SetHole( true );
|
||||
|
||||
pre_tess.AddContour( dst_contour );
|
||||
}
|
||||
|
||||
pre_tess = snap( pre_tess, gSnap );
|
||||
pre_tess = remove_dups( pre_tess );
|
||||
pre_tess = tgPolygon::Snap( pre_tess, gSnap );
|
||||
pre_tess = tgPolygon::RemoveDups( pre_tess );
|
||||
}
|
||||
|
||||
// save memory by deleting unneeded resources
|
||||
|
@ -377,170 +379,111 @@ void ClosedPoly::Finish()
|
|||
delete holes[i]->at(j);
|
||||
}
|
||||
}
|
||||
|
||||
holes.clear();
|
||||
}
|
||||
|
||||
int ClosedPoly::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, poly_list& slivers, TGPolygon* apt_base, TGPolygon* apt_clearing, bool make_shapefiles )
|
||||
std::string ClosedPoly::GetMaterial( int surface )
|
||||
{
|
||||
TGPolygon base, safe_base;
|
||||
std::string material;
|
||||
|
||||
switch( surface ) {
|
||||
case 1:
|
||||
material = "pa_tiedown";
|
||||
break;
|
||||
|
||||
string material;
|
||||
void* ds_id = NULL; // If we are going to build shapefiles
|
||||
void* l_id = NULL; // datasource and layer IDs
|
||||
case 2:
|
||||
material = "pc_tiedown";
|
||||
break;
|
||||
|
||||
if ( make_shapefiles ) {
|
||||
char ds_name[128];
|
||||
sprintf(ds_name, "./cp_debug");
|
||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||
case 3:
|
||||
material = "grass_rwy";
|
||||
break;
|
||||
|
||||
// TODO Differentiate more here:
|
||||
case 4:
|
||||
case 5:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
material = "grass_rwy";
|
||||
break;
|
||||
|
||||
default:
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (is_pavement)
|
||||
return material;
|
||||
}
|
||||
|
||||
int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tgPolygon& apt_base, tgPolygon& apt_clearing, bool make_shapefiles )
|
||||
{
|
||||
if (is_pavement && pre_tess.Contours() )
|
||||
{
|
||||
switch( surface_type )
|
||||
{
|
||||
case 1:
|
||||
material = "pa_tiedown";
|
||||
break;
|
||||
tgPolygon base, safe_base;
|
||||
|
||||
case 2:
|
||||
material = "pc_tiedown";
|
||||
break;
|
||||
BuildBtg( rwy_polys, slivers, make_shapefiles );
|
||||
|
||||
case 3:
|
||||
material = "grass_rwy";
|
||||
break;
|
||||
|
||||
// TODO Differentiate more here:
|
||||
case 4:
|
||||
case 5:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
material = "grass_rwy";
|
||||
break;
|
||||
base = tgPolygon::Expand( pre_tess, 20.0 );
|
||||
safe_base = tgPolygon::Expand( pre_tess, 50.0);
|
||||
|
||||
default:
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type );
|
||||
exit(1);
|
||||
}
|
||||
// add this to the airport clearing
|
||||
apt_clearing = tgPolygon::Union( safe_base, apt_clearing);
|
||||
|
||||
// verify the poly has been generated
|
||||
if ( pre_tess.contours() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours" << " and " << pre_tess.total_size() << " points" );
|
||||
|
||||
// do this before clipping and generating the base
|
||||
// pre_tess = tgPolygonSimplify( pre_tess );
|
||||
// pre_tess = reduce_degeneracy( pre_tess );
|
||||
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
sprintf( layer_name, "original" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "original" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, pre_tess, feature_name );
|
||||
}
|
||||
|
||||
TGPolygon clipped = tgPolygonDiffClipperWithAccumulator( pre_tess );
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( clipped );
|
||||
sp.set_material( material );
|
||||
//sp.set_flag("taxi");
|
||||
|
||||
rwy_polys->push_back( sp );
|
||||
|
||||
tgPolygonAddToClipperAccumulator( pre_tess, false );
|
||||
|
||||
/* If debugging this poly, write the poly, and clipped poly and the accum buffer into their own layers */
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
sprintf( layer_name, "clipped" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "clipped" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, clipped, feature_name );
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tp construct");
|
||||
|
||||
tp = TGTexParams( pre_tess.get_pt(0,0).toSGGeod(), 5.0, 5.0, texture_heading );
|
||||
texparams->push_back( tp );
|
||||
|
||||
if ( apt_base )
|
||||
{
|
||||
base = tgPolygonExpand( pre_tess, 20.0);
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
sprintf( layer_name, "exp_base" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "exp_base" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, base, feature_name );
|
||||
}
|
||||
|
||||
safe_base = tgPolygonExpand( pre_tess, 50.0);
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "expanded safe poly: " << safe_base);
|
||||
|
||||
sprintf( layer_name, "exp_safe_base" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "exp_safe_base" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, safe_base, feature_name );
|
||||
}
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
}
|
||||
|
||||
if ( make_shapefiles )
|
||||
{
|
||||
tgShapefileCloseDatasource( ds_id );
|
||||
}
|
||||
}
|
||||
// and add the clearing to the base
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
}
|
||||
|
||||
// clean up to save ram : we're done here...
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, bool make_shapefiles )
|
||||
{
|
||||
if ( is_pavement && pre_tess.Contours() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.Contours() << " contours" << " and " << pre_tess.TotalNodes() << " points" );
|
||||
|
||||
tgPolygon clipped = tgPolygon::DiffWithAccumulator( pre_tess );
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
clipped.SetMaterial( GetMaterial( surface_type ) );
|
||||
clipped.SetTexParams( clipped.GetNode(0,0), 5.0, 5.0, texture_heading );
|
||||
clipped.SetTexLimits( 0.0, 0.0, 1.0, 1.0 );
|
||||
clipped.SetTexMethod( TG_TEX_BY_TPS_NOCLIP );
|
||||
|
||||
rwy_polys.push_back( clipped );
|
||||
|
||||
tgPolygon::AddToAccumulator( pre_tess );
|
||||
}
|
||||
|
||||
// clean up to save ram : we're done here...
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Just used for user defined border - add a little bit, as some modelers made the border exactly on the edges
|
||||
// - resulting in no base, which we can't handle
|
||||
int ClosedPoly::BuildBtg( TGPolygon* apt_base, TGPolygon* apt_clearing, bool make_shapefiles )
|
||||
int ClosedPoly::BuildBtg( tgPolygon& apt_base, tgPolygon& apt_clearing, bool make_shapefiles )
|
||||
{
|
||||
TGPolygon base, safe_base;
|
||||
tgPolygon base, safe_base;
|
||||
|
||||
// verify the poly has been generated
|
||||
if ( pre_tess.contours() )
|
||||
// verify the poly has been generated, and the contour isn't a pavement
|
||||
if ( !is_pavement && pre_tess.Contours() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
||||
|
||||
base = tgPolygonExpand( pre_tess, 2.0);
|
||||
safe_base = tgPolygonExpand( pre_tess, 5.0);
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.Contours() << " contours");
|
||||
|
||||
base = tgPolygon::Expand( pre_tess, 2.0);
|
||||
safe_base = tgPolygon::Expand( pre_tess, 5.0);
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing);
|
||||
apt_clearing = tgPolygon::Union( safe_base, apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -25,10 +25,20 @@ public:
|
|||
void Finish();
|
||||
|
||||
// Build BTG for airport base for airports with boundary
|
||||
int BuildBtg( TGPolygon* apt_base, TGPolygon* apt_clearing, bool make_shapefiles );
|
||||
int BuildBtg( tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing,
|
||||
bool make_shapefiles );
|
||||
|
||||
// Build BTG for pavements for airports with no boundary
|
||||
int BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, poly_list& slivers, TGPolygon* apt_base, TGPolygon* apt_clearing, bool make_shapefiles );
|
||||
int BuildBtg( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
int BuildBtg( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing,
|
||||
bool make_shapefiles );
|
||||
|
||||
FeatureList* GetFeatures()
|
||||
{
|
||||
|
@ -38,13 +48,15 @@ public:
|
|||
private:
|
||||
// convert the BezierPoly to a normal Poly (adding nodes for the curves)
|
||||
void CreateConvexHull( void );
|
||||
void ConvertContour( BezContour* src, point_list *dst );
|
||||
void ConvertContour( BezContour* src, tgContour& dst );
|
||||
void ExpandContour( point_list& src, TGPolygon& dst, double dist );
|
||||
std::string GetMaterial( int surface );
|
||||
|
||||
|
||||
bool is_pavement;
|
||||
int surface_type;
|
||||
float smoothness;
|
||||
float texture_heading;
|
||||
double texture_heading;
|
||||
string description;
|
||||
|
||||
// outer boundary definition as bezier nodes
|
||||
|
@ -60,7 +72,7 @@ private:
|
|||
point_list hull;
|
||||
|
||||
// Converted polygon after parsing complete
|
||||
TGPolygon pre_tess;
|
||||
tgPolygon pre_tess;
|
||||
|
||||
// pavement definitions have multiple linear features (markings and lights for each contour)
|
||||
LinearFeature* cur_feature;
|
||||
|
|
|
@ -40,7 +40,8 @@ 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 );
|
||||
}
|
||||
|
||||
superpoly_list Helipad::gen_helipad_lights(double maxsize){
|
||||
tglightcontour_list Helipad::gen_helipad_lights(double maxsize){
|
||||
tglightcontour_list result;
|
||||
|
||||
point_list y_lights; y_lights.clear();
|
||||
point_list y_normals; y_normals.clear();
|
||||
|
@ -50,71 +51,58 @@ superpoly_list Helipad::gen_helipad_lights(double maxsize){
|
|||
|
||||
// Create yellow edge lights, 5m spacing
|
||||
int divs = (int)(maxsize / 5.0);
|
||||
TGPolygon area = gen_runway_area_w_extend(0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
tgContour area = gen_runway_area_w_extend(0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
Point3D pt, inc;
|
||||
tgLightContour yellow;
|
||||
|
||||
yellow.SetType( "RWY_YELLOW_LIGHTS" );
|
||||
for ( unsigned int i = 0; i < area.GetSize(); ++i ) {
|
||||
pt = Point3D::fromSGGeod( area.GetNode( i ) );
|
||||
inc = (Point3D::fromSGGeod( area.GetNode( i==3 ? 0 : i+1) ) - Point3D::fromSGGeod( area.GetNode(i) ) ) / divs;
|
||||
|
||||
for ( int i = 0; i < area.contour_size( 0 ); ++i ) {
|
||||
pt = area.get_pt( 0, i );
|
||||
inc = (area.get_pt(0, i==3 ? 0 : i+1) - area.get_pt(0,i)) / divs;
|
||||
for ( int j = 0; j < divs; ++j) {
|
||||
y_lights.push_back( pt);
|
||||
y_normals.push_back(Point3D::fromSGVec3(vec));
|
||||
yellow.AddLight( pt.toSGGeod(), vec );
|
||||
pt += inc;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a circle of yellow lights where the white texture circle is
|
||||
for (int deg = 0; deg < 360; deg += 45){
|
||||
y_lights.push_back( Point3D::fromSGGeod( SGGeodesy::direct(GetLoc(), deg, maxsize * 0.46)) );
|
||||
y_normals.push_back( Point3D::fromSGVec3(vec) );
|
||||
yellow.AddLight( SGGeodesy::direct(GetLoc(), deg, maxsize * 0.46), vec );
|
||||
}
|
||||
|
||||
TGPolygon lights_poly; lights_poly.erase();
|
||||
TGPolygon normals_poly; normals_poly.erase();
|
||||
lights_poly.add_contour( y_lights, false );
|
||||
normals_poly.add_contour( y_normals, false );
|
||||
|
||||
TGSuperPoly yellow;
|
||||
yellow.set_poly( lights_poly );
|
||||
yellow.set_normals( normals_poly );
|
||||
yellow.set_material( "RWY_YELLOW_LIGHTS" );
|
||||
|
||||
superpoly_list result; result.clear();
|
||||
|
||||
result.push_back( yellow );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Helipad::WriteGeom( TGPolygon polygon, string material,
|
||||
superpoly_list *rwy_polys,
|
||||
poly_list& slivers )
|
||||
tgPolygon Helipad::WriteGeom( const tgContour& area, string material,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers )
|
||||
{
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
TGPolygon clipped = tgPolygonDiffClipperWithAccumulator( polygon );
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
tgPolygon clipped = tgContour::DiffWithAccumulator( area );
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
tgPolygon split = tgPolygon::SplitLongEdges( 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 );
|
||||
rwy_polys->push_back( sp );
|
||||
split.SetMaterial( material );
|
||||
rwy_polys.push_back( split );
|
||||
|
||||
tgPolygonAddToClipperAccumulator( polygon, false );
|
||||
tgContour::AddToAccumulator( area );
|
||||
|
||||
return split;
|
||||
}
|
||||
|
||||
void Helipad::BuildBtg( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
superpoly_list *rwy_lights,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing )
|
||||
void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
||||
tglightcontour_list& rwy_lights,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing )
|
||||
{
|
||||
//
|
||||
// Generate the basic helipad outlines
|
||||
|
@ -133,67 +121,61 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys,
|
|||
area_side = true;
|
||||
}
|
||||
|
||||
TGPolygon helipad = gen_wgs84_area( GetLoc(), maxsize, 0, 0, maxsize, heli.heading, false);
|
||||
helipad = snap( helipad, gSnap );
|
||||
tgContour helipad = gen_wgs84_area( GetLoc(), maxsize, 0, 0, maxsize, heli.heading, false);
|
||||
helipad = tgContour::Snap( helipad, gSnap );
|
||||
string material, shoulder_mat;
|
||||
if (heli.surface == 1)
|
||||
material = "pa_";
|
||||
else
|
||||
material = "pc_";
|
||||
// write out
|
||||
WriteGeom( helipad, material + "heli", rwy_polys, slivers);
|
||||
|
||||
TGTexParams tp;
|
||||
tp = TGTexParams( helipad.get_pt(0,0).toSGGeod(), maxsize, maxsize, heli.heading );
|
||||
tp.set_minu( 1 );
|
||||
tp.set_maxu( 0 );
|
||||
tp.set_minv( 1 );
|
||||
tp.set_maxv( 0 );
|
||||
texparams->push_back( tp );
|
||||
// write out
|
||||
tgPolygon result = WriteGeom( helipad, material + "heli", rwy_polys, slivers);
|
||||
result.SetTexParams( helipad.GetNode(0), maxsize, maxsize, heli.heading );
|
||||
result.SetTexLimits( 1,1,0,0 );
|
||||
result.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
|
||||
rwy_polys.push_back( result );
|
||||
|
||||
int i = 0;
|
||||
double heading = 0, areahight = 0;
|
||||
TGPolygon heli_area = gen_runway_area_w_extend(0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
heli_area = snap( heli_area, gSnap );
|
||||
TGPolygon area_poly; area_poly.erase();
|
||||
point_list area; area.clear();
|
||||
tgContour heli_area = gen_runway_area_w_extend(0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
heli_area = tgContour::Snap( heli_area, gSnap );
|
||||
|
||||
tgcontour_list area_contours;
|
||||
tgContour area;
|
||||
|
||||
if (area_top || area_side) {
|
||||
|
||||
if (area_top) {
|
||||
areahight = (heli.length - maxsize) /2;
|
||||
heading = heli.heading;
|
||||
heading = SGMiscd::normalizePeriodic( 0, 360, heli.heading-90 );
|
||||
i = 0;
|
||||
} else {
|
||||
areahight = (heli.width - maxsize) /2;
|
||||
heading = heli.heading - 90;
|
||||
if ( heading < 0.0 ) { heading += 360.0; }
|
||||
heading = SGMiscd::normalizePeriodic( 0, 360, heli.heading-90 );
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (;i<4; ++i) {
|
||||
area.push_back( heli_area.get_pt( 0,i ) );
|
||||
area.push_back( heli_area.get_pt( 0,i == 3? 0 : i+1 ) );
|
||||
area.push_back( helipad.get_pt( 0,i == 3? 0 : i+1) );
|
||||
area.push_back( helipad.get_pt( 0,i ) );
|
||||
area_poly.add_contour( area, false );
|
||||
area.clear();
|
||||
area.Erase();
|
||||
area.AddNode( heli_area.GetNode( i ) );
|
||||
area.AddNode( heli_area.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
area.AddNode( helipad.GetNode( i == 3 ? 0 : i+1) );
|
||||
area.AddNode( helipad.GetNode( i ) );
|
||||
area.SetHole( false );
|
||||
area_contours.push_back( area );
|
||||
i++;
|
||||
}
|
||||
|
||||
TGPolygon area_geom;
|
||||
tgPolygon result;
|
||||
for (i = 0; i < 2; ++i) {
|
||||
area_geom.add_contour(area_poly.get_contour(i), false);
|
||||
WriteGeom( area_geom, material + "tiedown", rwy_polys, slivers);
|
||||
|
||||
tp = TGTexParams( area_poly.get_pt(i,0).toSGGeod(), maxsize, areahight, heading );
|
||||
tp.set_minu( 1 );
|
||||
tp.set_maxu( 0 );
|
||||
tp.set_minv( 1 );
|
||||
tp.set_maxv( 0 );
|
||||
texparams->push_back( tp );
|
||||
area_geom.erase();
|
||||
heading += 180;
|
||||
if ( heading > 360.0 ) { heading -= 360.0; }
|
||||
result = WriteGeom( area_contours[i], material + "tiedown", rwy_polys, slivers);
|
||||
result.SetTexParams( area_contours[i].GetNode(0), maxsize, areahight, heading );
|
||||
result.SetTexLimits( 1,1,0,0 );
|
||||
result.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
rwy_polys.push_back( result );
|
||||
heading = SGMiscd::normalizePeriodic(0, 360, heading + 180 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,7 +190,6 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys,
|
|||
areahight = 1; // fake shoulder size in m
|
||||
}
|
||||
|
||||
TGSuperPoly sp;
|
||||
double shoulder_width = heli.length;
|
||||
heading = heli.heading;
|
||||
|
||||
|
@ -216,100 +197,234 @@ void Helipad::BuildBtg( superpoly_list *rwy_polys,
|
|||
shoulder_width = heli.width;
|
||||
}
|
||||
|
||||
TGPolygon shoulder = gen_runway_area_w_extend(0.0, areahight, 0.0, 0.0, areahight);
|
||||
shoulder = snap( shoulder, gSnap );
|
||||
tgContour shoulder = gen_runway_area_w_extend(0.0, areahight, 0.0, 0.0, areahight);
|
||||
shoulder = tgContour::Snap( shoulder, gSnap );
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
heading -= 90;
|
||||
if ( heading < 0.0 ) { heading += 360.0; }
|
||||
area_poly.erase();
|
||||
area.clear();
|
||||
heading = SGMiscd::normalizePeriodic(0,360,heading-90);
|
||||
area.Erase();
|
||||
area.AddNode( shoulder.GetNode( i ) );
|
||||
area.AddNode( shoulder.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
area.AddNode( heli_area.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
area.AddNode( heli_area.GetNode( i ) );
|
||||
area.SetHole(false);
|
||||
|
||||
area.push_back( shoulder.get_pt( 0,i ) );
|
||||
area.push_back( shoulder.get_pt( 0,i == 3? 0 : i+1 ) );
|
||||
area.push_back( heli_area.get_pt( 0,i == 3? 0 : i+1 ) );
|
||||
area.push_back( heli_area.get_pt( 0,i ) );
|
||||
area_poly.add_contour( area, false );
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( area_poly );
|
||||
sp.set_material( shoulder_mat );
|
||||
sp.set_flag( "heli-shoulder" );
|
||||
shoulder_polys.push_back( sp );
|
||||
|
||||
tp = TGTexParams( area_poly.get_pt(0,1).toSGGeod(), areahight, shoulder_width, heading );
|
||||
tp.set_minu( 1 );
|
||||
tp.set_maxu( 0 );
|
||||
tp.set_minv( 1 );
|
||||
tp.set_maxv( 0 );
|
||||
shoulder_tps.push_back( tp );
|
||||
}
|
||||
|
||||
// generate area around helipad
|
||||
if (apt_base)
|
||||
{
|
||||
TGPolygon base, safe_base;
|
||||
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, heli.length * 0.5, 0.0, 0.0, heli.width * 0.5 );
|
||||
safe_base = snap( safe_base, gSnap );
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper(safe_base, *apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
result.Erase();
|
||||
result.AddContour( area );
|
||||
result.SetMaterial( shoulder_mat );
|
||||
result.SetTexParams( area.GetNode(1), areahight, shoulder_width, heading );
|
||||
result.SetTexLimits( 1,1,0,0 );
|
||||
result.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
shoulder_polys.push_back( result );
|
||||
}
|
||||
|
||||
if (heli.edge_lights)
|
||||
{
|
||||
// Now generate the helipad lights
|
||||
superpoly_list s = gen_helipad_lights(maxsize);
|
||||
tglightcontour_list s = gen_helipad_lights(maxsize);
|
||||
for ( unsigned int i = 0; i < s.size(); ++i ) {
|
||||
rwy_lights->push_back( s[i] );
|
||||
rwy_lights.push_back( s[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// generate area around helipad
|
||||
tgContour base, safe_base;
|
||||
base = gen_runway_area_w_extend( 0.0, heli.length * 0.25 , 0.0, 0.0, heli.width * 0.25 );
|
||||
base = tgContour::Snap( base, gSnap );
|
||||
|
||||
// also clear a safe area around the pad
|
||||
safe_base = gen_runway_area_w_extend( 0.0, heli.length * 0.5, 0.0, 0.0, heli.width * 0.5 );
|
||||
safe_base = tgContour::Snap( safe_base, gSnap );
|
||||
|
||||
// add this to the airport clearing
|
||||
apt_clearing = tgPolygon::Union(safe_base, apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
}
|
||||
|
||||
void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
||||
tglightcontour_list& rwy_lights,
|
||||
tgcontour_list& slivers )
|
||||
{
|
||||
//
|
||||
// Generate the basic helipad outlines
|
||||
//
|
||||
|
||||
double maxsize = heli.width - heli.length;
|
||||
bool area_top = false;
|
||||
bool area_side = false;
|
||||
if (maxsize == 0) {
|
||||
maxsize = heli.width;
|
||||
} else if (maxsize < 0) {
|
||||
maxsize = heli.width;
|
||||
area_top = true;
|
||||
} else {
|
||||
maxsize = heli.length;
|
||||
area_side = true;
|
||||
}
|
||||
|
||||
tgContour helipad = gen_wgs84_area( GetLoc(), maxsize, 0, 0, maxsize, heli.heading, false);
|
||||
helipad = tgContour::Snap( helipad, gSnap );
|
||||
string material, shoulder_mat;
|
||||
if (heli.surface == 1)
|
||||
material = "pa_";
|
||||
else
|
||||
material = "pc_";
|
||||
|
||||
// write out
|
||||
tgPolygon result = WriteGeom( helipad, material + "heli", rwy_polys, slivers);
|
||||
result.SetTexParams( helipad.GetNode(0), maxsize, maxsize, heli.heading );
|
||||
result.SetTexLimits( 1,1,0,0 );
|
||||
result.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
rwy_polys.push_back( result );
|
||||
|
||||
int i = 0;
|
||||
double heading = 0, areahight = 0;
|
||||
tgContour heli_area = gen_runway_area_w_extend(0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
heli_area = tgContour::Snap( heli_area, gSnap );
|
||||
|
||||
tgcontour_list area_contours;
|
||||
tgContour area;
|
||||
|
||||
if (area_top || area_side) {
|
||||
|
||||
if (area_top) {
|
||||
areahight = (heli.length - maxsize) /2;
|
||||
heading = SGMiscd::normalizePeriodic( 0, 360, heli.heading-90 );
|
||||
i = 0;
|
||||
} else {
|
||||
areahight = (heli.width - maxsize) /2;
|
||||
heading = SGMiscd::normalizePeriodic( 0, 360, heli.heading-90 );
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (;i<4; ++i) {
|
||||
area.Erase();
|
||||
area.AddNode( heli_area.GetNode( i ) );
|
||||
area.AddNode( heli_area.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
area.AddNode( helipad.GetNode( i == 3 ? 0 : i+1) );
|
||||
area.AddNode( helipad.GetNode( i ) );
|
||||
area.SetHole( false );
|
||||
area_contours.push_back( area );
|
||||
i++;
|
||||
}
|
||||
|
||||
tgPolygon result;
|
||||
for (i = 0; i < 2; ++i) {
|
||||
result = WriteGeom( area_contours[i], material + "tiedown", rwy_polys, slivers);
|
||||
result.SetTexParams( area_contours[i].GetNode(0), maxsize, areahight, heading );
|
||||
result.SetTexLimits( 1,1,0,0 );
|
||||
result.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
rwy_polys.push_back( result );
|
||||
heading = SGMiscd::normalizePeriodic(0, 360, heading + 180 );
|
||||
}
|
||||
}
|
||||
|
||||
if (heli.shoulder == 1) {
|
||||
shoulder_mat = "pa_shoulder";
|
||||
areahight = 6; // shoulder size in m
|
||||
} else if (heli.shoulder == 2) {
|
||||
shoulder_mat = "pc_shoulder";
|
||||
areahight = 6; // shoulder size in m
|
||||
} else {
|
||||
shoulder_mat = material + "shoulder_f";
|
||||
areahight = 1; // fake shoulder size in m
|
||||
}
|
||||
|
||||
double shoulder_width = heli.length;
|
||||
heading = heli.heading;
|
||||
|
||||
if (area_side) {
|
||||
shoulder_width = heli.width;
|
||||
}
|
||||
|
||||
tgContour shoulder = gen_runway_area_w_extend(0.0, areahight, 0.0, 0.0, areahight);
|
||||
shoulder = tgContour::Snap( shoulder, gSnap );
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
heading = SGMiscd::normalizePeriodic(0,360,heading-90);
|
||||
area.Erase();
|
||||
area.AddNode( shoulder.GetNode( i ) );
|
||||
area.AddNode( shoulder.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
area.AddNode( heli_area.GetNode( i == 3 ? 0 : i+1 ) );
|
||||
area.AddNode( heli_area.GetNode( i ) );
|
||||
area.SetHole(false);
|
||||
|
||||
result.Erase();
|
||||
result.AddContour( area );
|
||||
result.SetMaterial( shoulder_mat );
|
||||
result.SetTexParams( area.GetNode(1), areahight, shoulder_width, heading );
|
||||
result.SetTexLimits( 1,1,0,0 );
|
||||
result.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
shoulder_polys.push_back( result );
|
||||
}
|
||||
|
||||
if (heli.edge_lights)
|
||||
{
|
||||
// Now generate the helipad lights
|
||||
tglightcontour_list s = gen_helipad_lights(maxsize);
|
||||
for ( unsigned int i = 0; i < s.size(); ++i ) {
|
||||
rwy_lights.push_back( s[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Helipad::BuildShoulder( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing )
|
||||
void Helipad::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing )
|
||||
{
|
||||
TGPolygon base, safe_base;
|
||||
TGPolygon shoulder;
|
||||
tgPolygon base, safe_base;
|
||||
tgPolygon shoulder;
|
||||
|
||||
for (unsigned int i=0; i<shoulder_polys.size(); i++) {
|
||||
shoulder = shoulder_polys[i].get_poly();
|
||||
shoulder = shoulder_polys[i];
|
||||
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
TGPolygon clipped = tgPolygonDiffClipperWithAccumulator( shoulder );
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
tgPolygon clipped = tgPolygon::DiffWithAccumulator( shoulder );
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
shoulder_polys[i].set_poly( split );
|
||||
tgPolygon split = tgPolygon::SplitLongEdges( clipped, 400.0 );
|
||||
shoulder_polys[i] = split;
|
||||
|
||||
rwy_polys->push_back( shoulder_polys[i] );
|
||||
texparams->push_back( shoulder_tps[i] );
|
||||
rwy_polys.push_back( shoulder_polys[i] );
|
||||
|
||||
tgPolygonAddToClipperAccumulator( shoulder, false );
|
||||
tgPolygon::AddToAccumulator( shoulder );
|
||||
|
||||
if (apt_base)
|
||||
{
|
||||
// also clear a safe area around the runway
|
||||
base = tgPolygonExpand( shoulder, 20.0);
|
||||
safe_base = tgPolygonExpand( shoulder, 50.0);
|
||||
// also clear a safe area around the runway
|
||||
base = tgPolygon::Expand( shoulder, 20.0);
|
||||
safe_base = tgPolygon::Expand( shoulder, 50.0);
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing );
|
||||
// add this to the airport clearing
|
||||
apt_clearing = tgPolygon::Union( safe_base, apt_clearing );
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
}
|
||||
// and add the clearing to the base
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
}
|
||||
}
|
||||
|
||||
void Helipad::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers )
|
||||
{
|
||||
tgPolygon shoulder;
|
||||
|
||||
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 = tgPolygon::DiffWithAccumulator( 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 );
|
||||
shoulder_polys[i] = split;
|
||||
|
||||
rwy_polys.push_back( shoulder_polys[i] );
|
||||
|
||||
tgPolygon::AddToAccumulator( shoulder );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,16 @@ class Helipad
|
|||
{
|
||||
public:
|
||||
Helipad(char* def);
|
||||
void BuildBtg( superpoly_list* heli_polys, texparams_list* texparams, superpoly_list* heli_lights, poly_list& slivers, TGPolygon* apt_base, TGPolygon* apt_clearing );
|
||||
|
||||
void BuildBtg( tgpolygon_list& heli_polys,
|
||||
tglightcontour_list& heli_lights,
|
||||
tgcontour_list& slivers );
|
||||
|
||||
void BuildBtg( tgpolygon_list& heli_polys,
|
||||
tglightcontour_list& heli_lights,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing );
|
||||
|
||||
SGGeod GetLoc()
|
||||
{
|
||||
|
@ -36,11 +45,13 @@ public:
|
|||
return (heli.surface < 3) ? true : false;
|
||||
}
|
||||
|
||||
void BuildShoulder( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing );
|
||||
void BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers );
|
||||
|
||||
void BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing );
|
||||
|
||||
private:
|
||||
struct TGRunway {
|
||||
|
@ -63,21 +74,21 @@ private:
|
|||
|
||||
// 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 )
|
||||
tgContour gen_runway_area_w_extend( double alt_m, double length_extend, double displ1, double displ2, double width_extend )
|
||||
{
|
||||
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(double maxsize);
|
||||
tglightcontour_list gen_helipad_lights(double maxsize);
|
||||
|
||||
// storage for Shoulders - The superpolys are generated during
|
||||
// helipad construction, but not clipped until shoulder construction.
|
||||
superpoly_list shoulder_polys;
|
||||
texparams_list shoulder_tps;
|
||||
tgpolygon_list shoulder_polys;
|
||||
|
||||
void WriteGeom( TGPolygon polygon, string material,
|
||||
superpoly_list *rwy_polys,
|
||||
poly_list& slivers );
|
||||
tgPolygon WriteGeom( const tgContour& area,
|
||||
string material,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers );
|
||||
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,9 +5,6 @@
|
|||
#include <Geometry/poly_support.hxx>
|
||||
#include <Geometry/util.hxx>
|
||||
|
||||
// for debugging clipping errors
|
||||
#include <Polygon/chop.hxx>
|
||||
|
||||
#include "global.hxx"
|
||||
#include "beznode.hxx"
|
||||
#include "linearfeature.hxx"
|
||||
|
@ -410,8 +407,7 @@ SGGeod LinearFeature::OffsetPointMiddle( const SGGeod& gPrev, const SGGeod& gCur
|
|||
// straight line blows up math - offset 90 degree and dist is as given
|
||||
courseOffset = SGMiscd::normalizePeriodic(0, 360, courseNext-90.0);
|
||||
distOffset = offset_by;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature: (normal case) " << description << ": theta is " << theta );
|
||||
|
||||
// calculate correct distance for the offset point
|
||||
|
@ -477,10 +473,7 @@ SGGeod midpoint( const SGGeod& p0, const SGGeod& p1 )
|
|||
|
||||
int LinearFeature::Finish( bool closed, unsigned int idx )
|
||||
{
|
||||
TGPolygon poly, poly2;
|
||||
TGPolygon normals_poly, normals_poly2;
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
tgPolygon poly;
|
||||
SGGeod prev_inner, prev_outer;
|
||||
SGGeod cur_inner, cur_outer;
|
||||
double heading;
|
||||
|
@ -650,22 +643,18 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
SGGeod cur_mp = midpoint( cur_outer, cur_inner );
|
||||
SGGeodesy::inverse( prev_mp, cur_mp, heading, az2, dist );
|
||||
|
||||
poly.erase();
|
||||
poly.add_node( 0, Point3D::fromSGGeod( prev_inner ) );
|
||||
poly.add_node( 0, Point3D::fromSGGeod( prev_outer ) );
|
||||
poly.add_node( 0, Point3D::fromSGGeod( cur_outer ) );
|
||||
poly.add_node( 0, Point3D::fromSGGeod( cur_inner ) );
|
||||
poly = snap( poly, gSnap );
|
||||
poly.Erase();
|
||||
poly.AddNode( 0, prev_inner );
|
||||
poly.AddNode( 0, prev_outer );
|
||||
poly.AddNode( 0, cur_outer );
|
||||
poly.AddNode( 0, cur_inner );
|
||||
poly = tgPolygon::Snap( poly, gSnap );
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( poly );
|
||||
sp.set_material( material );
|
||||
sp.set_flag("lf");
|
||||
marking_polys.push_back(sp);
|
||||
|
||||
tp = TGTexParams( prev_inner, width, 1.0f, heading );
|
||||
tp.set_minv(last_end_v);
|
||||
marking_tps.push_back(tp);
|
||||
poly.SetMaterial( material );
|
||||
poly.SetTexParams( prev_inner, width, 1.0f, heading );
|
||||
poly.SetTexLimits( 0, last_end_v, 1, 1 );
|
||||
poly.SetTexMethod( TG_TEX_BY_TPS_CLIPU, -1.0, 0.0, 1.0, 0.0 );
|
||||
marking_polys.push_back(poly);
|
||||
|
||||
last_end_v = (double)1.0f - (fmod( (double)(dist - last_end_v), (double)1.0f ));
|
||||
} else {
|
||||
|
@ -678,6 +667,10 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
}
|
||||
|
||||
// now generate the superpoly list for lights with constant distance between lights (depending on feature type)
|
||||
tglightcontour_list light_contours;
|
||||
tgLightContour cur_light_contour;
|
||||
tgLightContour alt_light_contour;
|
||||
|
||||
for (unsigned int i=0; i<lights.size(); i++)
|
||||
{
|
||||
markStarted = false;
|
||||
|
@ -689,43 +682,38 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
switch( lights[i]->type )
|
||||
{
|
||||
case LF_BIDIR_GREEN:
|
||||
material = "RWY_GREEN_TAXIWAY_LIGHTS";
|
||||
cur_light_contour.SetType( "RWY_GREEN_TAXIWAY_LIGHTS" );
|
||||
light_delta = 10.0f;
|
||||
break;
|
||||
|
||||
case LF_OMNIDIR_BLUE:
|
||||
material = "RWY_BLUE_TAXIWAY_LIGHTS";
|
||||
cur_light_contour.SetType( "RWY_BLUE_TAXIWAY_LIGHTS" );
|
||||
light_delta = 10.0f;
|
||||
break;
|
||||
|
||||
case LF_UNIDIR_CLOSE_AMBER:
|
||||
material = "RWY_YELLOW_LIGHTS";
|
||||
cur_light_contour.SetType( "RWY_YELLOW_LIGHTS" );
|
||||
light_delta = 2.0f;
|
||||
break;
|
||||
|
||||
case LF_UNIDIR_CLOSE_AMBER_PULSE:
|
||||
material = "RWY_YELLOW_PULSE_LIGHTS";
|
||||
cur_light_contour.SetType( "RWY_YELLOW_PULSE_LIGHTS" );
|
||||
light_delta = 2.0f;
|
||||
break;
|
||||
|
||||
case LF_BIDIR_GREEN_AMBER:
|
||||
material = "RWY_GREEN_TAXIWAY_LIGHTS";
|
||||
cur_light_contour.SetType( "RWY_GREEN_TAXIWAY_LIGHTS" );
|
||||
alt_light_contour.SetType( "RWY_YELLOW_LIGHTS" );
|
||||
light_delta = 10.0f;
|
||||
alternate = true;
|
||||
break;
|
||||
|
||||
case LF_OMNIDIR_RED:
|
||||
material = "RWY_RED_LIGHTS";
|
||||
cur_light_contour.SetType( "RWY_RED_LIGHTS" );
|
||||
light_delta = 10.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
poly.erase();
|
||||
poly2.erase();
|
||||
normals_poly.erase();
|
||||
normals_poly2.erase();
|
||||
sp.erase();
|
||||
|
||||
for (unsigned int j = lights[i]->start_idx; j <= lights[i]->end_idx; j++)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::Finish: calculating offsets for light " << i << " whose start idx is " << lights[i]->start_idx << " and end idx is " << lights[i]->end_idx << " cur idx is " << j );
|
||||
|
@ -781,23 +769,19 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
|
||||
if (!alternate)
|
||||
{
|
||||
poly.add_node(0, Point3D::fromSGGeod(tmp));
|
||||
normals_poly.add_node(0, Point3D::fromSGVec3(vec) );
|
||||
cur_light_contour.AddLight( tmp, vec );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (switch_poly)
|
||||
{
|
||||
poly.add_node(0, Point3D::fromSGGeod(tmp));
|
||||
normals_poly.add_node(0, Point3D::fromSGVec3(vec) );
|
||||
switch_poly = !switch_poly;
|
||||
cur_light_contour.AddLight( tmp, vec );
|
||||
}
|
||||
else
|
||||
{
|
||||
poly2.add_node(0, Point3D::fromSGGeod(tmp));
|
||||
normals_poly2.add_node(0, Point3D::fromSGVec3(vec) );
|
||||
switch_poly = !switch_poly;
|
||||
alt_light_contour.AddLight( tmp, vec );
|
||||
}
|
||||
switch_poly = !switch_poly;
|
||||
}
|
||||
|
||||
// update current light distance
|
||||
|
@ -814,26 +798,19 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
}
|
||||
|
||||
// if there were lights generated - create the superpoly
|
||||
if (poly.total_size())
|
||||
if (cur_light_contour.ContourSize())
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::Finish: Adding superpoly with " << poly.total_size() << " lights" );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::Finish: Adding light contour with " << cur_light_contour.ContourSize() << " lights" );
|
||||
cur_light_contour.SetFlag("");
|
||||
lighting_polys.push_back(cur_light_contour);
|
||||
}
|
||||
|
||||
sp.set_poly( poly );
|
||||
sp.set_normals( normals_poly );
|
||||
sp.set_material( material );
|
||||
sp.set_flag("");
|
||||
lighting_polys.push_back(sp);
|
||||
|
||||
// create the superpoly for the alternating light color
|
||||
if (poly2.total_size())
|
||||
{
|
||||
sp.erase();
|
||||
sp.set_poly( poly2 );
|
||||
sp.set_normals( normals_poly2 );
|
||||
sp.set_material( "RWY_YELLOW_LIGHTS" );
|
||||
sp.set_flag("");
|
||||
lighting_polys.push_back(sp);
|
||||
}
|
||||
// create the superpoly for the alternating light color
|
||||
if (alt_light_contour.ContourSize())
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::Finish: Adding light contour with " << cur_light_contour.ContourSize() << " lights" );
|
||||
alt_light_contour.SetFlag("");
|
||||
lighting_polys.push_back(cur_light_contour);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -844,53 +821,26 @@ int LinearFeature::Finish( bool closed, unsigned int idx )
|
|||
return 1;
|
||||
}
|
||||
|
||||
int LinearFeature::BuildBtg(superpoly_list* line_polys, texparams_list* line_tps, superpoly_list* lights, bool make_shapefiles )
|
||||
int LinearFeature::BuildBtg(tgpolygon_list& line_polys, tglightcontour_list& lights, bool make_shapefiles )
|
||||
{
|
||||
TGPolygon poly, tmp;
|
||||
void* ds_id = NULL; // If we are going to build shapefiles
|
||||
void* l_id = NULL; // datasource and layer IDs
|
||||
SGGeod min, max, minp, maxp;
|
||||
|
||||
if ( make_shapefiles ) {
|
||||
char ds_name[128];
|
||||
sprintf(ds_name, "./lf_debug");
|
||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||
}
|
||||
tgPolygon poly;
|
||||
SGGeod min, max, minp, maxp;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::BuildBtg: " << description);
|
||||
for ( unsigned int i = 0; i < marking_polys.size(); i++)
|
||||
{
|
||||
poly = tgPolygonDiffClipperWithAccumulator( marking_polys[i].get_poly() );
|
||||
// Clipping and triangulation need to copy texparams, and material info...
|
||||
marking_polys[i] = tgPolygon::DiffWithAccumulator( marking_polys[i] );
|
||||
line_polys.push_back( marking_polys[i] );
|
||||
|
||||
marking_polys[i].set_poly( poly );
|
||||
line_polys->push_back( marking_polys[i] );
|
||||
|
||||
/* If debugging this lf, write the polys into their own layers */
|
||||
if (ds_id) {
|
||||
char layer_name[128];
|
||||
sprintf( layer_name, "poly_%d", i );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
|
||||
char feature_name[128];
|
||||
sprintf( feature_name, "poly_%d", i);
|
||||
tgShapefileCreateFeature( ds_id, l_id, poly, feature_name );
|
||||
}
|
||||
|
||||
tgPolygonAddToClipperAccumulator(poly, false);
|
||||
|
||||
line_tps->push_back( marking_tps[i] );
|
||||
}
|
||||
|
||||
if (ds_id) {
|
||||
tgShapefileCloseDatasource( ds_id );
|
||||
tgPolygon::AddToAccumulator( marking_polys[i] );
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: add " << lighting_polys.size() << " light defs");
|
||||
for ( unsigned i = 0; i < lighting_polys.size(); i++)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: adding light " << i );
|
||||
lights->push_back( lighting_polys[i] );
|
||||
lights.push_back( lighting_polys[i] );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -97,17 +97,15 @@ public:
|
|||
}
|
||||
|
||||
int Finish( bool closed, unsigned int idx );
|
||||
int BuildBtg( superpoly_list* line_polys, texparams_list* line_tps, superpoly_list* lights, bool debug );
|
||||
// int BuildBtg( float alt_m, superpoly_list* line_polys, texparams_list* line_tps, ClipPolyType* line_accum, superpoly_list* lights );
|
||||
int BuildBtg( tgpolygon_list& line_polys, tglightcontour_list& lights, bool debug );
|
||||
|
||||
private:
|
||||
SGGeod OffsetPointFirst( const SGGeod& cur, const SGGeod& next, double offset_by );
|
||||
SGGeod OffsetPointMiddle( const SGGeod& prev, const SGGeod& cur, const SGGeod& next, double offset_by );
|
||||
SGGeod OffsetPointLast( const SGGeod& prev, const SGGeod& cur, double offset_by );
|
||||
|
||||
|
||||
double offset;
|
||||
double width;
|
||||
double offset;
|
||||
double width;
|
||||
|
||||
MarkingList marks;
|
||||
Marking* cur_mark;
|
||||
|
@ -119,17 +117,15 @@ private:
|
|||
|
||||
// text description
|
||||
string description;
|
||||
|
||||
|
||||
// contour definition (each beznode has marking type)
|
||||
BezContour contour;
|
||||
|
||||
// contour definition after bezier interpolation
|
||||
point_list points;
|
||||
|
||||
superpoly_list marking_polys;
|
||||
texparams_list marking_tps;
|
||||
|
||||
superpoly_list lighting_polys;
|
||||
tgpolygon_list marking_polys;
|
||||
tglightcontour_list lighting_polys;
|
||||
};
|
||||
|
||||
typedef std::vector <LinearFeature *> FeatureList;
|
||||
|
|
|
@ -120,6 +120,9 @@ int nudge = 10;
|
|||
double slope_max = 0.02;
|
||||
double gSnap = 0.00000001; // approx 1 mm
|
||||
|
||||
//TODO : new polygon chop API
|
||||
extern bool tgPolygon_index_init( const std::string& path );
|
||||
|
||||
// For creating a buffered stream to write to the socket
|
||||
Net::StreamSocket ss;
|
||||
Net::SocketStreamBuf ssb( ss );
|
||||
|
@ -328,13 +331,13 @@ int main(int argc, char **argv)
|
|||
SGPath sgp( airportareadir );
|
||||
sgp.append( "dummy" );
|
||||
sgp.create_dir( 0755 );
|
||||
|
||||
|
||||
string command = argv[0];
|
||||
string lastaptfile = work_dir+"/last_apt";
|
||||
|
||||
// initialize persistant polygon counter
|
||||
string counter_file = airportareadir+"/poly_counter";
|
||||
poly_index_init( counter_file );
|
||||
tgPolygon_index_init( counter_file );
|
||||
|
||||
// Initialize shapefile support (for debugging)
|
||||
tgShapefileInit();
|
||||
|
|
|
@ -9,23 +9,20 @@ LightingObj::LightingObj( char* definition )
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "Read lighting object: (" << lon << "," << lat << ") heading: " << heading << " type: " << type );
|
||||
}
|
||||
|
||||
void LightingObj::BuildBtg( superpoly_list* lights )
|
||||
void LightingObj::BuildBtg( tglightcontour_list& lights )
|
||||
{
|
||||
point_list lightobj; lightobj.clear();
|
||||
point_list normals; normals.clear();
|
||||
tgLightContour light_contour;
|
||||
light_contour.SetType( "RWY_VASI_LIGHTS" );
|
||||
|
||||
double left_hdg = heading - 90.0;
|
||||
if ( left_hdg < 0 ) { left_hdg += 360.0; }
|
||||
|
||||
SGGeod ref = SGGeod::fromDeg(lon, lat);
|
||||
double left_hdg = SGMiscd::normalizePeriodic(0, 360, heading - 90.0 );
|
||||
SGGeod ref = SGGeod::fromDeg(lon, lat);
|
||||
|
||||
// Calculate the light normal with the help of a second point
|
||||
// in the object heading direction.
|
||||
// SimGear takes care of the glideslope angle calculation from the normal
|
||||
SGVec3d cart1 = SGVec3d::fromGeod(SGGeodesy::direct( ref, heading, 10));
|
||||
SGVec3d cart2 = SGVec3d::fromGeod(ref);
|
||||
|
||||
Point3D normal = Point3D::fromSGVec3(normalize(cart2 - cart1));
|
||||
SGVec3d normal = normalize(cart2 - cart1);
|
||||
|
||||
// We know our normal, now create the lights
|
||||
SGGeod pt1;
|
||||
|
@ -42,15 +39,13 @@ void LightingObj::BuildBtg( superpoly_list* lights )
|
|||
|
||||
// unit1
|
||||
pt1 = SGGeodesy::direct( pt1, left_hdg, -5 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
|
||||
// unit2+3
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
pt1 = SGGeodesy::direct( pt1, left_hdg, 5 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
}
|
||||
|
||||
// Go to upwind bar
|
||||
|
@ -58,15 +53,13 @@ void LightingObj::BuildBtg( superpoly_list* lights )
|
|||
|
||||
// unit4
|
||||
pt1 = SGGeodesy::direct( pt1, left_hdg, -5 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
|
||||
// unit5+6
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
pt1 = SGGeodesy::direct( pt1, left_hdg,5 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
}
|
||||
}
|
||||
else if (type == 2)
|
||||
|
@ -75,15 +68,13 @@ void LightingObj::BuildBtg( superpoly_list* lights )
|
|||
|
||||
// unit1
|
||||
pt1 = SGGeodesy::direct( ref, left_hdg, -12 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
|
||||
// unit2-4
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
pt1 = SGGeodesy::direct( pt1, left_hdg, 8 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
}
|
||||
}
|
||||
else if (type == 3)
|
||||
|
@ -92,15 +83,13 @@ void LightingObj::BuildBtg( superpoly_list* lights )
|
|||
|
||||
// unit1
|
||||
pt1 = SGGeodesy::direct( ref, left_hdg, 12 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
|
||||
// unit2-4
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
pt1 = SGGeodesy::direct( pt1, left_hdg, -8 );
|
||||
lightobj.push_back( Point3D::fromSGGeod(pt1) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( pt1, normal );
|
||||
}
|
||||
}
|
||||
else if (type == 4)
|
||||
|
@ -113,8 +102,7 @@ void LightingObj::BuildBtg( superpoly_list* lights )
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "Generating tri-colour VASI = " << assoc_rw);
|
||||
|
||||
// only one light here
|
||||
lightobj.push_back( Point3D::fromSGGeod(ref) );
|
||||
normals.push_back( normal );
|
||||
light_contour.AddLight( ref, normal );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -122,15 +110,5 @@ void LightingObj::BuildBtg( superpoly_list* lights )
|
|||
return;
|
||||
}
|
||||
|
||||
TGPolygon lights_poly; lights_poly.erase();
|
||||
TGPolygon normals_poly; normals_poly.erase();
|
||||
lights_poly.add_contour( lightobj, false );
|
||||
normals_poly.add_contour( normals, false );
|
||||
|
||||
TGSuperPoly result;
|
||||
result.set_poly( lights_poly );
|
||||
result.set_normals( normals_poly );
|
||||
result.set_material( "RWY_VASI_LIGHTS" );
|
||||
|
||||
lights->push_back( result);
|
||||
lights.push_back( light_contour);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
char assoc_rw;
|
||||
|
||||
|
||||
void BuildBtg( superpoly_list* lights );
|
||||
void BuildBtg( tglightcontour_list& lights );
|
||||
|
||||
};
|
||||
typedef std::vector <LightingObj *> LightingObjList;
|
||||
|
|
|
@ -455,16 +455,19 @@ int Parser::ParseLine(char* line)
|
|||
|
||||
case PAVEMENT_CODE:
|
||||
SetState( STATE_PARSE_PAVEMENT );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing pavement: " << line);
|
||||
cur_pavement = ParsePavement( line );
|
||||
break;
|
||||
|
||||
case LINEAR_FEATURE_CODE:
|
||||
SetState( STATE_PARSE_FEATURE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Linear Feature: " << line);
|
||||
cur_feat = ParseFeature( line );
|
||||
break;
|
||||
|
||||
case BOUNDRY_CODE:
|
||||
SetState( STATE_PARSE_BOUNDARY );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing Boundary: " << line);
|
||||
cur_boundary = ParseBoundary( line );
|
||||
break;
|
||||
|
||||
|
|
|
@ -60,10 +60,9 @@ WaterRunway::WaterRunway(char* definition)
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "Read water runway: (" << lon[0] << "," << lat[0] << ") to (" << lon[1] << "," << lat[1] << ") width: " << width << " buoys = " << buoys );
|
||||
}
|
||||
|
||||
point_list WaterRunway::GetNodes()
|
||||
tgContour WaterRunway::GetNodes()
|
||||
{
|
||||
point_list buoys_nodes;
|
||||
buoys_nodes.clear();
|
||||
tgContour buoys_nodes;
|
||||
|
||||
if (buoys){
|
||||
double heading, az2, length;
|
||||
|
@ -72,15 +71,17 @@ point_list WaterRunway::GetNodes()
|
|||
|
||||
// create a polygon for the outline and use it to calculate the point list
|
||||
int divs = (int)(length / 100.0);
|
||||
TGPolygon area = gen_wgs84_area(GetStart(), GetEnd(),
|
||||
tgContour area = gen_wgs84_area(GetStart(), GetEnd(),
|
||||
0, 0, 0, width, heading, false);
|
||||
Point3D pt, inc;
|
||||
Point3D pt, inc;
|
||||
|
||||
for ( int i = 0; i < area.contour_size( 0 ); ++i ) {
|
||||
pt = area.get_pt( 0, i );
|
||||
inc = (area.get_pt(0, i==3 ? 0 : i+1) - area.get_pt(0,i)) / divs;
|
||||
for ( unsigned int i = 0; i < area.GetSize(); ++i ) {
|
||||
pt = Point3D::fromSGGeod( area.GetNode(i) );
|
||||
inc = ( Point3D::fromSGGeod( area.GetNode(i==3 ? 0 : i+1) ) -
|
||||
Point3D::fromSGGeod( area.GetNode(i)) ) / divs;
|
||||
|
||||
for ( int j = 0; j < divs; ++j) {
|
||||
buoys_nodes.push_back( pt);
|
||||
buoys_nodes.AddNode( pt.toSGGeod() );
|
||||
pt += inc;
|
||||
}
|
||||
}
|
||||
|
@ -88,31 +89,56 @@ point_list WaterRunway::GetNodes()
|
|||
return buoys_nodes;
|
||||
}
|
||||
|
||||
|
||||
int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, poly_list& slivers, TGPolygon* apt_base, TGPolygon* apt_clearing, bool make_shapefiles )
|
||||
point_list WaterRunway::TempGetAsPointList()
|
||||
{
|
||||
TGPolygon base, safe_base;
|
||||
point_list buoys_nodes;
|
||||
|
||||
if (buoys){
|
||||
double heading, az2, length;
|
||||
// calculate runway heading and length
|
||||
SGGeodesy::inverse(GetStart(), GetEnd(), heading, az2, length);
|
||||
|
||||
// create a polygon for the outline and use it to calculate the point list
|
||||
int divs = (int)(length / 100.0);
|
||||
tgContour area = gen_wgs84_area(GetStart(), GetEnd(),
|
||||
0, 0, 0, width, heading, false);
|
||||
Point3D pt, inc;
|
||||
|
||||
for ( unsigned int i = 0; i < area.GetSize(); ++i ) {
|
||||
pt = Point3D::fromSGGeod( area.GetNode( i ) );
|
||||
inc = ( Point3D::fromSGGeod( area.GetNode(i==3 ? 0 : i+1) ) -
|
||||
Point3D::fromSGGeod( area.GetNode(i)) ) / divs;
|
||||
for ( int j = 0; j < divs; ++j) {
|
||||
buoys_nodes.push_back( pt );
|
||||
pt += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buoys_nodes;
|
||||
}
|
||||
|
||||
int Runway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, bool make_shapefiles )
|
||||
{
|
||||
if ( rwy.surface == 1 /* Asphalt */ )
|
||||
{
|
||||
material_prefix = "pa_";
|
||||
}
|
||||
}
|
||||
else if ( rwy.surface == 2 /* Concrete */ )
|
||||
{
|
||||
material_prefix = "pc_";
|
||||
}
|
||||
}
|
||||
else if ( rwy.surface == 3 /* Turf/Grass */ )
|
||||
{
|
||||
material_prefix = "grass_rwy";
|
||||
}
|
||||
}
|
||||
else if ( rwy.surface == 4 /* Dirt */ || rwy.surface == 5 /* Gravel */ )
|
||||
{
|
||||
material_prefix = "dirt_rwy";
|
||||
}
|
||||
}
|
||||
else if ( rwy.surface == 12 /* Dry Lakebed */ )
|
||||
{
|
||||
material_prefix = "lakebed_taxiway";
|
||||
}
|
||||
}
|
||||
else if ( rwy.surface == 13 /* Water runway (buoys) */ )
|
||||
{
|
||||
// water
|
||||
|
@ -125,10 +151,10 @@ int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, supe
|
|||
{
|
||||
//Transparent texture
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "surface_code = " << rwy.surface);
|
||||
throw sg_exception("unknown runway type!");
|
||||
throw sg_exception("unknown runway type!");
|
||||
}
|
||||
|
||||
// first, check the surface type - anything but concrete and asphalt are easy
|
||||
|
@ -137,16 +163,16 @@ int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, supe
|
|||
case 1: // asphalt:
|
||||
case 2: // concrete
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: asphalt or concrete " << rwy.surface);
|
||||
gen_rwy( rwy_polys, texparams, slivers, make_shapefiles );
|
||||
gen_rwy( rwy_polys, slivers, make_shapefiles );
|
||||
gen_runway_lights( rwy_lights );
|
||||
break;
|
||||
|
||||
|
||||
case 3: // Grass
|
||||
case 4: // Dirt
|
||||
case 5: // Gravel
|
||||
case 12: // dry lakebed
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Grass, Dirt, Gravel or Dry Lakebed " << rwy.surface );
|
||||
gen_simple_rwy( rwy_polys, texparams, slivers );
|
||||
gen_simple_rwy( rwy_polys, slivers );
|
||||
gen_runway_lights( rwy_lights );
|
||||
break;
|
||||
|
||||
|
@ -165,24 +191,30 @@ int Runway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, supe
|
|||
default: // unknown
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: unknown: " << rwy.surface);
|
||||
break;
|
||||
}
|
||||
|
||||
if (apt_base)
|
||||
{
|
||||
// generate area around runways
|
||||
base = gen_runway_area_w_extend( 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0 );
|
||||
base = snap( base, gSnap );
|
||||
|
||||
// also clear a safe area around the runway
|
||||
safe_base = gen_runway_area_w_extend( 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 );
|
||||
safe_base = snap( safe_base, gSnap );
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing );
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Runway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgPolygon& apt_base, tgPolygon& apt_clearing, bool make_shapefiles )
|
||||
{
|
||||
tgContour base, safe_base;
|
||||
|
||||
BuildBtg( rwy_polys, rwy_lights, slivers, make_shapefiles );
|
||||
|
||||
// generate area around runways
|
||||
base = gen_runway_area_w_extend( 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0 );
|
||||
base = tgContour::Snap( base, gSnap );
|
||||
|
||||
// also clear a safe area around the runway
|
||||
safe_base = gen_runway_area_w_extend( 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 );
|
||||
safe_base = tgContour::Snap( safe_base, gSnap );
|
||||
|
||||
// add this to the airport clearing
|
||||
apt_clearing = tgPolygon::Union( safe_base, apt_clearing );
|
||||
|
||||
// and add the clearing to the base
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -39,19 +39,25 @@ public:
|
|||
return (rwy.surface < 3) ? true : false;
|
||||
}
|
||||
|
||||
int BuildBtg( superpoly_list* rwy_polys,
|
||||
texparams_list* texparams,
|
||||
superpoly_list* rwy_lights,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing,
|
||||
int BuildBtg( tgpolygon_list& rwy_polys,
|
||||
tglightcontour_list& rwy_lights,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
void BuildShoulder( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing );
|
||||
int BuildBtg( tgpolygon_list& rwy_polys,
|
||||
tglightcontour_list& rwy_lights,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing,
|
||||
bool make_shapefiles );
|
||||
|
||||
void BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers );
|
||||
|
||||
void BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing );
|
||||
|
||||
private:
|
||||
struct TGRunway {
|
||||
|
@ -85,61 +91,66 @@ private:
|
|||
|
||||
// storage for Shoulders - The superpolys are generated during rwy construction,
|
||||
// but not clipped until shoulder construction.
|
||||
superpoly_list shoulder_polys;
|
||||
texparams_list shoulder_tps;
|
||||
tgpolygon_list shoulder_polys;
|
||||
|
||||
// Build Helpers:
|
||||
// generate an area for a runway and include midpoints
|
||||
TGPolygon gen_runway_w_mid( double length_extend_m, double width_extend_m )
|
||||
tgContour gen_runway_w_mid( double length_extend_m, double width_extend_m )
|
||||
{
|
||||
return ( gen_wgs84_area( GetStart(), GetEnd(), 2.0*length_extend_m, 0.0, 0.0, rwy.width + 2.0 * width_extend_m, rwy.heading, true) );
|
||||
}
|
||||
|
||||
// generate an area for a runway with expansion specified in meters
|
||||
// (return result points in degrees)
|
||||
TGPolygon gen_runway_area_w_extend( double length_extend, double displ1, double displ2, double width_extend )
|
||||
tgContour gen_runway_area_w_extend( double length_extend, double displ1, double displ2, double width_extend )
|
||||
{
|
||||
return ( gen_wgs84_area( GetStart(), GetEnd(), 2.0*length_extend, displ1, displ2, rwy.width + 2.0*width_extend, rwy.heading, false) );
|
||||
}
|
||||
|
||||
void gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
||||
void gen_rw_designation( tgPolygon poly, double heading, string rwname,
|
||||
double &start_pct, double &end_pct,
|
||||
superpoly_list* rwy_polys,
|
||||
texparams_list* texparams,
|
||||
poly_list& slivers,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
// generate a section of runway
|
||||
void gen_runway_section( const TGPolygon& runway,
|
||||
// generate a section of runway with shoulders
|
||||
void 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& material,
|
||||
superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
superpoly_list *shoulder_polys,
|
||||
texparams_list *shoulder_tps,
|
||||
poly_list& slivers,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgpolygon_list& shoulder_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
// generate a section of runway without shoulders
|
||||
void 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& material,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
// generate a section of shoulder
|
||||
void gen_shoulder_section( Point3D p0, Point3D p1,
|
||||
Point3D t0, Point3D t1,
|
||||
int side,
|
||||
double heading,
|
||||
double width,
|
||||
std::string surface,
|
||||
TGSuperPoly& sp, TGTexParams& tp );
|
||||
tgPolygon gen_shoulder_section( SGGeod& p0, SGGeod& p1,
|
||||
SGGeod& t0, SGGeod& t1,
|
||||
int side,
|
||||
double heading,
|
||||
double width,
|
||||
std::string surface );
|
||||
|
||||
void gen_simple_rwy( superpoly_list *rwy_polys, texparams_list *texparams, poly_list& slivers );
|
||||
void gen_simple_rwy( tgpolygon_list& rwy_polys, tgcontour_list& slivers );
|
||||
|
||||
void gen_rwy( superpoly_list* rwy_polys,
|
||||
texparams_list* texparams,
|
||||
poly_list& slivers,
|
||||
void gen_rwy( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
void gen_runway_lights( superpoly_list* lights );
|
||||
void gen_runway_lights( tglightcontour_list& lights );
|
||||
|
||||
int get_thresh0(bool recip)
|
||||
{
|
||||
|
@ -156,17 +167,17 @@ private:
|
|||
return (rwy.threshold[get_thresh0(recip)] > 60.0) ? true : false;
|
||||
}
|
||||
|
||||
Point3D gen_runway_light_vector( float angle, bool recip );
|
||||
superpoly_list gen_runway_edge_lights( bool recip );
|
||||
superpoly_list gen_runway_threshold_lights( const int kind, bool recip );
|
||||
superpoly_list gen_runway_center_line_lights( bool recip );
|
||||
TGSuperPoly gen_touchdown_zone_lights( bool recip );
|
||||
TGSuperPoly gen_reil( const int kind, bool recip );
|
||||
superpoly_list gen_calvert( const string &kind, bool recip );
|
||||
superpoly_list gen_alsf( const string &kind, bool recip );
|
||||
TGSuperPoly gen_odals( const int kind, bool recip );
|
||||
superpoly_list gen_ssalx( const string& kind, bool recip );
|
||||
superpoly_list gen_malsx( const string& kind, bool recip );
|
||||
SGVec3d gen_runway_light_vector( float angle, bool recip );
|
||||
tglightcontour_list gen_runway_edge_lights( bool recip );
|
||||
tglightcontour_list gen_runway_threshold_lights( const int kind, bool recip );
|
||||
tglightcontour_list gen_runway_center_line_lights( bool recip );
|
||||
tgLightContour gen_touchdown_zone_lights( bool recip );
|
||||
tgLightContour gen_reil( const int kind, bool recip );
|
||||
tglightcontour_list gen_calvert( const string &kind, bool recip );
|
||||
tglightcontour_list gen_alsf( const string &kind, bool recip );
|
||||
tgLightContour gen_odals( const int kind, bool recip );
|
||||
tglightcontour_list gen_ssalx( const string& kind, bool recip );
|
||||
tglightcontour_list gen_malsx( const string& kind, bool recip );
|
||||
};
|
||||
|
||||
typedef std::vector <Runway *> RunwayList;
|
||||
|
@ -177,7 +188,8 @@ class WaterRunway
|
|||
public:
|
||||
WaterRunway(char* def);
|
||||
|
||||
point_list GetNodes();
|
||||
tgContour GetNodes();
|
||||
point_list TempGetAsPointList();
|
||||
|
||||
SGGeod GetStart(void)
|
||||
{
|
||||
|
|
|
@ -88,92 +88,77 @@ static const struct sections nprec[] = {
|
|||
};
|
||||
|
||||
|
||||
void Runway::gen_shoulder_section( Point3D p0, Point3D p1, Point3D t0, Point3D t1, int side, double heading, double width, std::string surface, TGSuperPoly& sp, TGTexParams& tp )
|
||||
tgPolygon Runway::gen_shoulder_section( SGGeod& p0, SGGeod& p1, SGGeod& t0, SGGeod& t1, int side, double heading, double width, std::string surface )
|
||||
{
|
||||
Point3D s0, s1, s2, s3;
|
||||
TGPolygon poly;
|
||||
SGGeod s0, s1, s2, s3;
|
||||
tgPolygon poly;
|
||||
|
||||
double wid_hdg = 0.0f;
|
||||
double az2 = 0.0f;
|
||||
double dist = 0.0f;
|
||||
double pt_x = 0.0f;
|
||||
double pt_y = 0.0f;
|
||||
|
||||
// calc heading from p1 to p0
|
||||
geo_inverse_wgs_84( p0.y(), p0.x(), p1.y(), p1.x(), &wid_hdg, &az2, &dist);
|
||||
|
||||
// calc heading and distance from p0 to p1
|
||||
SGGeodesy::inverse( p0, p1, wid_hdg, az2, dist );
|
||||
|
||||
// s0 is width away from t1 in wid_hdg direction
|
||||
geo_direct_wgs_84( t1.y(), t1.x(), wid_hdg, width, &pt_y, &pt_x, &az2 );
|
||||
s0 = Point3D( pt_x, pt_y, 0.0f );
|
||||
s0 = SGGeodesy::direct( t1, wid_hdg, width );
|
||||
|
||||
// s1 is width away from t0 in wid_hdg direction
|
||||
geo_direct_wgs_84( t0.y(), t0.x(), wid_hdg, width, &pt_y, &pt_x, &az2 );
|
||||
s1 = Point3D( pt_x, pt_y, 0.0f );
|
||||
s1 = SGGeodesy::direct( t0, wid_hdg, width );
|
||||
|
||||
// s2 is nudge away from t0 in -wid_hdg direction
|
||||
geo_direct_wgs_84( t0.y(), t0.x(), wid_hdg, -0.01, &pt_y, &pt_x, &az2 );
|
||||
s2 = Point3D( pt_x, pt_y, 0.0f );
|
||||
s2 = SGGeodesy::direct( t0, wid_hdg, -0.01 );
|
||||
|
||||
// s3 is nudge away from t1 in -wid_hdg direction
|
||||
geo_direct_wgs_84( t1.y(), t1.x(), wid_hdg, -0.01, &pt_y, &pt_x, &az2 );
|
||||
s3 = Point3D( pt_x, pt_y, 0.0f );
|
||||
s3 = SGGeodesy::direct( t1, wid_hdg, -0.01 );
|
||||
|
||||
// Generate a poly
|
||||
poly.erase();
|
||||
poly.add_node( 0, s0 );
|
||||
poly.add_node( 0, s1 );
|
||||
poly.add_node( 0, s2 );
|
||||
poly.add_node( 0, s3 );
|
||||
poly = snap( poly, gSnap );
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( poly );
|
||||
sp.set_material( surface );
|
||||
sp.set_flag( "shoulder" );
|
||||
poly.AddNode( 0, s0 );
|
||||
poly.AddNode( 0, s1 );
|
||||
poly.AddNode( 0, s2 );
|
||||
poly.AddNode( 0, s3 );
|
||||
poly = tgPolygon::Snap( poly, gSnap );
|
||||
|
||||
poly.SetMaterial( surface );
|
||||
if (side == 0) {
|
||||
tp = TGTexParams( poly.get_pt(0,2).toSGGeod(), width, dist, heading );
|
||||
tp.set_minu(0);
|
||||
tp.set_maxu(1);
|
||||
poly.SetTexParams( poly.GetNode(0,2), width, dist, heading );
|
||||
poly.SetTexLimits( 0,0,1,1 );
|
||||
} else {
|
||||
tp = TGTexParams( poly.get_pt(0,1).toSGGeod(), width, dist, heading );
|
||||
tp.set_minu(1);
|
||||
tp.set_maxu(0);
|
||||
poly.SetTexParams( poly.GetNode(0,1), width, dist, heading );
|
||||
poly.SetTexLimits( 1,0,0,1 );
|
||||
}
|
||||
poly.SetTexMethod( TG_TEX_BY_TPS_CLIPU, 0.0, 0.0, 1.0, 0.0 );
|
||||
|
||||
tp.set_minv(0);
|
||||
tp.set_maxv(1);
|
||||
return poly;
|
||||
}
|
||||
|
||||
// generate a section of texture
|
||||
void Runway::gen_runway_section( const TGPolygon& runway,
|
||||
// generate a section of texture with shoulders
|
||||
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& material,
|
||||
superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
superpoly_list *shoulder_polys,
|
||||
texparams_list *shoulder_tps,
|
||||
poly_list& slivers,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgpolygon_list& shoulder_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles )
|
||||
{
|
||||
int j, k;
|
||||
double width = rwy.width;
|
||||
double length = rwy.length;
|
||||
double lshoulder_width = 0.0f;
|
||||
double rshoulder_width = 0.0f;
|
||||
std::string shoulder_surface = "";
|
||||
|
||||
void* ds_id = NULL; // If we are going to build shapefiles
|
||||
void* l_id = NULL; // datasource and layer IDs
|
||||
static int poly_id = 0; // for naming
|
||||
static int runway_idx = 0;
|
||||
static int section_idx = 0;
|
||||
static int clipped_idx = 0;
|
||||
char layer[64];
|
||||
|
||||
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);
|
||||
SGVec2d a0 = SGVec2d( runway.GetNode(0, 1).getLongitudeDeg(), runway.GetNode(0, 1).getLatitudeDeg() );
|
||||
SGVec2d a1 = SGVec2d( runway.GetNode(0, 2).getLongitudeDeg(), runway.GetNode(0, 2).getLatitudeDeg() );
|
||||
SGVec2d a2 = SGVec2d( runway.GetNode(0, 0).getLongitudeDeg(), runway.GetNode(0, 0).getLatitudeDeg() );
|
||||
SGVec2d a3 = SGVec2d( runway.GetNode(0, 3).getLongitudeDeg(), runway.GetNode(0, 3).getLatitudeDeg() );
|
||||
|
||||
if ( startl_pct > 0.0 ) {
|
||||
startl_pct -= nudge * SG_EPSILON;
|
||||
|
@ -185,12 +170,6 @@ void Runway::gen_runway_section( const TGPolygon& runway,
|
|||
endl_pct = 1.0;
|
||||
}
|
||||
|
||||
if ( make_shapefiles ) {
|
||||
char ds_name[128];
|
||||
sprintf(ds_name, "./rwy_debug");
|
||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||
}
|
||||
|
||||
// calculate if we are going to be creating shoulder polys
|
||||
if ( (rwy.shoulder > 0) && (rwy.surface < 3) ){
|
||||
if (rwy.shoulder == 1){
|
||||
|
@ -237,146 +216,98 @@ void Runway::gen_runway_section( const TGPolygon& runway,
|
|||
}
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "start len % = " << startl_pct
|
||||
<< " end len % = " << endl_pct);
|
||||
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);
|
||||
SGVec2d t0 = SGVec2d( a0.x() + dlx * startl_pct,
|
||||
a0.y() + dly * startl_pct );
|
||||
SGVec2d t1 = SGVec2d( a0.x() + dlx * endl_pct,
|
||||
a0.y() + dly * endl_pct );
|
||||
|
||||
dlx = a3.x() - a2.x();
|
||||
dly = a3.y() - a2.y();
|
||||
|
||||
Point3D t2 = Point3D( a2.x() + dlx * startl_pct,
|
||||
a2.y() + dly * startl_pct, 0);
|
||||
SGVec2d t2 = SGVec2d( a2.x() + dlx * startl_pct,
|
||||
a2.y() + dly * startl_pct );
|
||||
|
||||
Point3D t3 = Point3D( a2.x() + dlx * endl_pct,
|
||||
a2.y() + dly * endl_pct, 0);
|
||||
SGVec2d t3 = SGVec2d( a2.x() + dlx * endl_pct,
|
||||
a2.y() + dly * endl_pct );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "start wid % = " << startw_pct
|
||||
<< " end wid % = " << endw_pct);
|
||||
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);
|
||||
SGVec2d p0 = SGVec2d( t2.x() + dwx * startw_pct,
|
||||
t2.y() + dwy * startw_pct );
|
||||
|
||||
Point3D p1 = Point3D( t2.x() + dwx * endw_pct,
|
||||
t2.y() + dwy * endw_pct, 0);
|
||||
|
||||
// check for left shoulder
|
||||
if ( lshoulder_width > 0.0f ) {
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
|
||||
gen_shoulder_section( p0, p1, t0, t1, 0, heading, lshoulder_width, shoulder_surface, sp, tp );
|
||||
shoulder_polys->push_back( sp );
|
||||
shoulder_tps->push_back( tp );
|
||||
|
||||
/* If debugging this runway, write the shoulder poly */
|
||||
if (ds_id) {
|
||||
poly_id++;
|
||||
|
||||
char layer_name[128];
|
||||
sprintf( layer_name, "lshoulder_%d", poly_id );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
|
||||
char feature_name[128];
|
||||
sprintf( feature_name, "lshoulder_%d", poly_id);
|
||||
tgShapefileCreateFeature( ds_id, l_id, sp.get_poly(), feature_name );
|
||||
}
|
||||
}
|
||||
SGVec2d p1 = SGVec2d( t2.x() + dwx * endw_pct,
|
||||
t2.y() + dwy * endw_pct );
|
||||
|
||||
dwx = t1.x() - t3.x();
|
||||
dwy = t1.y() - t3.y();
|
||||
|
||||
Point3D p2 = Point3D( t3.x() + dwx * startw_pct,
|
||||
t3.y() + dwy * startw_pct, 0);
|
||||
SGVec2d p2 = SGVec2d( t3.x() + dwx * startw_pct,
|
||||
t3.y() + dwy * startw_pct );
|
||||
|
||||
Point3D p3 = Point3D( t3.x() + dwx * endw_pct,
|
||||
t3.y() + dwy * endw_pct, 0);
|
||||
SGVec2d p3 = SGVec2d( t3.x() + dwx * endw_pct,
|
||||
t3.y() + dwy * endw_pct );
|
||||
|
||||
|
||||
// convert vectors back to GEOD
|
||||
SGGeod pg0 = SGGeod::fromDeg( p0.x(), p0.y() );
|
||||
SGGeod pg1 = SGGeod::fromDeg( p1.x(), p1.y() );
|
||||
SGGeod pg2 = SGGeod::fromDeg( p2.x(), p2.y() );
|
||||
SGGeod pg3 = SGGeod::fromDeg( p3.x(), p3.y() );
|
||||
SGGeod tg0 = SGGeod::fromDeg( t0.x(), t0.y() );
|
||||
SGGeod tg1 = SGGeod::fromDeg( t1.x(), t1.y() );
|
||||
SGGeod tg2 = SGGeod::fromDeg( t2.x(), t2.y() );
|
||||
SGGeod tg3 = SGGeod::fromDeg( t3.x(), t3.y() );
|
||||
|
||||
// check for left shoulder
|
||||
if ( lshoulder_width > 0.0f ) {
|
||||
tgPolygon sp;
|
||||
|
||||
sp = gen_shoulder_section( pg0, pg1, tg0, tg1, 0, heading, lshoulder_width, shoulder_surface );
|
||||
shoulder_polys.push_back( sp );
|
||||
}
|
||||
|
||||
// check for right shoulder
|
||||
if ( rshoulder_width > 0.0f ) {
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
tgPolygon sp;
|
||||
|
||||
gen_shoulder_section( p1, p0, t2, t3, 1, heading, rshoulder_width, shoulder_surface, sp, tp );
|
||||
shoulder_polys->push_back( sp );
|
||||
shoulder_tps->push_back( tp );
|
||||
|
||||
/* If debugging this runway, write the shoulder poly */
|
||||
if (ds_id) {
|
||||
poly_id++;
|
||||
|
||||
char layer_name[128];
|
||||
sprintf( layer_name, "rshoulder_%d", poly_id );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
|
||||
char feature_name[128];
|
||||
sprintf( feature_name, "rshoulder_%d", poly_id);
|
||||
tgShapefileCreateFeature( ds_id, l_id, sp.get_poly(), feature_name );
|
||||
}
|
||||
sp = gen_shoulder_section( pg1, pg0, tg2, tg3, 1, heading, rshoulder_width, shoulder_surface );
|
||||
shoulder_polys.push_back( sp );
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
/* If debugging this runway, write the shoulder poly */
|
||||
if (ds_id) {
|
||||
char layer_name[128];
|
||||
sprintf( layer_name, "poly_%d", poly_id );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
|
||||
char feature_name[128];
|
||||
sprintf( feature_name, "section_%d", poly_id);
|
||||
tgShapefileCreateFeature( ds_id, l_id, section, feature_name );
|
||||
}
|
||||
tgPolygon section;
|
||||
|
||||
section.AddNode( 0, pg2 );
|
||||
section.AddNode( 0, pg0 );
|
||||
section.AddNode( 0, pg1 );
|
||||
section.AddNode( 0, pg3 );
|
||||
section = tgPolygon::Snap( section, gSnap );
|
||||
|
||||
// print runway points
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << material_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);
|
||||
}
|
||||
}
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, section );
|
||||
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
TGPolygon clipped = tgPolygonDiffClipperWithAccumulator( section );
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
tgPolygon clipped = tgPolygon::DiffWithAccumulator( section );
|
||||
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
tgPolygon split = tgPolygon::SplitLongEdges( 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_prefix + material );
|
||||
rwy_polys->push_back( sp );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "section = " << clipped.contours());
|
||||
|
||||
tgPolygonAddToClipperAccumulator( section, false );
|
||||
tgPolygon::AddToAccumulator( section );
|
||||
|
||||
// Store away what we need to know for texture coordinate
|
||||
// calculation. (CLO 10/20/02: why can't we calculate texture
|
||||
|
@ -389,36 +320,157 @@ void Runway::gen_runway_section( const TGPolygon& runway,
|
|||
double sect_len = len * ( endl_pct - startl_pct );
|
||||
double sect_wid = width * ( endw_pct - startw_pct );
|
||||
|
||||
TGTexParams tp;
|
||||
tp = TGTexParams( p0.toSGGeod(),
|
||||
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 );
|
||||
split.SetMaterial( material_prefix + material );
|
||||
split.SetTexParams( pg0, sect_wid, sect_len, heading );
|
||||
split.SetTexLimits( minu, minv, maxu, maxv );
|
||||
split.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
|
||||
// print runway points
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped runway pts " << material_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);
|
||||
// Create the final output and push on to the runway super_polygon
|
||||
// list
|
||||
rwy_polys.push_back( split );
|
||||
}
|
||||
|
||||
// generate a section of texture without shoulders
|
||||
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& material,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles )
|
||||
{
|
||||
double width = rwy.width;
|
||||
double length = rwy.length;
|
||||
|
||||
SGVec2d a0 = SGVec2d( runway.GetNode(0, 1).getLongitudeDeg(), runway.GetNode(0, 1).getLatitudeDeg() );
|
||||
SGVec2d a1 = SGVec2d( runway.GetNode(0, 1).getLongitudeDeg(), runway.GetNode(0, 2).getLatitudeDeg() );
|
||||
SGVec2d a2 = SGVec2d( runway.GetNode(0, 1).getLongitudeDeg(), runway.GetNode(0, 0).getLatitudeDeg() );
|
||||
SGVec2d a3 = SGVec2d( runway.GetNode(0, 1).getLongitudeDeg(), runway.GetNode(0, 3).getLatitudeDeg() );
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (ds_id) {
|
||||
tgShapefileCloseDatasource( ds_id );
|
||||
}
|
||||
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();
|
||||
|
||||
SGVec2d t0 = SGVec2d( a0.x() + dlx * startl_pct,
|
||||
a0.y() + dly * startl_pct );
|
||||
SGVec2d t1 = SGVec2d( a0.x() + dlx * endl_pct,
|
||||
a0.y() + dly * endl_pct );
|
||||
|
||||
dlx = a3.x() - a2.x();
|
||||
dly = a3.y() - a2.y();
|
||||
|
||||
SGVec2d t2 = SGVec2d( a2.x() + dlx * startl_pct,
|
||||
a2.y() + dly * startl_pct );
|
||||
|
||||
SGVec2d t3 = SGVec2d( a2.x() + dlx * endl_pct,
|
||||
a2.y() + dly * endl_pct );
|
||||
|
||||
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();
|
||||
|
||||
SGVec2d p0 = SGVec2d( t2.x() + dwx * startw_pct,
|
||||
t2.y() + dwy * startw_pct );
|
||||
|
||||
SGVec2d p1 = SGVec2d( t2.x() + dwx * endw_pct,
|
||||
t2.y() + dwy * endw_pct );
|
||||
|
||||
dwx = t1.x() - t3.x();
|
||||
dwy = t1.y() - t3.y();
|
||||
|
||||
SGVec2d p2 = SGVec2d( t3.x() + dwx * startw_pct,
|
||||
t3.y() + dwy * startw_pct );
|
||||
|
||||
SGVec2d p3 = SGVec2d( t3.x() + dwx * endw_pct,
|
||||
t3.y() + dwy * endw_pct );
|
||||
|
||||
|
||||
// convert vectors back to GEOD
|
||||
SGGeod pg0 = SGGeod::fromDeg( p0.x(), p0.y() );
|
||||
SGGeod pg1 = SGGeod::fromDeg( p1.x(), p1.y() );
|
||||
SGGeod pg2 = SGGeod::fromDeg( p2.x(), p2.y() );
|
||||
SGGeod pg3 = SGGeod::fromDeg( p3.x(), p3.y() );
|
||||
|
||||
tgPolygon section;
|
||||
|
||||
section.AddNode( 0, pg2 );
|
||||
section.AddNode( 0, pg0 );
|
||||
section.AddNode( 0, pg1 );
|
||||
section.AddNode( 0, pg3 );
|
||||
section = tgPolygon::Snap( section, gSnap );
|
||||
|
||||
// print runway points
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "pre clipped runway pts " << material_prefix << material);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, section );
|
||||
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
tgPolygon clipped = tgPolygon::DiffWithAccumulator( section );
|
||||
|
||||
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::AddToAccumulator( section );
|
||||
|
||||
// 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 );
|
||||
|
||||
split.SetMaterial( material_prefix + material );
|
||||
split.SetTexParams( pg0, sect_wid, sect_len, heading );
|
||||
split.SetTexLimits( minu, minv, maxu, maxv );
|
||||
split.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
|
||||
// Create the final output and push on to the runway super_polygon
|
||||
// list
|
||||
rwy_polys.push_back( split );
|
||||
}
|
||||
|
||||
void Runway::gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
||||
void Runway::gen_rw_designation( tgPolygon poly, double heading, string rwname,
|
||||
double &start_pct, double &end_pct,
|
||||
superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers,
|
||||
tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles )
|
||||
{
|
||||
if (rwname != "XX") { /* Do not create a designation block if the runway name is set to none */
|
||||
|
@ -443,8 +495,8 @@ void Runway::gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
letter,
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -473,8 +525,8 @@ void Runway::gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
tex1,
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
gen_runway_section( poly,
|
||||
|
@ -483,8 +535,8 @@ void Runway::gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
tex2,
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
|
||||
|
@ -497,8 +549,8 @@ void Runway::gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
tex1,
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -509,9 +561,8 @@ void Runway::gen_rw_designation( TGPolygon poly, double heading, string rwname,
|
|||
// rwy_polys, texparams, and accum. For specific details and
|
||||
// dimensions of precision runway markings, please refer to FAA
|
||||
// document AC 150/5340-1H
|
||||
void Runway::gen_rwy( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers,
|
||||
void Runway::gen_rwy( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles )
|
||||
{
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Building runway = " << rwy.rwnum[0] << " / " << rwy.rwnum[1]);
|
||||
|
@ -519,35 +570,35 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
//
|
||||
// Generate the basic runway outlines
|
||||
//
|
||||
TGPolygon runway = gen_runway_w_mid( 0, 0 );
|
||||
tgContour runway = gen_runway_w_mid( 0, 0 );
|
||||
tgPolygon runway_half;
|
||||
|
||||
TGPolygon runway_half;
|
||||
for ( int rwhalf=0; rwhalf<2; ++rwhalf ){
|
||||
|
||||
if (rwhalf == 0) {
|
||||
|
||||
//Create the first half of the runway (first entry in apt.dat)
|
||||
runway_half.erase();
|
||||
runway_half.add_node( 0, runway.get_pt(0, 3) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 4) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 5) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 2) );
|
||||
runway_half.Erase();
|
||||
runway_half.AddNode( 0, runway.GetNode(3) );
|
||||
runway_half.AddNode( 0, runway.GetNode(4) );
|
||||
runway_half.AddNode( 0, runway.GetNode(5) );
|
||||
runway_half.AddNode( 0, runway.GetNode(2) );
|
||||
}
|
||||
|
||||
else if (rwhalf == 1) {
|
||||
|
||||
//Create the second runway half from apt.dat
|
||||
runway_half.erase();
|
||||
runway_half.add_node( 0, runway.get_pt(0, 0) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 1) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 2) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 5) );
|
||||
runway_half.Erase();
|
||||
runway_half.AddNode( 0, runway.GetNode(0) );
|
||||
runway_half.AddNode( 0, runway.GetNode(1) );
|
||||
runway_half.AddNode( 0, runway.GetNode(2) );
|
||||
runway_half.AddNode( 0, runway.GetNode(5) );
|
||||
}
|
||||
|
||||
Point3D p;
|
||||
SGGeod p;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "raw runway half pts (run " << rwhalf << ")");
|
||||
for ( int i = 0; i < runway_half.contour_size( 0 ); ++i ) {
|
||||
p = runway_half.get_pt( 0, i );
|
||||
for ( unsigned int i = 0; i < runway_half.ContourSize( 0 ); ++i ) {
|
||||
p = runway_half.GetNode( 0, i );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " point = " << p);
|
||||
}
|
||||
|
||||
|
@ -576,7 +627,7 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
// Displaced threshold if it exists
|
||||
//
|
||||
if (rwhalf == 0) {
|
||||
heading = rwy.heading + 180.0;
|
||||
heading = SGMiscd::normalizePeriodic( 0,360, rwy.heading + 180.0 );
|
||||
rwname = rwy.rwnum[0];
|
||||
}
|
||||
else if (rwhalf == 1) {
|
||||
|
@ -614,8 +665,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, tex_pct, 1.0,
|
||||
heading,
|
||||
"dspl_thresh",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
|
||||
|
@ -629,8 +680,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
"dspl_thresh",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -645,8 +696,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
"dspl_arrows",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -661,8 +712,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
"no_threshold",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
} else {
|
||||
|
@ -675,8 +726,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
"threshold",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -684,7 +735,7 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
// Runway designation block
|
||||
gen_rw_designation( runway_half, heading,
|
||||
rwname, start1_pct, end1_pct,
|
||||
rwy_polys, texparams, slivers,
|
||||
rwy_polys, slivers,
|
||||
make_shapefiles );
|
||||
|
||||
// Generate remaining markings depending on type of runway
|
||||
|
@ -723,8 +774,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
rw_marking_list[i].tex,
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -752,8 +803,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
"rest",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -782,8 +833,8 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0, //last number is lengthwise
|
||||
heading,
|
||||
"stopway",
|
||||
rwy_polys, texparams,
|
||||
&shoulder_polys, &shoulder_tps,
|
||||
rwy_polys,
|
||||
shoulder_polys,
|
||||
slivers,
|
||||
make_shapefiles );
|
||||
}
|
||||
|
@ -791,43 +842,61 @@ void Runway::gen_rwy( superpoly_list *rwy_polys,
|
|||
}
|
||||
}
|
||||
|
||||
void Runway::BuildShoulder( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing )
|
||||
void Runway::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing )
|
||||
{
|
||||
TGPolygon base, safe_base;
|
||||
TGPolygon shoulder;
|
||||
tgPolygon base, safe_base;
|
||||
tgPolygon shoulder;
|
||||
|
||||
for (unsigned int i=0; i<shoulder_polys.size(); i++) {
|
||||
shoulder = shoulder_polys[i].get_poly();
|
||||
shoulder = shoulder_polys[i];
|
||||
|
||||
// Clip the new polygon against what ever has already been created.
|
||||
TGPolygon clipped = tgPolygonDiffClipperWithAccumulator( shoulder );
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
tgPolygon clipped = tgPolygon::DiffWithAccumulator( shoulder );
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
// Split long edges to create an object that can better flow with
|
||||
// the surface terrain
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
shoulder_polys[i].set_poly( split );
|
||||
|
||||
rwy_polys->push_back( shoulder_polys[i] );
|
||||
texparams->push_back( shoulder_tps[i] );
|
||||
tgPolygon split = tgPolygon::SplitLongEdges( clipped, 400.0 );
|
||||
shoulder_polys[i] = split;
|
||||
|
||||
tgPolygonAddToClipperAccumulator( shoulder, false );
|
||||
rwy_polys.push_back( shoulder_polys[i] );
|
||||
|
||||
if (apt_base)
|
||||
{
|
||||
// also clear a safe area around the runway
|
||||
base = tgPolygonExpand( shoulder, 20.0);
|
||||
safe_base = tgPolygonExpand( shoulder, 50.0);
|
||||
tgPolygon::AddToAccumulator( shoulder );
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing );
|
||||
// also clear a safe area around the runway
|
||||
base = tgPolygon::Expand( shoulder, 20.0);
|
||||
safe_base = tgPolygon::Expand( shoulder, 50.0);
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
}
|
||||
// add this to the airport clearing
|
||||
apt_clearing = tgPolygon::Union( safe_base, apt_clearing );
|
||||
|
||||
// and add the clearing to the base
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
}
|
||||
}
|
||||
|
||||
void Runway::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers )
|
||||
{
|
||||
tgPolygon shoulder;
|
||||
|
||||
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 = tgPolygon::DiffWithAccumulator( 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 );
|
||||
shoulder_polys[i] = split;
|
||||
|
||||
rwy_polys.push_back( shoulder_polys[i] );
|
||||
|
||||
tgPolygon::AddToAccumulator( shoulder );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,34 +32,32 @@ using std::string;
|
|||
|
||||
// generate a simple runway. The routine modifies rwy_polys,
|
||||
// texparams, and accum
|
||||
void Runway::gen_simple_rwy( superpoly_list *rwy_polys,
|
||||
texparams_list *texparams,
|
||||
poly_list& slivers )
|
||||
void Runway::gen_simple_rwy( tgpolygon_list& rwy_polys,
|
||||
tgcontour_list& slivers )
|
||||
{
|
||||
TGPolygon runway = gen_runway_w_mid( 0.0, 0.0 );
|
||||
|
||||
TGPolygon runway_half;
|
||||
tgContour runway = gen_runway_w_mid( 0.0, 0.0 );
|
||||
tgPolygon runway_half;
|
||||
|
||||
for ( int rwhalf=0; rwhalf<2; ++rwhalf ) {
|
||||
|
||||
if (rwhalf == 0) {
|
||||
|
||||
//Create the first half of the runway (first entry in apt.dat)
|
||||
runway_half.erase();
|
||||
runway_half.add_node( 0, runway.get_pt(0, 3) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 4) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 5) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 2) );
|
||||
runway_half.Erase();
|
||||
runway_half.AddNode( 0, runway.GetNode(3) );
|
||||
runway_half.AddNode( 0, runway.GetNode(4) );
|
||||
runway_half.AddNode( 0, runway.GetNode(5) );
|
||||
runway_half.AddNode( 0, runway.GetNode(2) );
|
||||
}
|
||||
|
||||
else if (rwhalf == 1) {
|
||||
|
||||
//Create the second runway half from apt.dat
|
||||
runway_half.erase();
|
||||
runway_half.add_node( 0, runway.get_pt(0, 0) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 1) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 2) );
|
||||
runway_half.add_node( 0, runway.get_pt(0, 5) );
|
||||
runway_half.Erase();
|
||||
runway_half.AddNode( 0, runway.GetNode(0) );
|
||||
runway_half.AddNode( 0, runway.GetNode(1) );
|
||||
runway_half.AddNode( 0, runway.GetNode(2) );
|
||||
runway_half.AddNode( 0, runway.GetNode(5) );
|
||||
}
|
||||
|
||||
double length = rwy.length / 2.0;
|
||||
|
@ -68,7 +66,7 @@ void Runway::gen_simple_rwy( superpoly_list *rwy_polys,
|
|||
double heading = 0.0;
|
||||
|
||||
if (rwhalf == 0) {
|
||||
heading = rwy.heading + 180.0;
|
||||
heading = SGMiscd::normalizePeriodic(0, 360, rwy.heading + 180.0);
|
||||
}
|
||||
else if (rwhalf == 1) {
|
||||
heading = rwy.heading;
|
||||
|
@ -88,8 +86,7 @@ void Runway::gen_simple_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 1.0, 0.0, 1.0,
|
||||
heading,
|
||||
"",
|
||||
rwy_polys, texparams,
|
||||
NULL, NULL,
|
||||
rwy_polys,
|
||||
slivers,
|
||||
false );
|
||||
}
|
||||
|
@ -101,8 +98,7 @@ void Runway::gen_simple_rwy( superpoly_list *rwy_polys,
|
|||
0.0, 0.28, 0.0, 1.0,
|
||||
heading,
|
||||
"",
|
||||
rwy_polys, texparams,
|
||||
NULL, NULL,
|
||||
rwy_polys,
|
||||
slivers,
|
||||
false );
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ void ProcessList::Launch( string command, string work_dir, string file, AirportI
|
|||
|
||||
sprintf( arg, "--redirect-port=%d", GENAPT_PORT );
|
||||
args.push_back(arg);
|
||||
|
||||
|
||||
// Launch the child process
|
||||
ProcessHandle ph = Process::launch(command, args, 0, &outPipe, &outPipe);
|
||||
|
||||
|
@ -587,7 +587,7 @@ long Scheduler::FindAirport( string icao )
|
|||
|
||||
void Scheduler::RetryAirport( AirportInfo* pai )
|
||||
{
|
||||
retryList.push_back( *pai );
|
||||
// retryList.push_back( *pai );
|
||||
}
|
||||
|
||||
bool Scheduler::AddAirports( long start_pos, tg::Rectangle* boundingBox )
|
||||
|
|
|
@ -58,11 +58,13 @@ Taxiway::Taxiway(char* definition)
|
|||
lon = pt_x;
|
||||
}
|
||||
|
||||
int Taxiway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, superpoly_list* rwy_lights, poly_list& slivers, TGPolygon* apt_base, TGPolygon* apt_clearing, bool make_shapefiles )
|
||||
int Taxiway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgPolygon& apt_base, tgPolygon& apt_clearing, bool make_shapefiles )
|
||||
{
|
||||
TGPolygon taxi;
|
||||
TGPolygon base, safe_base;
|
||||
tgContour taxi;
|
||||
tgContour base, safe_base;
|
||||
std::string material;
|
||||
|
||||
#if 0
|
||||
void* ds_id = NULL; // If we are going to build shapefiles
|
||||
void* l_id = NULL; // datasource and layer IDs
|
||||
|
||||
|
@ -71,6 +73,7 @@ int Taxiway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, sup
|
|||
sprintf(ds_name, "./taxi_debug");
|
||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( surface == 1 /* Asphalt */ )
|
||||
{
|
||||
|
@ -121,9 +124,7 @@ int Taxiway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, sup
|
|||
// generate a poly for this segment
|
||||
taxi = gen_wgs84_rect( lat, lon, heading, length, width );
|
||||
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
|
||||
#if 0
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
@ -133,21 +134,22 @@ int Taxiway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, sup
|
|||
sprintf( feature_name, "original" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, taxi, feature_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
TGPolygon clipped = tgPolygonDiffClipperWithAccumulator( taxi );
|
||||
tgPolygonFindSlivers( clipped, slivers );
|
||||
tgPolygon clipped = tgContour::DiffWithAccumulator( taxi );
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tw1 clipped = " << clipped.Contours());
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( clipped );
|
||||
sp.set_material( material );
|
||||
sp.set_flag("taxi");
|
||||
clipped.SetMaterial( material );
|
||||
clipped.SetTexParams( taxi.GetNode(0), width, 250*SG_FEET_TO_METER, heading );
|
||||
clipped.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
|
||||
rwy_polys.push_back( clipped );
|
||||
|
||||
rwy_polys->push_back( sp );
|
||||
|
||||
tgPolygonAddToClipperAccumulator( taxi, false );
|
||||
tgContour::AddToAccumulator( taxi );
|
||||
|
||||
#if 0
|
||||
/* If debugging this poly, write the poly, and clipped poly and the accum buffer into their own layers */
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
|
@ -158,49 +160,162 @@ int Taxiway::BuildBtg( superpoly_list* rwy_polys, texparams_list* texparams, sup
|
|||
sprintf( feature_name, "clipped" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, clipped, feature_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tp construct");
|
||||
base = tgContour::Expand( taxi, 20.0);
|
||||
|
||||
tp = TGTexParams( taxi.get_pt(0,0).toSGGeod(), width, 250*SG_FEET_TO_METER, heading );
|
||||
texparams->push_back( tp );
|
||||
#if 0
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
if ( apt_base )
|
||||
{
|
||||
base = tgPolygonExpand( taxi, 20.0);
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
sprintf( layer_name, "exp_base" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "exp_base" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, base, feature_name );
|
||||
}
|
||||
|
||||
safe_base = tgPolygonExpand( taxi, 50.0);
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "expanded safe poly: " << safe_base);
|
||||
|
||||
sprintf( layer_name, "exp_safe_base" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "exp_safe_base" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, safe_base, feature_name );
|
||||
}
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
sprintf( layer_name, "exp_base" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "exp_base" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, base, feature_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
safe_base = tgContour::Expand( taxi, 50.0);
|
||||
|
||||
#if 0
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "expanded safe poly: " << safe_base);
|
||||
|
||||
sprintf( layer_name, "exp_safe_base" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "exp_safe_base" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, safe_base, feature_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
// add this to the airport clearing
|
||||
apt_clearing = tgPolygon::Union( safe_base, apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
apt_base = tgPolygon::Union( base, apt_base );
|
||||
|
||||
#if 0
|
||||
if ( make_shapefiles )
|
||||
{
|
||||
tgShapefileCloseDatasource( ds_id );
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Taxiway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, bool make_shapefiles )
|
||||
{
|
||||
tgContour taxi;
|
||||
std::string material;
|
||||
|
||||
#if 0
|
||||
void* ds_id = NULL; // If we are going to build shapefiles
|
||||
void* l_id = NULL; // datasource and layer IDs
|
||||
|
||||
if ( make_shapefiles ) {
|
||||
char ds_name[128];
|
||||
sprintf(ds_name, "./taxi_debug");
|
||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( surface == 1 /* Asphalt */ )
|
||||
{
|
||||
if ( (width <= 50) && (lighting[1] == '6') ) {
|
||||
material = "pa_taxiway";
|
||||
} else {
|
||||
material = "pa_tiedown";
|
||||
}
|
||||
}
|
||||
else if ( surface == 2 /* Concrete */ )
|
||||
{
|
||||
if ( (width <= 50) && (lighting[1] == '6') ) {
|
||||
material = "pc_taxiway";
|
||||
} else {
|
||||
material = "pc_tiedown";
|
||||
}
|
||||
}
|
||||
else if ( surface == 3 /* Turf/Grass */ )
|
||||
{
|
||||
material = "grass_rwy";
|
||||
}
|
||||
else if ( surface == 4 /* Dirt */ || surface == 5 /* Gravel */ )
|
||||
{
|
||||
material = "dirt_rwy";
|
||||
}
|
||||
else if ( surface == 12 /* Dry Lakebed */ )
|
||||
{
|
||||
material = "lakebed_taxiway";
|
||||
}
|
||||
else if ( surface == 13 /* Water runway (buoy's?) */ )
|
||||
{
|
||||
// water
|
||||
}
|
||||
else if ( surface == 14 /* Snow / Ice */ )
|
||||
{
|
||||
// Ice
|
||||
}
|
||||
else if ( surface == 15 /* Transparent */ )
|
||||
{
|
||||
//Transparent texture
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "surface_code = " << surface);
|
||||
throw sg_exception("unknown runway type!");
|
||||
}
|
||||
|
||||
// generate a poly for this segment
|
||||
taxi = gen_wgs84_rect( lat, lon, heading, length, width );
|
||||
|
||||
#if 0
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
sprintf( layer_name, "original" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "original" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, taxi, feature_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
tgPolygon clipped = tgContour::DiffWithAccumulator( taxi );
|
||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tw2 clipped = " << clipped.Contours());
|
||||
|
||||
clipped.SetMaterial( material );
|
||||
clipped.SetTexParams( taxi.GetNode(0), width, 250*SG_FEET_TO_METER, heading );
|
||||
clipped.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, 0.0, 0.0, 1.0, 1.0 );
|
||||
rwy_polys.push_back( clipped );
|
||||
|
||||
tgContour::AddToAccumulator( taxi );
|
||||
|
||||
#if 0
|
||||
/* If debugging this poly, write the poly, and clipped poly and the accum buffer into their own layers */
|
||||
if ( make_shapefiles ) {
|
||||
char layer_name[128];
|
||||
char feature_name[128];
|
||||
|
||||
sprintf( layer_name, "clipped" );
|
||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||
sprintf( feature_name, "clipped" );
|
||||
tgShapefileCreateFeature( ds_id, l_id, clipped, feature_name );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if ( make_shapefiles )
|
||||
{
|
||||
tgShapefileCloseDatasource( ds_id );
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,12 +19,16 @@ public:
|
|||
|
||||
Taxiway(char* def);
|
||||
|
||||
int BuildBtg( superpoly_list* taxi_polys,
|
||||
texparams_list* texparams,
|
||||
superpoly_list* taxi_lights,
|
||||
poly_list& slivers,
|
||||
TGPolygon* apt_base,
|
||||
TGPolygon* apt_clearing,
|
||||
int BuildBtg( tgpolygon_list& taxi_polys,
|
||||
tglightcontour_list& taxi_lights,
|
||||
tgcontour_list& slivers,
|
||||
bool make_shapefiles );
|
||||
|
||||
int BuildBtg( tgpolygon_list& taxi_polys,
|
||||
tglightcontour_list& taxi_lights,
|
||||
tgcontour_list& slivers,
|
||||
tgPolygon& apt_base,
|
||||
tgPolygon& apt_clearing,
|
||||
bool make_shapefiles );
|
||||
|
||||
private:
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#include <Polygon/polygon.hxx>
|
||||
|
||||
namespace tg {
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
include_directories(${GDAL_INCLUDE_DIR})
|
||||
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
add_library(Polygon STATIC
|
||||
chop-bin.cxx
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,8 +32,10 @@
|
|||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <CGAL/Plane_3.h>
|
||||
#include <Geometry/point3d.hxx>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -44,8 +46,6 @@ class TGPolygon;
|
|||
#include "clipper.hpp"
|
||||
#define FG_MAX_VERTICES 1500000
|
||||
|
||||
typedef TGPolygon ClipPolyType;
|
||||
|
||||
typedef std::vector < point_list > polytype;
|
||||
typedef polytype::iterator polytype_iterator;
|
||||
typedef polytype::const_iterator const_polytype_iterator;
|
||||
|
@ -291,6 +291,426 @@ void tgPolygonDumpClipper(const TGPolygon &poly);
|
|||
// Output
|
||||
std::ostream &operator<<(std::ostream &output, const TGPolygon &poly);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// WORK IN PROGRESS BEGIN ******************************************************
|
||||
// Looking ato TGPolygon and TGSuperPoly, I think it would be best if we could
|
||||
// templatize TGPolygon. We really want 4 mirror shapes
|
||||
// 1 with SGGeode as nodes - to represent Geodetic coordinates
|
||||
// 1 with SGVec2d as nodes - to represent texture coordinates
|
||||
// 1 with SGVec3d as nodes - to represent normals
|
||||
// 1 with int as nodes - to represent indicies into the node list
|
||||
//
|
||||
// The problem being, is that there are many type dependent implimenations needed
|
||||
// For example:
|
||||
// boolean operations, and calc_point_inside() should only be done on SGGeod polys
|
||||
// most of the other formats are for data storage only.
|
||||
//
|
||||
// For the first attempt, I will just have TGPolygon with a list of contours.
|
||||
// the extra data are stored in paralell vectors.
|
||||
// This should also make TGSuperPoly obsolete
|
||||
#include <Geometry/trinodes.hxx>
|
||||
#include <Geometry/rectangle.hxx>
|
||||
|
||||
// forward declaration
|
||||
class tgPolygon;
|
||||
|
||||
|
||||
class tgContour
|
||||
{
|
||||
public:
|
||||
tgContour() {
|
||||
hole = false;
|
||||
}
|
||||
|
||||
void Erase() {
|
||||
node_list.clear();
|
||||
}
|
||||
|
||||
void SetHole( bool h ) {
|
||||
hole = h;
|
||||
}
|
||||
bool GetHole( void ) const {
|
||||
return hole;
|
||||
}
|
||||
|
||||
unsigned int GetSize( void ) const {
|
||||
return node_list.size();
|
||||
}
|
||||
|
||||
void AddNode( SGGeod n ) {
|
||||
node_list.push_back( n );
|
||||
}
|
||||
void SetNode( unsigned int i, SGGeod n ) {
|
||||
node_list[i] = n;
|
||||
}
|
||||
SGGeod GetNode( unsigned int i ) const {
|
||||
return node_list[i];
|
||||
}
|
||||
void RemoveNodeAt( unsigned int idx ) {
|
||||
if ( idx < node_list.size() ) {
|
||||
node_list.erase( node_list.begin() + idx );
|
||||
}
|
||||
}
|
||||
void RemoveNodeRange( unsigned int from, unsigned int to ) {
|
||||
if ( ( from < to ) && ( to < node_list.size() ) ) {
|
||||
node_list.erase( node_list.begin()+from,node_list.begin()+to );
|
||||
}
|
||||
}
|
||||
|
||||
tg::Rectangle GetBoundingBox( void ) const;
|
||||
|
||||
double GetMinimumAngle( void ) const;
|
||||
double GetArea( void ) const;
|
||||
|
||||
static tgContour Snap( const tgContour& subject, double snap );
|
||||
static tgContour RemoveDups( const tgContour& subject );
|
||||
static tgContour RemoveCycles( const tgContour& subject );
|
||||
static tgContour SplitLongEdges( const tgContour& subject, double dist );
|
||||
static tgContour RemoveSpikes( const tgContour& subject );
|
||||
|
||||
static tgPolygon DiffWithAccumulator( const tgContour& subject );
|
||||
static void AddToAccumulator( const tgContour& subject );
|
||||
|
||||
static tgContour AddColinearNodes( const tgContour& subject, TGTriNodes nodes );
|
||||
|
||||
// conversions
|
||||
static ClipperLib::Polygon ToClipper( const tgContour& subject );
|
||||
static tgContour FromClipper( const ClipperLib::Polygon& subject );
|
||||
|
||||
static tgContour Expand( const tgContour& subject, double offset );
|
||||
|
||||
// Friend for output
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgContour& );
|
||||
|
||||
private:
|
||||
std::vector<SGGeod> node_list;
|
||||
bool hole;
|
||||
};
|
||||
|
||||
typedef std::vector <tgContour> tgcontour_list;
|
||||
typedef tgcontour_list::iterator tgcontour_list_iterator;
|
||||
typedef tgcontour_list::const_iterator const_tgcontour_list_iterator;
|
||||
|
||||
class tgTriangle
|
||||
{
|
||||
public:
|
||||
tgTriangle( const SGGeod& p0, const SGGeod& p1, const SGGeod& p2 ) {
|
||||
node_list.push_back( p0 );
|
||||
node_list.push_back( p1 );
|
||||
node_list.push_back( p2 );
|
||||
|
||||
tc_list.resize( 3, SGVec2d(0.0, 0.0) );
|
||||
norm_list.resize( 3, SGVec3d(0.0, 0.0, 0.0) );
|
||||
idx_list.resize( 3, -1 );
|
||||
}
|
||||
|
||||
SGGeod GetNode( unsigned int i ) const {
|
||||
return node_list[i];
|
||||
}
|
||||
SGVec2d GetTexCoord( unsigned int i ) const {
|
||||
return tc_list[i];
|
||||
}
|
||||
void SetTexCoord( unsigned int i, const SGVec2d tc ) {
|
||||
tc_list[i] = tc;
|
||||
}
|
||||
|
||||
// Friend for output
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgTriangle& );
|
||||
|
||||
private:
|
||||
std::vector<SGGeod> node_list;
|
||||
std::vector<SGVec2d> tc_list;
|
||||
std::vector<SGVec3d> norm_list;
|
||||
std::vector<int> idx_list;
|
||||
|
||||
SGVec3d face_normal;
|
||||
double face_area;
|
||||
};
|
||||
|
||||
typedef std::vector <tgTriangle> tgtriangle_list;
|
||||
typedef tgtriangle_list::iterator tgtriangle_list_iterator;
|
||||
typedef tgtriangle_list::const_iterator const_tgtriangle_list_iterator;
|
||||
|
||||
typedef enum {
|
||||
TG_TEX_BY_GEODE,
|
||||
TG_TEX_BY_TPS_NOCLIP,
|
||||
TG_TEX_BY_TPS_CLIPU,
|
||||
TG_TEX_BY_TPS_CLIPV,
|
||||
TG_TEX_BY_TPS_CLIPUV
|
||||
} tgTexMethod;
|
||||
|
||||
class tgTexParams
|
||||
{
|
||||
public:
|
||||
SGGeod ref;
|
||||
double width;
|
||||
double length;
|
||||
double heading;
|
||||
|
||||
double minu;
|
||||
double maxu;
|
||||
double minv;
|
||||
double maxv;
|
||||
|
||||
double min_clipu;
|
||||
double max_clipu;
|
||||
double min_clipv;
|
||||
double max_clipv;
|
||||
|
||||
tgTexMethod method;
|
||||
|
||||
// Friend for output
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgTexParams& );
|
||||
};
|
||||
|
||||
// Forward Declaration:
|
||||
class tgPolygon;
|
||||
typedef std::vector <tgPolygon> tgpolygon_list;
|
||||
typedef tgpolygon_list::iterator tgpolygon_list_iterator;
|
||||
typedef tgpolygon_list::const_iterator const_tgpolygon_list_iterator;
|
||||
typedef void (*tgpolygon_texfunc)(void);
|
||||
|
||||
class tgPolygon
|
||||
{
|
||||
public:
|
||||
|
||||
void Erase( void ) {
|
||||
contours.clear();
|
||||
triangles.clear();
|
||||
}
|
||||
|
||||
unsigned int Contours( void ) const {
|
||||
return contours.size();
|
||||
}
|
||||
unsigned int ContourSize( unsigned int c ) const {
|
||||
return contours[c].GetSize();
|
||||
}
|
||||
void AddContour( tgContour contour ) {
|
||||
contours.push_back(contour);
|
||||
}
|
||||
tgContour GetContour( unsigned int c ) const {
|
||||
return contours[c];
|
||||
}
|
||||
void DeleteContourAt( unsigned int idx ) {
|
||||
if ( idx < contours.size() ) {
|
||||
contours.erase( contours.begin() + idx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int TotalNodes( void ) const;
|
||||
SGGeod GetNode( unsigned int c, unsigned int i ) const {
|
||||
return contours[c].GetNode( i );
|
||||
}
|
||||
void SetNode( unsigned int c, unsigned int i, const SGGeod& n ) {
|
||||
contours[c].SetNode( i, n );
|
||||
}
|
||||
|
||||
void AddNode( unsigned int c, const SGGeod& n ) {
|
||||
// Make sure we have contour c. If we don't add it
|
||||
while( contours.size() < c+1 ) {
|
||||
tgContour dummy;
|
||||
dummy.SetHole( false );
|
||||
contours.push_back( dummy );
|
||||
}
|
||||
|
||||
contours[c].AddNode( n );
|
||||
}
|
||||
|
||||
tg::Rectangle GetBoundingBox( void ) const;
|
||||
|
||||
void InheritElevations( const tgPolygon& source );
|
||||
|
||||
unsigned int Triangles( void ) const {
|
||||
return triangles.size();
|
||||
}
|
||||
void AddTriangle( const SGGeod& p1, const SGGeod p2, const SGGeod p3 ) {
|
||||
triangles.push_back( tgTriangle( p1, p2, p3 ) );
|
||||
}
|
||||
|
||||
SGGeod GetTriNode( unsigned int c, unsigned int i ) const {
|
||||
return triangles[c].GetNode( i );
|
||||
}
|
||||
SGVec2d GetTriTexCoord( unsigned int c, unsigned int i ) const {
|
||||
return triangles[c].GetTexCoord( i );
|
||||
}
|
||||
|
||||
std::string GetMaterial( void ) const {
|
||||
return material;
|
||||
}
|
||||
void SetMaterial( const std::string m ) {
|
||||
material = m;
|
||||
}
|
||||
void SetTexParams( const SGGeod& ref, double width, double length, double heading ) {
|
||||
tp.ref = ref;
|
||||
tp.width = width;
|
||||
tp.length = length;
|
||||
tp.heading = heading;
|
||||
}
|
||||
void SetTexParams( const tgTexParams& t ) {
|
||||
tp = t;
|
||||
}
|
||||
const tgTexParams& GetTexParams( void ) const {
|
||||
return tp;
|
||||
}
|
||||
|
||||
void SetTexLimits( double minu, double minv, double maxu, double maxv ) {
|
||||
tp.minu = minu;
|
||||
tp.minv = minv;
|
||||
tp.maxu = maxu;
|
||||
tp.maxv = maxv;
|
||||
}
|
||||
void SetTexMethod( tgTexMethod m ) {
|
||||
tp.method = m;
|
||||
}
|
||||
void SetTexMethod( tgTexMethod m, double min_cu, double min_cv, double max_cu, double max_cv ) {
|
||||
tp.method = m;
|
||||
tp.min_clipu = min_cu;
|
||||
tp.min_clipv = min_cv;
|
||||
tp.max_clipu = max_cu;
|
||||
tp.max_clipv = max_cv;
|
||||
}
|
||||
|
||||
void Tesselate( void );
|
||||
void Tesselate( std::vector<SGGeod> extra );
|
||||
|
||||
void Texture( void );
|
||||
|
||||
// Boolean operations
|
||||
|
||||
// TODO : Both should be constant
|
||||
// what we really need is multiple accumulators
|
||||
// init_accumulator should return a handle...
|
||||
static tgPolygon Union( const tgContour& subject, tgPolygon& clip );
|
||||
static tgPolygon Union( const tgPolygon& subject, tgPolygon& clip );
|
||||
static tgPolygon Intersect( const tgPolygon& subject, const tgPolygon& clip );
|
||||
|
||||
static tgPolygon DiffWithAccumulator( const tgPolygon& subject );
|
||||
static void AddToAccumulator( const tgPolygon& subject );
|
||||
|
||||
// Conversions
|
||||
static ClipperLib::Polygons ToClipper( const tgPolygon& subject );
|
||||
static tgPolygon FromClipper( const ClipperLib::Polygons& subject );
|
||||
|
||||
// other operations
|
||||
static tgPolygon Snap( const tgPolygon& subject, double snap );
|
||||
static tgPolygon StripHoles( const tgPolygon& subject );
|
||||
static tgPolygon SplitLongEdges( const tgPolygon& subject, double dist );
|
||||
|
||||
static tgPolygon RemoveCycles( const tgPolygon& subject );
|
||||
static tgPolygon RemoveDups( const tgPolygon& subject );
|
||||
static tgPolygon RemoveBadContours( const tgPolygon& subject );
|
||||
static tgPolygon Simplify( const tgPolygon& subject );
|
||||
static tgPolygon RemoveTinyContours( const tgPolygon& subject );
|
||||
static tgPolygon RemoveSpikes( const tgPolygon& subject );
|
||||
|
||||
static tgPolygon Expand( const tgPolygon& subject, double offset );
|
||||
|
||||
static void Chop( const tgPolygon& subject, const std::string& path, const std::string& type, bool withTexparams, bool preserve3d );
|
||||
static void ToShapefile( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& feature );
|
||||
|
||||
static void Tesselate( const tgPolygon& subject );
|
||||
|
||||
static tgPolygon AddColinearNodes( const tgPolygon& subject, TGTriNodes& nodes );
|
||||
|
||||
static void RemoveSlivers( tgPolygon& subject, tgcontour_list& slivers );
|
||||
static void MergeSlivers( tgpolygon_list& subjects, tgcontour_list& slivers );
|
||||
|
||||
void SaveToGzFile( gzFile& fp );
|
||||
void LoadFromGzFile( gzFile& fp );
|
||||
|
||||
// Friend for output
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgPolygon& );
|
||||
|
||||
private:
|
||||
tgcontour_list contours;
|
||||
tgtriangle_list triangles;
|
||||
|
||||
std::string material;
|
||||
std::string flag; // let's get rid of this....
|
||||
tgTexParams tp;
|
||||
};
|
||||
|
||||
class tgLight
|
||||
{
|
||||
public:
|
||||
SGGeod pos;
|
||||
SGVec3d norm;
|
||||
};
|
||||
|
||||
typedef std::vector <tgLight> tglight_list;
|
||||
typedef tglight_list::iterator tglight_list_iterator;
|
||||
typedef tglight_list::const_iterator const_tglight_list_iterator;
|
||||
|
||||
class tgLightContour
|
||||
{
|
||||
public:
|
||||
unsigned int ContourSize( void ) const {
|
||||
return lights.size();
|
||||
}
|
||||
|
||||
void AddLight( SGGeod p, SGVec3d n ) {
|
||||
tgLight light;
|
||||
light.pos = p;
|
||||
light.norm = n;
|
||||
lights.push_back(light);
|
||||
}
|
||||
|
||||
SGGeod GetNode( unsigned int i ) const {
|
||||
return lights[i].pos;
|
||||
}
|
||||
|
||||
std::string GetFlag( void ) const {
|
||||
return flag;
|
||||
}
|
||||
void SetFlag( const std::string f ) {
|
||||
flag = f;
|
||||
}
|
||||
|
||||
std::string GetType( void ) const {
|
||||
return type;
|
||||
}
|
||||
void SetType( const std::string t ) {
|
||||
type = t;
|
||||
}
|
||||
|
||||
// TEMP TEMP TEMP : need to redo Airport.cxx methods
|
||||
point_list TempGetPosListAsPoint3D( void ) {
|
||||
point_list p3dlist;
|
||||
|
||||
for (unsigned int i=0; i<lights.size(); i++) {
|
||||
p3dlist.push_back( Point3D::fromSGGeod( lights[i].pos ) );
|
||||
}
|
||||
|
||||
return p3dlist;
|
||||
}
|
||||
|
||||
point_list TempGetNormalListAsPoint3D( void ) {
|
||||
point_list p3dlist;
|
||||
|
||||
for (unsigned int i=0; i<lights.size(); i++) {
|
||||
p3dlist.push_back( Point3D::fromSGVec3( lights[i].norm ) );
|
||||
}
|
||||
|
||||
return p3dlist;
|
||||
}
|
||||
// END TEMP TEMP TEMP
|
||||
|
||||
// Friend for output
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgLightContour& );
|
||||
|
||||
std::string type;
|
||||
std::string flag;
|
||||
tglight_list lights;
|
||||
};
|
||||
|
||||
typedef std::vector <tgLightContour> tglightcontour_list;
|
||||
typedef tglightcontour_list::iterator tglightcontour_list_iterator;
|
||||
typedef tglightcontour_list::const_iterator const_tglightcontour_list_iterator;
|
||||
|
||||
#endif // _POLYGON_HXX
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "polygon.hxx"
|
||||
#include <Polygon/polygon.hxx>
|
||||
|
||||
// TODO : Needs to be its own class
|
||||
typedef std::vector < int > int_list;
|
||||
|
|
Loading…
Add table
Reference in a new issue