Added Airport boundary support.
- needs testing on lots of airports. I'm uncomfortable with expanding concave polys by 20 meters. I really need to find a safe polygon expander.
This commit is contained in:
parent
33c92f60f6
commit
3ba27cd481
10 changed files with 267 additions and 125 deletions
|
@ -35,14 +35,12 @@ Airport::Airport( int c, char* def)
|
||||||
|
|
||||||
code = c;
|
code = c;
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "sscanf " << def);
|
|
||||||
numParams = sscanf(def, "%d %d %d %s %ls", &altitude, &x, &y, tmp, d);
|
numParams = sscanf(def, "%d %d %d %s %ls", &altitude, &x, &y, tmp, d);
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "done ");
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "got " << altitude << ", " << tmp << ", " << d);
|
|
||||||
|
|
||||||
altitude *= SG_FEET_TO_METER;
|
altitude *= SG_FEET_TO_METER;
|
||||||
icao = tmp;
|
icao = tmp;
|
||||||
description = d;
|
description = d;
|
||||||
|
boundary = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix OSG - it was nice, but unnecesary...
|
// TODO: fix OSG - it was nice, but unnecesary...
|
||||||
|
@ -380,7 +378,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
{
|
{
|
||||||
if ( runways[i]->IsPrecision() )
|
if ( runways[i]->IsPrecision() )
|
||||||
{
|
{
|
||||||
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
|
if (boundary)
|
||||||
|
{
|
||||||
|
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +402,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
{
|
{
|
||||||
for (i=0; i<helipads.size(); i++ )
|
for (i=0; i<helipads.size(); i++ )
|
||||||
{
|
{
|
||||||
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
|
if (boundary)
|
||||||
|
{
|
||||||
|
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Build the pavements
|
// Build the pavements
|
||||||
|
@ -406,8 +418,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
for ( i=0; i<pavements.size(); i++ )
|
for ( i=0; i<pavements.size(); i++ )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
|
SG_LOG(SG_GENERAL, SG_ALERT, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
|
||||||
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, &apt_base, &apt_clearing );
|
|
||||||
// AddFeatures( pavements[i]->GetMarkings() );
|
if (boundary)
|
||||||
|
{
|
||||||
|
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, NULL, NULL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, &apt_base, &apt_clearing );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -415,6 +434,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "no pavements");
|
SG_LOG(SG_GENERAL, SG_ALERT, "no pavements");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build the base and clearing if there's a boundary
|
||||||
|
if (boundary)
|
||||||
|
{
|
||||||
|
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
|
||||||
|
}
|
||||||
|
|
||||||
if ( apt_base.total_size() == 0 )
|
if ( apt_base.total_size() == 0 )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
|
SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
|
||||||
|
|
|
@ -57,6 +57,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetBoundary( ClosedPoly* bndry )
|
||||||
|
{
|
||||||
|
boundary = bndry;
|
||||||
|
}
|
||||||
|
|
||||||
void AddWindsock( Windsock* windsock )
|
void AddWindsock( Windsock* windsock )
|
||||||
{
|
{
|
||||||
windsocks.push_back( windsock );
|
windsocks.push_back( windsock );
|
||||||
|
@ -90,6 +95,7 @@ private:
|
||||||
BeaconList beacons;
|
BeaconList beacons;
|
||||||
SignList signs;
|
SignList signs;
|
||||||
HelipadList helipads;
|
HelipadList helipads;
|
||||||
|
ClosedPoly* boundary;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector <Airport *> AirportList;
|
typedef std::vector <Airport *> AirportList;
|
||||||
|
|
|
@ -14,12 +14,31 @@
|
||||||
#include "convex_hull.hxx"
|
#include "convex_hull.hxx"
|
||||||
#include "closedpoly.hxx"
|
#include "closedpoly.hxx"
|
||||||
|
|
||||||
|
ClosedPoly::ClosedPoly( char* desc )
|
||||||
|
{
|
||||||
|
is_pavement = false;
|
||||||
|
|
||||||
|
if ( desc )
|
||||||
|
{
|
||||||
|
description = desc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
description = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
boundary = NULL;
|
||||||
|
cur_contour = NULL;
|
||||||
|
cur_feature = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
|
ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
|
||||||
{
|
{
|
||||||
surface_type = st;
|
surface_type = st;
|
||||||
smoothness = s;
|
smoothness = s;
|
||||||
texture_heading = th;
|
texture_heading = th;
|
||||||
|
is_pavement = true;
|
||||||
|
|
||||||
if ( desc )
|
if ( desc )
|
||||||
{
|
{
|
||||||
description = desc;
|
description = desc;
|
||||||
|
@ -43,31 +62,28 @@ void ClosedPoly::AddNode( BezNode* node )
|
||||||
}
|
}
|
||||||
cur_contour->push_back( node );
|
cur_contour->push_back( node );
|
||||||
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : (" << node->GetLoc().x() << "," << node->GetLoc().y() << ")");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : (" << node->GetLoc().x() << "," << node->GetLoc().y() << ")");
|
||||||
|
|
||||||
|
// For pavement polys, add a linear feature for each contour
|
||||||
// TODO: Create ONE linear feature for each contour.
|
if (is_pavement)
|
||||||
// Parse the polys in linear feature
|
|
||||||
// if recording a linear feature on the pavement, add this node
|
|
||||||
// to it as well
|
|
||||||
// TODO: just doing marking now, need lighting as well
|
|
||||||
if (!cur_feature)
|
|
||||||
{
|
{
|
||||||
string feature_desc = description + ":";
|
if (!cur_feature)
|
||||||
if (boundary)
|
|
||||||
{
|
{
|
||||||
feature_desc += "hole";
|
string feature_desc = description + ":";
|
||||||
}
|
if (boundary)
|
||||||
else
|
{
|
||||||
{
|
feature_desc += "hole";
|
||||||
feature_desc += "boundary";
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
feature_desc += "boundary";
|
||||||
|
}
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " Adding node (" << node->GetLoc().x() << "," << node->GetLoc().y() << ") to current linear feature " << cur_feature);
|
SG_LOG(SG_GENERAL, SG_DEBUG, " Adding node (" << node->GetLoc().x() << "," << node->GetLoc().y() << ") to current linear feature " << cur_feature);
|
||||||
cur_feature = new LinearFeature(feature_desc, 1.0f );
|
cur_feature = new LinearFeature(feature_desc, 1.0f );
|
||||||
}
|
}
|
||||||
cur_feature->AddNode( node );
|
cur_feature->AddNode( node );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClosedPoly::CreateConvexHull( void )
|
void ClosedPoly::CreateConvexHull( void )
|
||||||
|
@ -77,17 +93,20 @@ void ClosedPoly::CreateConvexHull( void )
|
||||||
Point3D p;
|
Point3D p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (boundary->size() > 2){
|
if (boundary->size() > 2)
|
||||||
|
{
|
||||||
for (i=0; i<boundary->size(); i++)
|
for (i=0; i<boundary->size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
p = boundary->at(i)->GetLoc();
|
p = boundary->at(i)->GetLoc();
|
||||||
nodes.push_back( p );
|
nodes.push_back( p );
|
||||||
}
|
}
|
||||||
convexHull = convex_hull( nodes );
|
convexHull = convex_hull( nodes );
|
||||||
hull = convexHull.get_contour(0);
|
hull = convexHull.get_contour(0);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Boundary size too small: " << boundary->size() << ". Ignoring..." );
|
SG_LOG(SG_GENERAL, SG_ALERT, "Boundary size too small: " << boundary->size() << ". Ignoring..." );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClosedPoly::CloseCurContour()
|
int ClosedPoly::CloseCurContour()
|
||||||
|
@ -281,9 +300,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the first point again?
|
|
||||||
// dst->push_back( src->at(0)->GetLoc() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpandPoint( Point3D *prev, Point3D *cur, Point3D *next, double expand_by, double *heading, double *offset )
|
void ExpandPoint( Point3D *prev, Point3D *cur, Point3D *next, double expand_by, double *heading, double *offset )
|
||||||
|
@ -459,7 +475,7 @@ int ClosedPoly::Finish()
|
||||||
// error handling
|
// error handling
|
||||||
if (boundary == NULL)
|
if (boundary == NULL)
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "no boundary");
|
SG_LOG(SG_GENERAL, SG_ALERT, "no boundary");
|
||||||
}
|
}
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Converting a poly with " << holes.size() << " holes");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Converting a poly with " << holes.size() << " holes");
|
||||||
|
@ -485,7 +501,7 @@ int ClosedPoly::Finish()
|
||||||
delete boundary;
|
delete boundary;
|
||||||
boundary = NULL;
|
boundary = NULL;
|
||||||
|
|
||||||
// The convert the hole contours
|
// and the hole contours
|
||||||
holes.clear();
|
holes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,84 +595,109 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
|
||||||
string material;
|
string material;
|
||||||
int j, k;
|
int j, k;
|
||||||
|
|
||||||
switch( surface_type )
|
if (is_pavement)
|
||||||
{
|
{
|
||||||
case 1:
|
switch( surface_type )
|
||||||
material = "pa_tiedown";
|
{
|
||||||
break;
|
case 1:
|
||||||
|
material = "pa_tiedown";
|
||||||
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
material = "pc_tiedown";
|
material = "pc_tiedown";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
material = "grass_rwy";
|
material = "grass_rwy";
|
||||||
break;
|
break;
|
||||||
// TODO Differentiate more here:
|
|
||||||
case 4:
|
// TODO Differentiate more here:
|
||||||
case 5:
|
case 4:
|
||||||
case 12:
|
case 5:
|
||||||
case 13:
|
case 12:
|
||||||
case 14:
|
case 13:
|
||||||
case 15:
|
case 14:
|
||||||
material = "grass_rwy";
|
case 15:
|
||||||
break;
|
material = "grass_rwy";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type );
|
SG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type );
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify the poly has been generated
|
||||||
|
if ( pre_tess.contours() )
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
||||||
|
|
||||||
|
// do this before clipping and generating the base
|
||||||
|
pre_tess = remove_dups( pre_tess );
|
||||||
|
pre_tess = reduce_degeneracy( pre_tess );
|
||||||
|
|
||||||
|
for (int c=0; c<pre_tess.contours(); c++)
|
||||||
|
{
|
||||||
|
for (int pt=0; pt<pre_tess.contour_size(c); pt++)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: contour " << c << " pt " << pt << ": (" << pre_tess.get_pt(c, pt).x() << "," << pre_tess.get_pt(c, pt).y() << ")" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TGSuperPoly sp;
|
||||||
|
TGTexParams tp;
|
||||||
|
|
||||||
|
TGPolygon clipped = tgPolygonDiff( pre_tess, *accum );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly has " << clipped.contours() << " contours");
|
||||||
|
|
||||||
|
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: split poly has " << split.contours() << " contours");
|
||||||
|
|
||||||
|
sp.erase();
|
||||||
|
sp.set_poly( split );
|
||||||
|
sp.set_material( material );
|
||||||
|
//sp.set_flag("taxi");
|
||||||
|
|
||||||
|
rwy_polys->push_back( sp );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||||
|
*accum = tgPolygonUnion( pre_tess, *accum );
|
||||||
|
tp = TGTexParams( pre_tess.get_pt(0,0), 5.0, 5.0, texture_heading );
|
||||||
|
texparams->push_back( tp );
|
||||||
|
|
||||||
|
if ( apt_base )
|
||||||
|
{
|
||||||
|
ExpandContour( hull, base, 20.0 );
|
||||||
|
ExpandContour( hull, safe_base, 50.0 );
|
||||||
|
|
||||||
|
// add this to the airport clearing
|
||||||
|
*apt_clearing = tgPolygonUnion( safe_base, *apt_clearing);
|
||||||
|
|
||||||
|
// and add the clearing to the base
|
||||||
|
*apt_base = tgPolygonUnion( base, *apt_base );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clean up to save ram : we're done here...
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClosedPoly::BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing )
|
||||||
|
{
|
||||||
|
TGPolygon base, safe_base;
|
||||||
|
|
||||||
// verify the poly has been generated
|
// verify the poly has been generated
|
||||||
if ( pre_tess.contours() )
|
if ( pre_tess.contours() )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
||||||
|
|
||||||
// do this before clipping and generating the base
|
hull = pre_tess.get_contour(0);
|
||||||
pre_tess = remove_dups( pre_tess );
|
ExpandContour( hull, safe_base, 20.0 );
|
||||||
pre_tess = reduce_degeneracy( pre_tess );
|
|
||||||
|
|
||||||
for (int c=0; c<pre_tess.contours(); c++)
|
|
||||||
{
|
|
||||||
for (int pt=0; pt<pre_tess.contour_size(c); pt++)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: contour " << c << " pt " << pt << ": (" << pre_tess.get_pt(c, pt).x() << "," << pre_tess.get_pt(c, pt).y() << ")" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TGSuperPoly sp;
|
|
||||||
TGTexParams tp;
|
|
||||||
|
|
||||||
TGPolygon clipped = tgPolygonDiff( pre_tess, *accum );
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly has " << clipped.contours() << " contours");
|
|
||||||
|
|
||||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: split poly has " << split.contours() << " contours");
|
|
||||||
|
|
||||||
sp.erase();
|
|
||||||
sp.set_poly( split );
|
|
||||||
sp.set_material( material );
|
|
||||||
//sp.set_flag("taxi");
|
|
||||||
|
|
||||||
rwy_polys->push_back( sp );
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
|
||||||
*accum = tgPolygonUnion( pre_tess, *accum );
|
|
||||||
tp = TGTexParams( pre_tess.get_pt(0,0), 5.0, 5.0, texture_heading );
|
|
||||||
texparams->push_back( tp );
|
|
||||||
|
|
||||||
ExpandContour( hull, base, 20.0 );
|
|
||||||
ExpandContour( hull, safe_base, 50.0 );
|
|
||||||
|
|
||||||
// add this to the airport clearing
|
// add this to the airport clearing
|
||||||
*apt_clearing = tgPolygonUnion( safe_base, *apt_clearing);
|
*apt_clearing = tgPolygonUnion( safe_base, *apt_clearing);
|
||||||
|
|
||||||
// and add the clearing to the base
|
// and add the clearing to the base
|
||||||
*apt_base = tgPolygonUnion( base, *apt_base );
|
*apt_base = tgPolygonUnion( pre_tess, *apt_base );
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up to save ram : we're done here...
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,20 @@ using std::string;
|
||||||
class ClosedPoly
|
class ClosedPoly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ClosedPoly( char* desc );
|
||||||
ClosedPoly( int st, float s, float th, char* desc );
|
ClosedPoly( int st, float s, float th, char* desc );
|
||||||
|
|
||||||
inline string GetDescription() { return description; }
|
inline string GetDescription() { return description; }
|
||||||
void AddNode( BezNode* node );
|
void AddNode( BezNode* node );
|
||||||
int CloseCurContour();
|
int CloseCurContour();
|
||||||
int Finish();
|
int Finish();
|
||||||
|
|
||||||
int BuildOsg( osg::Group* airport );
|
int BuildOsg( osg::Group* airport );
|
||||||
|
|
||||||
|
// Build BTG for airport base for airports with boundary
|
||||||
|
int BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing );
|
||||||
|
|
||||||
|
// Build BTG for pavements for airports with no boundary
|
||||||
int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing );
|
int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing );
|
||||||
|
|
||||||
FeatureList* GetFeatures()
|
FeatureList* GetFeatures()
|
||||||
|
@ -40,6 +47,7 @@ private:
|
||||||
osg::DrawArrays* CreateOsgPrimitive( point_list contour, osg::Vec3Array* vpave );
|
osg::DrawArrays* CreateOsgPrimitive( point_list contour, osg::Vec3Array* vpave );
|
||||||
void ExpandContour( point_list& src, TGPolygon& dst, double dist );
|
void ExpandContour( point_list& src, TGPolygon& dst, double dist );
|
||||||
|
|
||||||
|
bool is_pavement;
|
||||||
int surface_type;
|
int surface_type;
|
||||||
float smoothness;
|
float smoothness;
|
||||||
float texture_heading;
|
float texture_heading;
|
||||||
|
|
|
@ -114,17 +114,20 @@ void Helipad::BuildBtg( float alt_m,
|
||||||
|
|
||||||
|
|
||||||
// generate area around helipad
|
// generate area around helipad
|
||||||
TGPolygon base, safe_base;
|
if (apt_base)
|
||||||
base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 );
|
{
|
||||||
|
TGPolygon base, safe_base;
|
||||||
|
base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 );
|
||||||
|
|
||||||
// also clear a safe area around the pad
|
// also clear a safe area around the pad
|
||||||
safe_base = gen_runway_area_w_extend( 0.0, maxsize * 0.5, 0.0, 0.0, maxsize * 0.5 );
|
safe_base = gen_runway_area_w_extend( 0.0, maxsize * 0.5, 0.0, 0.0, maxsize * 0.5 );
|
||||||
|
|
||||||
// add this to the airport clearing
|
// add this to the airport clearing
|
||||||
*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
|
*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
|
||||||
|
|
||||||
// and add the clearing to the base
|
// and add the clearing to the base
|
||||||
*apt_base = tgPolygonUnion( base, *apt_base );
|
*apt_base = tgPolygonUnion( base, *apt_base );
|
||||||
|
}
|
||||||
|
|
||||||
// Now generate the helipad lights
|
// Now generate the helipad lights
|
||||||
superpoly_list s = gen_helipad_lights();
|
superpoly_list s = gen_helipad_lights();
|
||||||
|
|
|
@ -2578,7 +2578,7 @@ superpoly_list Runway::gen_malsx( float alt_m, const string& kind, bool recip )
|
||||||
|
|
||||||
|
|
||||||
// top level runway light generator
|
// top level runway light generator
|
||||||
void Runway::gen_runway_lights( float alt_m, superpoly_list *lights, TGPolygon *apt_base ) {
|
void Runway::gen_runway_lights( float alt_m, superpoly_list *lights ) {
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,30 @@ ClosedPoly* Parser::ParsePavement( char* line )
|
||||||
return poly;
|
return poly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClosedPoly* Parser::ParseBoundary( char* line )
|
||||||
|
{
|
||||||
|
ClosedPoly* poly;
|
||||||
|
char desc[256];
|
||||||
|
char *d = NULL;
|
||||||
|
int numParams;
|
||||||
|
|
||||||
|
numParams = sscanf(line, "%ls", desc);
|
||||||
|
|
||||||
|
if (numParams == 1)
|
||||||
|
{
|
||||||
|
d = strstr(line,desc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly for airport boundary : " << d);
|
||||||
|
poly = new ClosedPoly(d);
|
||||||
|
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
|
||||||
int Parser::SetState( int state )
|
int Parser::SetState( int state )
|
||||||
{
|
{
|
||||||
// if we are currently parsing pavement, the oly way we know we are done
|
// if we are currently parsing pavement, the oly way we know we are done
|
||||||
|
@ -223,6 +247,14 @@ int Parser::SetState( int state )
|
||||||
cur_pavement = NULL;
|
cur_pavement = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( cur_airport && cur_state == STATE_PARSE_BOUNDARY )
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Closing and Adding boundary");
|
||||||
|
cur_boundary->Finish();
|
||||||
|
cur_airport->SetBoundary( cur_boundary );
|
||||||
|
cur_boundary = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
cur_state = state;
|
cur_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,8 +329,7 @@ int Parser::ParseLine(char* line)
|
||||||
|
|
||||||
case BOUNDRY_CODE:
|
case BOUNDRY_CODE:
|
||||||
SetState( STATE_PARSE_BOUNDARY );
|
SetState( STATE_PARSE_BOUNDARY );
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airport boundary: " << line);
|
cur_boundary = ParseBoundary( line );
|
||||||
// ParseBoundry(line);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_CODE:
|
case NODE_CODE:
|
||||||
|
@ -317,6 +348,10 @@ int Parser::ParseLine(char* line)
|
||||||
{
|
{
|
||||||
cur_feat->AddNode( prev_node );
|
cur_feat->AddNode( prev_node );
|
||||||
}
|
}
|
||||||
|
else if ( cur_state == STATE_PARSE_BOUNDARY )
|
||||||
|
{
|
||||||
|
cur_boundary->AddNode( prev_node );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_node = cur_node;
|
prev_node = cur_node;
|
||||||
|
@ -340,6 +375,19 @@ int Parser::ParseLine(char* line)
|
||||||
}
|
}
|
||||||
cur_pavement->CloseCurContour();
|
cur_pavement->CloseCurContour();
|
||||||
}
|
}
|
||||||
|
else if ( cur_state == STATE_PARSE_BOUNDARY )
|
||||||
|
{
|
||||||
|
if (cur_node != prev_node)
|
||||||
|
{
|
||||||
|
cur_boundary->AddNode( prev_node );
|
||||||
|
cur_boundary->AddNode( cur_node );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur_boundary->AddNode( cur_node );
|
||||||
|
}
|
||||||
|
cur_boundary->CloseCurContour();
|
||||||
|
}
|
||||||
else if ( cur_state == STATE_PARSE_FEATURE )
|
else if ( cur_state == STATE_PARSE_FEATURE )
|
||||||
{
|
{
|
||||||
if (cur_node != prev_node)
|
if (cur_node != prev_node)
|
||||||
|
|
|
@ -59,8 +59,16 @@ public:
|
||||||
{
|
{
|
||||||
filename = f;
|
filename = f;
|
||||||
cur_airport = NULL;
|
cur_airport = NULL;
|
||||||
|
cur_runway = NULL;
|
||||||
|
cur_waterrunway = NULL;
|
||||||
|
cur_helipad = NULL;
|
||||||
cur_pavement = NULL;
|
cur_pavement = NULL;
|
||||||
|
cur_boundary = NULL;
|
||||||
cur_feat = NULL;
|
cur_feat = NULL;
|
||||||
|
cur_object = NULL;
|
||||||
|
cur_windsock = NULL;
|
||||||
|
cur_beacon = NULL;
|
||||||
|
cur_sign = NULL;
|
||||||
prev_node = NULL;
|
prev_node = NULL;
|
||||||
cur_state = STATE_NONE;
|
cur_state = STATE_NONE;
|
||||||
}
|
}
|
||||||
|
@ -76,10 +84,12 @@ private:
|
||||||
LinearFeature* ParseFeature( char* line );
|
LinearFeature* ParseFeature( char* line );
|
||||||
ClosedPoly* ParsePavement( char* line );
|
ClosedPoly* ParsePavement( char* line );
|
||||||
osg::Geode* ParseRunway(char* line );
|
osg::Geode* ParseRunway(char* line );
|
||||||
|
ClosedPoly* ParseBoundary( char* line );
|
||||||
|
|
||||||
int ParseLine( char* line );
|
int ParseLine( char* line );
|
||||||
|
|
||||||
// int ParseBoundry(char* line, Node* airport);
|
BezNode* prev_node;
|
||||||
|
int cur_state;
|
||||||
string filename;
|
string filename;
|
||||||
|
|
||||||
// a polygon conists of an array of contours
|
// a polygon conists of an array of contours
|
||||||
|
@ -89,16 +99,14 @@ private:
|
||||||
WaterRunway* cur_waterrunway;
|
WaterRunway* cur_waterrunway;
|
||||||
Helipad* cur_helipad;
|
Helipad* cur_helipad;
|
||||||
ClosedPoly* cur_pavement;
|
ClosedPoly* cur_pavement;
|
||||||
|
ClosedPoly* cur_boundary;
|
||||||
LinearFeature* cur_feat;
|
LinearFeature* cur_feat;
|
||||||
BezNode* prev_node;
|
|
||||||
LightingObj* cur_object;
|
LightingObj* cur_object;
|
||||||
Windsock* cur_windsock;
|
Windsock* cur_windsock;
|
||||||
Beacon* cur_beacon;
|
Beacon* cur_beacon;
|
||||||
Sign* cur_sign;
|
Sign* cur_sign;
|
||||||
|
|
||||||
AirportList airports;
|
AirportList airports;
|
||||||
|
|
||||||
int cur_state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -170,7 +170,7 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
|
||||||
case 2: // concrete
|
case 2: // concrete
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Build Runway: asphalt or concrete" << rwy.surface);
|
SG_LOG( SG_GENERAL, SG_ALERT, "Build Runway: asphalt or concrete" << rwy.surface);
|
||||||
gen_rwy( alt_m, material, rwy_polys, texparams, accum );
|
gen_rwy( alt_m, material, rwy_polys, texparams, accum );
|
||||||
gen_runway_lights( alt_m, rwy_lights, apt_base );
|
gen_runway_lights( alt_m, rwy_lights );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Grass
|
case 3: // Grass
|
||||||
|
@ -178,7 +178,7 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
|
||||||
case 5: // Gravel
|
case 5: // Gravel
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Build Runway: Turf, Dirt or Gravel" << rwy.surface );
|
SG_LOG( SG_GENERAL, SG_ALERT, "Build Runway: Turf, Dirt or Gravel" << rwy.surface );
|
||||||
gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
|
gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
|
||||||
gen_runway_lights( alt_m, rwy_lights, apt_base );
|
gen_runway_lights( alt_m, rwy_lights );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 12: // dry lakebed
|
case 12: // dry lakebed
|
||||||
|
@ -202,15 +202,18 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate area around runways
|
if (apt_base)
|
||||||
base = gen_runway_area_w_extend( 0.0, rwy.width * 0.25, -rwy.overrun[0], -rwy.overrun[1], rwy.width * 0.25);
|
{
|
||||||
|
// generate area around runways
|
||||||
|
base = gen_runway_area_w_extend( 0.0, rwy.width * 0.25, -rwy.overrun[0], -rwy.overrun[1], rwy.width * 0.25);
|
||||||
|
|
||||||
// also clear a safe area around the runway
|
// also clear a safe area around the runway
|
||||||
safe_base = gen_runway_area_w_extend( 0.0, rwy.width, -rwy.overrun[0], -rwy.overrun[1], rwy.width );
|
safe_base = gen_runway_area_w_extend( 0.0, rwy.width, -rwy.overrun[0], -rwy.overrun[1], rwy.width );
|
||||||
|
|
||||||
// add this to the airport clearing
|
// add this to the airport clearing
|
||||||
*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
|
*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
|
||||||
|
|
||||||
// and add the clearing to the base
|
// and add the clearing to the base
|
||||||
*apt_base = tgPolygonUnion( base, *apt_base );
|
*apt_base = tgPolygonUnion( base, *apt_base );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ private:
|
||||||
texparams_list* texparams,
|
texparams_list* texparams,
|
||||||
TGPolygon* accum, int marking);
|
TGPolygon* accum, int marking);
|
||||||
|
|
||||||
void gen_runway_lights( float alt_m, superpoly_list* lights, TGPolygon* apt_base );
|
void gen_runway_lights( float alt_m, superpoly_list* lights );
|
||||||
|
|
||||||
Point3D gen_runway_light_vector( double angle, bool recip );
|
Point3D gen_runway_light_vector( double angle, bool recip );
|
||||||
superpoly_list gen_runway_edge_lights( bool recip );
|
superpoly_list gen_runway_edge_lights( bool recip );
|
||||||
|
|
Loading…
Reference in a new issue