Progress, we are now generating really crude airports.
This commit is contained in:
parent
3095364857
commit
43491f4ec0
3 changed files with 141 additions and 501 deletions
|
@ -29,6 +29,7 @@ genapts_SOURCES = \
|
|||
build.cxx build.hxx \
|
||||
convex_hull.cxx convex_hull.hxx \
|
||||
main.cxx \
|
||||
output.cxx output.hxx \
|
||||
point2d.cxx point2d.hxx \
|
||||
runway.cxx runway.hxx
|
||||
|
||||
|
|
|
@ -51,98 +51,12 @@
|
|||
#include <Triangulate/trieles.hxx>
|
||||
|
||||
#include "convex_hull.hxx"
|
||||
#include "output.hxx"
|
||||
#include "point2d.hxx"
|
||||
#include "runway.hxx"
|
||||
#include "scenery_version.hxx"
|
||||
|
||||
|
||||
typedef vector < int_list > group_list;
|
||||
typedef group_list::iterator group_list_iterator;
|
||||
typedef group_list::const_iterator const_group_list_iterator;
|
||||
|
||||
|
||||
void write_polygon( const FGPolygon& poly, const string& base ) {
|
||||
for ( int i = 0; i < poly.contours(); ++i ) {
|
||||
char name[256];
|
||||
sprintf(name, "%s%d", base.c_str(), i );
|
||||
FILE *fp = fopen( name, "w" );
|
||||
|
||||
for ( int j = 0; j < poly.contour_size( i ); ++j ) {
|
||||
Point3D p0 = poly.get_pt(i, j);
|
||||
fprintf(fp, "%.8f %.8f\n", p0.x(), p0.y());
|
||||
}
|
||||
Point3D p0 = poly.get_pt(i, 0);
|
||||
fprintf(fp, "%.8f %.8f\n", p0.x(), p0.y());
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// calculate distance in meters between two lat/lon points
|
||||
static double gc_dist( Point3D p1, Point3D p2 ) {
|
||||
Point3D r1( p1.x() * DEG_TO_RAD, p1.y() * DEG_TO_RAD, 0 );
|
||||
Point3D r2( p2.x() * DEG_TO_RAD, p2.y() * DEG_TO_RAD, 0 );
|
||||
|
||||
// d=2*asin(sqrt((sin((lat1-lat2)/2))^2 +
|
||||
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
|
||||
double tmp1 = sin( (r1.y() - r2.y()) / 2.0 );
|
||||
double tmp2 = sin( (r1.x() - r2.x()) / 2.0 );
|
||||
|
||||
// d=2*asin(sqrt((tmp1)^2 + cos(lat1)*cos(lat2)*(tmp2)^2))
|
||||
double clat1 = cos( r1.y() );
|
||||
double clat2 = cos( r1.y() );
|
||||
|
||||
// d=2*asin(sqrt(tmp1*tmp1 + clat1*clat2*tmp2*tmp2))
|
||||
double tmp3 = sqrt(tmp1*tmp1 + clat1*clat2*tmp2*tmp2);
|
||||
|
||||
// d=2*asin(tmp3)
|
||||
double d_rad = 2 * asin( tmp3 );
|
||||
// cout << " dist (rad) = " << d_rad << endl;
|
||||
|
||||
double d_nm = d_rad * RAD_TO_NM;
|
||||
// cout << " dist (nm) = " << d_nm << endl;
|
||||
|
||||
double d_m = d_nm * NM_TO_METER;
|
||||
// cout << " dist (m) = " << d_m << endl;
|
||||
|
||||
return d_m;
|
||||
}
|
||||
|
||||
|
||||
// calculate true course between two points given the distance in meters
|
||||
static double gc_course( Point3D p1, Point3D p2, double d_m ) {
|
||||
double lon1 = p1.x() * DEG_TO_RAD;
|
||||
double lon2 = p2.x() * DEG_TO_RAD;
|
||||
double lat1 = p1.y() * DEG_TO_RAD;
|
||||
double lat2 = p2.y() * DEG_TO_RAD;
|
||||
|
||||
double d_rad = d_m * METER_TO_NM * NM_TO_RAD;
|
||||
|
||||
double tc1;
|
||||
|
||||
if ( cos(lat1) < FG_EPSILON) {
|
||||
if ( lat1 > 0.0 ) {
|
||||
tc1 = FG_PI; // starting from N pole
|
||||
} else {
|
||||
tc1 = 0.0; // starting from S pole
|
||||
}
|
||||
}
|
||||
|
||||
// For starting points other than the poles:
|
||||
|
||||
if ( sin(lon2 - lon1) < 0.0 ) {
|
||||
tc1 = acos( (sin(lat2)-sin(lat1)*cos(d_rad))/(sin(d_rad)*cos(lat1)));
|
||||
} else {
|
||||
tc1 = FG_2PI -
|
||||
acos((sin(lat2)-sin(lat1)*cos(d_rad))/(sin(d_rad)*cos(lat1)));
|
||||
}
|
||||
|
||||
return tc1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// calculate texture coordinates for a 1/2 runway. Returns a mirror
|
||||
// polygon to the runway, except each point is the texture coordinate
|
||||
// of the corresponding point in the original polygon.
|
||||
|
@ -176,7 +90,7 @@ static FGPolygon rwy_calc_tex_coords( const FGRunway& rwy,
|
|||
&az1, &az2, &dist );
|
||||
|
||||
cout << "basic course = " << az1 << endl;
|
||||
double course = az1 + angle;
|
||||
double course = az1 - angle;
|
||||
cout << "course = " << course << endl;
|
||||
while ( course < -360 ) { course += 360; }
|
||||
while ( course > 360 ) { course -= 360; }
|
||||
|
@ -208,50 +122,6 @@ static FGPolygon rwy_calc_tex_coords( const FGRunway& rwy,
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// Find a the specified point in the polygon and set the contour/index
|
||||
// values for it. Returns true if a match found, false otherwise
|
||||
static bool find_in_polygon( const Point3D p, const FGPolygon poly,
|
||||
int *contour, int *index ) {
|
||||
*contour = *index = -1;
|
||||
Point3D tmp;
|
||||
|
||||
for ( int i = 0; i < poly.contours(); ++i ) {
|
||||
for ( int j = 0; j < poly.contour_size( i ); ++j ) {
|
||||
tmp = poly.get_pt( i, j );
|
||||
if ( tmp == p ) {
|
||||
*contour = i;
|
||||
*index = j;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
// Add points to keep line segment lengths under 1000'
|
||||
static FGPolygon add_points( const FGPolygon& in_poly ) {
|
||||
FGPolygon result;
|
||||
result.erase();
|
||||
|
||||
for ( int i = 0; i < in_poly.contours(); ++i ) {
|
||||
for ( int j = 0; j < in_poly.contour_size( i ) - 1; ++j ) {
|
||||
gc_dist( in_poly.get_pt( i, j ),
|
||||
in_poly.get_pt( i, j+1 ) );
|
||||
}
|
||||
gc_dist( in_poly.get_pt( i, in_poly.contour_size( i ) - 1 ),
|
||||
in_poly.get_pt( i, 0 ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Divide segment if there are other existing points on it, return the
|
||||
// new polygon
|
||||
void add_intermediate_nodes( int contour, const Point3D& start,
|
||||
|
@ -269,29 +139,32 @@ void add_intermediate_nodes( int contour, const Point3D& start,
|
|||
Point3D p0 = start;
|
||||
Point3D p1 = end;
|
||||
|
||||
cout << " add_intermediate_nodes()" << endl;
|
||||
// cout << " add_intermediate_nodes()" << endl;
|
||||
|
||||
double xdist = fabs(p0.x() - p1.x());
|
||||
double ydist = fabs(p0.y() - p1.y());
|
||||
cout << "xdist = " << xdist << " ydist = " << ydist << endl;
|
||||
// cout << "xdist = " << xdist << " ydist = " << ydist << endl;
|
||||
x_err_min = xdist + 1.0;
|
||||
y_err_min = ydist + 1.0;
|
||||
|
||||
if ( xdist > ydist ) {
|
||||
cout << "use y = mx + b" << endl;
|
||||
// cout << "use y = mx + b" << endl;
|
||||
|
||||
// sort these in a sensible order
|
||||
if ( p0.x() > p1.x() ) {
|
||||
Point3D tmp = p0;
|
||||
p0 = p1;
|
||||
p1 = tmp;
|
||||
Point3D p_min, p_max;
|
||||
if ( p0.x() < p1.x() ) {
|
||||
p_min = p0;
|
||||
p_max = p1;
|
||||
} else {
|
||||
p_min = p1;
|
||||
p_max = p0;
|
||||
}
|
||||
|
||||
m = (p0.y() - p1.y()) / (p0.x() - p1.x());
|
||||
b = p1.y() - m * p1.x();
|
||||
m = (p_min.y() - p_max.y()) / (p_min.x() - p_max.x());
|
||||
b = p_max.y() - m * p_max.x();
|
||||
|
||||
// if ( temp ) {
|
||||
cout << "m = " << m << " b = " << b << endl;
|
||||
// cout << "m = " << m << " b = " << b << endl;
|
||||
// }
|
||||
|
||||
current = nodes.begin();
|
||||
|
@ -300,17 +173,17 @@ void add_intermediate_nodes( int contour, const Point3D& start,
|
|||
for ( ; current != last; ++current ) {
|
||||
cout << counter << endl;
|
||||
|
||||
if ( (current->x() > (p0.x() + FG_EPSILON))
|
||||
&& (current->x() < (p1.x() - FG_EPSILON)) ) {
|
||||
if ( (current->x() > (p_min.x() + FG_EPSILON))
|
||||
&& (current->x() < (p_max.x() - FG_EPSILON)) ) {
|
||||
|
||||
cout << "found a potential candidate " << *current << endl;
|
||||
// cout << "found a potential candidate " << *current << endl;
|
||||
y_err = fabs(current->y() - (m * current->x() + b));
|
||||
cout << "y_err = " << y_err << endl;
|
||||
// cout << "y_err = " << y_err << endl;
|
||||
|
||||
if ( y_err < FG_PROXIMITY_EPSILON ) {
|
||||
cout << "FOUND EXTRA SEGMENT NODE (Y)" << endl;
|
||||
cout << p0 << " < " << *current << " < "
|
||||
<< p1 << endl;
|
||||
// cout << "FOUND EXTRA SEGMENT NODE (Y)" << endl;
|
||||
// cout << p_min << " < " << *current << " < "
|
||||
// << p_max << endl;
|
||||
found_extra = true;
|
||||
if ( y_err < y_err_min ) {
|
||||
extra_index = counter;
|
||||
|
@ -321,46 +194,49 @@ void add_intermediate_nodes( int contour, const Point3D& start,
|
|||
++counter;
|
||||
}
|
||||
} else {
|
||||
cout << "use x = m1 * y + b1" << endl;
|
||||
// cout << "use x = m1 * y + b1" << endl;
|
||||
|
||||
// sort these in a sensible order
|
||||
if ( p0.y() > p1.y() ) {
|
||||
Point3D tmp = p0;
|
||||
p0 = p1;
|
||||
p1 = tmp;
|
||||
Point3D p_min, p_max;
|
||||
if ( p0.y() < p1.y() ) {
|
||||
p_min = p0;
|
||||
p_min = p1;
|
||||
} else {
|
||||
p_min = p1;
|
||||
p_max = p0;
|
||||
}
|
||||
|
||||
m1 = (p0.x() - p1.x()) / (p0.y() - p1.y());
|
||||
b1 = p1.x() - m1 * p1.y();
|
||||
m1 = (p_min.x() - p_max.x()) / (p_min.y() - p_max.y());
|
||||
b1 = p_max.x() - m1 * p_max.y();
|
||||
|
||||
// bool temp = true;
|
||||
// if ( temp ) {
|
||||
cout << " m1 = " << m1 << " b1 = " << b1 << endl;
|
||||
// cout << " m1 = " << m1 << " b1 = " << b1 << endl;
|
||||
// }
|
||||
|
||||
// cout << " should = 0 = " << fabs(p0.x() - (m1 * p0.y() + b1)) << endl;;
|
||||
// cout << " should = 0 = " << fabs(p1.x() - (m1 * p1.y() + b1)) << endl;;
|
||||
// cout << " should = 0 = " << fabs(p_min.x() - (m1 * p_min.y() + b1)) << endl;;
|
||||
// cout << " should = 0 = " << fabs(p_max.x() - (m1 * p_max.y() + b1)) << endl;;
|
||||
|
||||
current = nodes.begin();
|
||||
last = nodes.end();
|
||||
counter = 0;
|
||||
for ( ; current != last; ++current ) {
|
||||
if ( (current->y() > (p0.y() + FG_EPSILON))
|
||||
&& (current->y() < (p1.y() - FG_EPSILON)) ) {
|
||||
if ( (current->y() > (p_min.y() + FG_EPSILON))
|
||||
&& (current->y() < (p_max.y() - FG_EPSILON)) ) {
|
||||
|
||||
cout << "found a potential candidate " << *current << endl;
|
||||
// cout << "found a potential candidate " << *current << endl;
|
||||
|
||||
x_err = fabs(current->x() - (m1 * current->y() + b1));
|
||||
cout << "x_err = " << x_err << endl;
|
||||
// cout << "x_err = " << x_err << endl;
|
||||
|
||||
// if ( temp ) {
|
||||
// cout << " (" << counter << ") x_err = " << x_err << endl;
|
||||
// }
|
||||
|
||||
if ( x_err < FG_PROXIMITY_EPSILON ) {
|
||||
cout << "FOUND EXTRA SEGMENT NODE (X)" << endl;
|
||||
cout << p0 << " < " << *current << " < "
|
||||
<< p1 << endl;
|
||||
// cout << "FOUND EXTRA SEGMENT NODE (X)" << endl;
|
||||
// cout << p_min << " < " << *current << " < "
|
||||
// << p_max << endl;
|
||||
found_extra = true;
|
||||
if ( x_err < x_err_min ) {
|
||||
extra_index = counter;
|
||||
|
@ -398,7 +274,7 @@ static FGPolygon add_nodes_to_poly( const FGPolygon& poly,
|
|||
FGPolygon result;
|
||||
Point3D p0, p1;
|
||||
|
||||
cout << "add_nodes_to_poly" << endl;
|
||||
// cout << "add_nodes_to_poly" << endl;
|
||||
|
||||
for ( int i = 0; i < poly.contours(); ++i ) {
|
||||
for ( int j = 0; j < poly.contour_size(i) - 1; ++j ) {
|
||||
|
@ -435,63 +311,6 @@ static FGPolygon add_nodes_to_poly( const FGPolygon& poly,
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// print polygon
|
||||
static void print_poly( const FGPolygon& poly ) {
|
||||
for ( int i = 0; i < poly.contours(); ++i ) {
|
||||
cout << "contour " << i << endl;
|
||||
for ( int j = 0; j < poly.contour_size( i ); ++j ) {
|
||||
cout << " " << poly.get_pt( i, j ) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// calculate the center of a list of points, by taking the halfway
|
||||
// point between the min and max points.
|
||||
Point3D calc_center( point_list& wgs84_nodes ) {
|
||||
Point3D p, min, max;
|
||||
|
||||
if ( wgs84_nodes.size() ) {
|
||||
min = max = wgs84_nodes[0];
|
||||
} else {
|
||||
min = max = Point3D( 0 );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
p = wgs84_nodes[i];
|
||||
|
||||
if ( p.x() < min.x() ) { min.setx( p.x() ); }
|
||||
if ( p.y() < min.y() ) { min.sety( p.y() ); }
|
||||
if ( p.z() < min.z() ) { min.setz( p.z() ); }
|
||||
|
||||
if ( p.x() > max.x() ) { max.setx( p.x() ); }
|
||||
if ( p.y() > max.y() ) { max.sety( p.y() ); }
|
||||
if ( p.z() > max.z() ) { max.setz( p.z() ); }
|
||||
}
|
||||
|
||||
return ( min + max ) / 2.0;
|
||||
}
|
||||
|
||||
// calculate the global bounding sphere. Center is the center of the
|
||||
// tile and zero elevation
|
||||
double calc_bounding_radius( Point3D center, point_list& wgs84_nodes ) {
|
||||
double dist_squared;
|
||||
double radius_squared = 0;
|
||||
|
||||
for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
dist_squared = center.distance3Dsquared( wgs84_nodes[i] );
|
||||
if ( dist_squared > radius_squared ) {
|
||||
radius_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
|
||||
return sqrt(radius_squared);
|
||||
}
|
||||
|
||||
|
||||
// fix node elevations
|
||||
point_list calc_elevations( const string& root, const point_list& geod_nodes ) {
|
||||
bool done = false;
|
||||
|
@ -507,7 +326,9 @@ point_list calc_elevations( const string& root, const point_list& geod_nodes ) {
|
|||
while ( !done ) {
|
||||
// find first node with -9999 elevation
|
||||
i = 0;
|
||||
while ( result[i].z() > -9000 ) { ++i; }
|
||||
while ( (result[i].z() > -9000) && (i < (int)result.size()) ) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if ( i < (int)result.size() ) {
|
||||
FGBucket b( result[i].x(), result[i].y() );
|
||||
|
@ -559,194 +380,6 @@ point_list calc_elevations( const string& root, const point_list& geod_nodes ) {
|
|||
}
|
||||
|
||||
|
||||
// write out the structures to a file. We assume that the groups come
|
||||
// to us sorted by material property. If not, things don't break, but
|
||||
// the result won't be as optimal.
|
||||
void write( const string& base, const FGBucket& b, const string& name,
|
||||
Point3D gbs_center, double gbs_radius,
|
||||
const point_list& wgs84_nodes, const point_list& normals,
|
||||
const point_list& texcoords,
|
||||
const group_list& strips_v, const group_list& strips_tc,
|
||||
const string_list& strip_materials,
|
||||
const group_list& fans_v, const group_list& fans_tc,
|
||||
const string_list& fan_materials )
|
||||
{
|
||||
Point3D p;
|
||||
|
||||
string dir = base + "/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + dir;
|
||||
system(command.c_str());
|
||||
|
||||
// string file = dir + "/" + b.gen_index_str();
|
||||
string file = dir + "/" + name;
|
||||
cout << "Output file = " << file << endl;
|
||||
|
||||
FILE *fp;
|
||||
if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
|
||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cout << "strip size = " << strips_v.size() << " strip_materials = "
|
||||
<< strip_materials.size() << endl;
|
||||
cout << "points = " << wgs84_nodes.size() << endl;
|
||||
cout << "tex coords = " << texcoords.size() << endl;
|
||||
// write headers
|
||||
fprintf(fp, "# FGFS Scenery\n");
|
||||
fprintf(fp, "# Version %s\n", FG_SCENERY_FILE_FORMAT);
|
||||
|
||||
time_t calendar_time = time(NULL);
|
||||
struct tm *local_tm;
|
||||
local_tm = localtime( &calendar_time );
|
||||
char time_str[256];
|
||||
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
|
||||
fprintf(fp, "# Created %s\n", time_str );
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write global bounding sphere
|
||||
fprintf(fp, "# gbs %.5f %.5f %.5f %.2f\n",
|
||||
gbs_center.x(), gbs_center.y(), gbs_center.z(), gbs_radius);
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// dump vertex list
|
||||
fprintf(fp, "# vertex list\n");
|
||||
for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
p = wgs84_nodes[i] - gbs_center;
|
||||
|
||||
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fprintf(fp, "# vertex normal list\n");
|
||||
for ( int i = 0; i < (int)normals.size(); ++i ) {
|
||||
p = normals[i];
|
||||
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// dump texture coordinates
|
||||
fprintf(fp, "# texture coordinate list\n");
|
||||
for ( int i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
p = texcoords[i];
|
||||
fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// dump triangle groups
|
||||
fprintf(fp, "# triangle groups\n");
|
||||
|
||||
int start = 0;
|
||||
int end = 1;
|
||||
string material;
|
||||
while ( start < (int)strip_materials.size() ) {
|
||||
// find next group
|
||||
material = strip_materials[start];
|
||||
while ( (end < (int)strip_materials.size()) &&
|
||||
(material == strip_materials[end]) )
|
||||
{
|
||||
// cout << "end = " << end << endl;
|
||||
end++;
|
||||
}
|
||||
// cout << "group = " << start << " to " << end - 1 << endl;
|
||||
|
||||
// make a list of points for the group
|
||||
point_list group_nodes;
|
||||
group_nodes.clear();
|
||||
Point3D bs_center;
|
||||
double bs_radius;
|
||||
for ( int i = start; i < end; ++i ) {
|
||||
for ( int j = 0; j < (int)strips_v[i].size(); ++j ) {
|
||||
group_nodes.push_back( wgs84_nodes[ strips_v[i][j] ] );
|
||||
bs_center = calc_center( group_nodes );
|
||||
bs_radius = calc_bounding_radius( bs_center, group_nodes );
|
||||
}
|
||||
}
|
||||
|
||||
// write group headers
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "# usemtl %s\n", material.c_str());
|
||||
fprintf(fp, "# bs %.4f %.4f %.4f %.2f\n",
|
||||
bs_center.x(), bs_center.y(), bs_center.z(), bs_radius);
|
||||
|
||||
// write groups
|
||||
for ( int i = start; i < end; ++i ) {
|
||||
fprintf(fp, "ts");
|
||||
for ( int j = 0; j < (int)strips_v[i].size(); ++j ) {
|
||||
fprintf(fp, " %d/%d", strips_v[i][j], strips_tc[i][j] );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
start = end;
|
||||
end = start + 1;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
command = "gzip --force --best " + file;
|
||||
system(command.c_str());
|
||||
}
|
||||
|
||||
|
||||
// update index
|
||||
void write_index(const string& base, const FGBucket& b, const string& name) {
|
||||
string dir = base + "/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + dir;
|
||||
system(command.c_str());
|
||||
|
||||
string file = dir + "/" + b.gen_index_str() + ".ind";
|
||||
// string file = dir + "/" + name;
|
||||
cout << "Output file = " << file << endl;
|
||||
|
||||
FILE *fp;
|
||||
if ( (fp = fopen( file.c_str(), "a" )) == NULL ) {
|
||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf( fp, "OBJECT %s\n", name.c_str() );
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
|
||||
void write_boundary( const string& base, const FGBucket& b,
|
||||
const FGPolygon& bounds, long int p_index )
|
||||
{
|
||||
Point3D p;
|
||||
|
||||
string dir = base + "/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + dir;
|
||||
system(command.c_str());
|
||||
|
||||
string file = dir + "/" + b.gen_index_str();
|
||||
|
||||
char poly_index[256];
|
||||
sprintf( poly_index, "%ld", p_index );
|
||||
file += ".";
|
||||
file += poly_index;
|
||||
|
||||
cout << "Output file = " << file << endl;
|
||||
|
||||
FILE *fp;
|
||||
if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
|
||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf( fp, "Hole\n" );
|
||||
|
||||
fprintf( fp, "%d\n", bounds.contours() );
|
||||
for ( int i = 0; i < bounds.contours(); ++i ) {
|
||||
fprintf( fp, "%d\n", bounds.contour_size(i) );
|
||||
fprintf( fp, "%d\n", bounds.get_hole_flag(i) );
|
||||
for ( int j = 0; j < bounds.contour_size(i); ++j ) {
|
||||
p = bounds.get_pt( i, j );
|
||||
fprintf( fp, "%.15f %.15f\n", p.x(), p.y() );
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
|
||||
// strip trailing spaces
|
||||
static void my_chomp( string& str ) {
|
||||
cout << "my_chomp()" << endl;
|
||||
|
@ -762,7 +395,7 @@ static void my_chomp( string& str ) {
|
|||
void build_airport( string airport_raw, string_list& runways_raw,
|
||||
const string& root ) {
|
||||
|
||||
poly_list rwy_nodes, rwy_strips, rwy_txs;
|
||||
poly_list rwy_polys, rwy_tris, rwy_txs;
|
||||
FGPolygon runway, runway_a, runway_b, result, result_a, result_b;
|
||||
FGPolygon base;
|
||||
point_list apt_pts;
|
||||
|
@ -888,12 +521,12 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
}
|
||||
|
||||
result_a = polygon_diff( runway_a, accum );
|
||||
rwy_nodes.push_back( result_a );
|
||||
rwy_polys.push_back( result_a );
|
||||
cout << "result_a = " << result_a.contours() << endl;
|
||||
accum = polygon_union( runway_a, accum );
|
||||
|
||||
result_b = polygon_diff( runway_b, accum );
|
||||
rwy_nodes.push_back( result_b );
|
||||
rwy_polys.push_back( result_b );
|
||||
cout << "result_b = " << result_b.contours() << endl;
|
||||
accum = polygon_union( runway_b, accum );
|
||||
|
||||
|
@ -921,7 +554,7 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
}
|
||||
}
|
||||
|
||||
base = gen_runway_area( runways[i], 1.01, 1.5 );
|
||||
base = gen_runway_area( runways[i], 1.05, 1.5 );
|
||||
|
||||
// add base to apt_pts (for convex hull of airport area)
|
||||
for ( int j = 0; j < base.contour_size( 0 ); ++j ) {
|
||||
|
@ -938,26 +571,28 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
|
||||
// generate convex hull
|
||||
FGPolygon hull = convex_hull(apt_pts);
|
||||
FGPolygon base_nodes = polygon_diff( hull, accum );
|
||||
FGPolygon base_poly = polygon_diff( hull, accum );
|
||||
|
||||
// add segments to polygons to remove any possible "T"
|
||||
// intersections
|
||||
FGTriNodes tmp_nodes;
|
||||
|
||||
// build temporary node list
|
||||
for ( int k = 0; k < (int)rwy_nodes.size(); ++k ) {
|
||||
for ( int i = 0; i < rwy_nodes[k].contours(); ++i ) {
|
||||
for ( int j = 0; j < rwy_nodes[k].contour_size( i ); ++j ) {
|
||||
tmp_nodes.unique_add( rwy_nodes[k].get_pt(i, j) );
|
||||
for ( int k = 0; k < (int)rwy_polys.size(); ++k ) {
|
||||
for ( int i = 0; i < rwy_polys[k].contours(); ++i ) {
|
||||
for ( int j = 0; j < rwy_polys[k].contour_size( i ); ++j ) {
|
||||
tmp_nodes.unique_add( rwy_polys[k].get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < base_nodes.contours(); ++i ) {
|
||||
for ( int j = 0; j < base_nodes.contour_size( i ); ++j ) {
|
||||
tmp_nodes.unique_add( base_nodes.get_pt(i, j) );
|
||||
for ( int i = 0; i < base_poly.contours(); ++i ) {
|
||||
for ( int j = 0; j < base_poly.contour_size( i ); ++j ) {
|
||||
tmp_nodes.unique_add( base_poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// dump info for debugging purposes
|
||||
point_list ttt = tmp_nodes.get_node_list();
|
||||
for ( int i = 0; i < (int)ttt.size(); ++i ) {
|
||||
char name[256];
|
||||
|
@ -967,44 +602,53 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
fclose(fp);
|
||||
}
|
||||
|
||||
for ( int i = 0; i < base_nodes.contours(); ++i ) {
|
||||
for ( int i = 0; i < base_poly.contours(); ++i ) {
|
||||
char name[256];
|
||||
sprintf(name, "l%d", i );
|
||||
FILE *fp = fopen( name, "w" );
|
||||
|
||||
for ( int j = 0; j < base_nodes.contour_size( i ) - 1; ++j ) {
|
||||
Point3D p0 = base_nodes.get_pt(i, j);
|
||||
Point3D p1 = base_nodes.get_pt(i, j + 1);
|
||||
for ( int j = 0; j < base_poly.contour_size( i ) - 1; ++j ) {
|
||||
Point3D p0 = base_poly.get_pt(i, j);
|
||||
Point3D p1 = base_poly.get_pt(i, j + 1);
|
||||
fprintf(fp, "%.8f %.8f\n", p0.x(), p0.y());
|
||||
fprintf(fp, "%.8f %.8f\n", p1.x(), p1.y());
|
||||
}
|
||||
Point3D p0 = base_nodes.get_pt(i, base_nodes.contour_size( i ) - 1);
|
||||
Point3D p1 = base_nodes.get_pt(i, 0);
|
||||
Point3D p0 = base_poly.get_pt(i, base_poly.contour_size( i ) - 1);
|
||||
Point3D p1 = base_poly.get_pt(i, 0);
|
||||
fprintf(fp, "%.8f %.8f\n", p0.x(), p0.y());
|
||||
fprintf(fp, "%.8f %.8f\n", p1.x(), p1.y());
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( int k = 0; k < (int)rwy_nodes.size(); ++k ) {
|
||||
rwy_nodes[k] = add_nodes_to_poly( rwy_nodes[k], tmp_nodes );
|
||||
for ( int k = 0; k < (int)rwy_polys.size(); ++k ) {
|
||||
rwy_polys[k] = add_nodes_to_poly( rwy_polys[k], tmp_nodes );
|
||||
}
|
||||
base_nodes = add_nodes_to_poly( base_nodes, tmp_nodes );
|
||||
|
||||
// new stripper approach
|
||||
cout << "Ready to try new striper" << endl;
|
||||
cout << "First calculate a 'point inside' for each contour and hole"
|
||||
<< endl;
|
||||
write_polygon( base_nodes, "base" );
|
||||
base_poly = add_nodes_to_poly( base_poly, tmp_nodes );
|
||||
|
||||
/* 1 */ calc_points_inside( base_nodes );
|
||||
for ( int i = 0; i < base_nodes.contours(); ++i ) {
|
||||
cout << base_nodes.get_point_inside( i ) << endl;
|
||||
// tesselate the polygons and prepair them for final output
|
||||
|
||||
cout << "Tesselating all polygons" << endl;
|
||||
|
||||
for ( int i = 0; i < (int)runways.size(); ++i ) {
|
||||
FGPolygon tri_a, tri_b, tc_a, tc_b;
|
||||
|
||||
tri_a = polygon_tesselate_alt( rwy_polys[2 * i] );
|
||||
tc_a = rwy_calc_tex_coords( runways[i], 0.0, tri_a );
|
||||
rwy_tris.push_back( tri_a );
|
||||
rwy_txs.push_back( tc_a );
|
||||
|
||||
tri_b = polygon_tesselate_alt( rwy_polys[2 * i + 1] );
|
||||
tc_b = rwy_calc_tex_coords( runways[i], 180.0, tri_b );
|
||||
rwy_tris.push_back( tri_b );
|
||||
rwy_txs.push_back( tc_b );
|
||||
}
|
||||
/* 2 */ triele_list base_tris = polygon_tesselate( base_nodes, -1 );
|
||||
|
||||
// generate convex hull and strip version
|
||||
FGPolygon base_strips = polygon_to_tristrip( base_nodes );
|
||||
write_polygon( base_poly, "base" );
|
||||
FGPolygon base_tris = polygon_tesselate_alt( base_poly );
|
||||
|
||||
#if 0
|
||||
// dump more debugging output
|
||||
for ( int i = 0; i < base_strips.contours(); ++i ) {
|
||||
char name[256];
|
||||
sprintf(name, "s%d", i );
|
||||
|
@ -1022,83 +666,69 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
fprintf(fp, "%.8f %.8f\n", p1.x(), p1.y());
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// generate strips and texture coordinates
|
||||
for ( int i = 0; i < (int)runways.size(); ++i ) {
|
||||
FGPolygon strip_a, strip_b, tc_a, tc_b;
|
||||
|
||||
strip_a = polygon_to_tristrip( rwy_nodes[2 * i] );
|
||||
tc_a = rwy_calc_tex_coords( runways[i], 0.0, strip_a );
|
||||
rwy_strips.push_back( strip_a );
|
||||
rwy_txs.push_back( tc_a );
|
||||
|
||||
strip_b = polygon_to_tristrip( rwy_nodes[2 * i + 1] );
|
||||
tc_b = rwy_calc_tex_coords( runways[i], 180.0, strip_b );
|
||||
rwy_strips.push_back( strip_b );
|
||||
rwy_txs.push_back( tc_b );
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// We should now have the runway polygons all generated with their
|
||||
// corresponding strips and texture coordinates, and the
|
||||
// corresponding triangles and texture coordinates, and the
|
||||
// surrounding base area.
|
||||
//
|
||||
// Next we need to create the output lists ... vertices, normals,
|
||||
// texture coordinates, and tri-strips
|
||||
//
|
||||
|
||||
// traverse the strip list and create ordered node and texture
|
||||
// traverse the tri list and create ordered node and texture
|
||||
// coordinate lists
|
||||
|
||||
FGTriNodes nodes, texcoords;
|
||||
nodes.clear();
|
||||
texcoords.clear();
|
||||
|
||||
group_list strips_v; strips_v.clear();
|
||||
group_list strips_tc; strips_tc.clear();
|
||||
string_list strip_materials; strip_materials.clear();
|
||||
group_list tris_v; tris_v.clear();
|
||||
group_list tris_tc; tris_tc.clear();
|
||||
string_list tri_materials; tri_materials.clear();
|
||||
|
||||
Point3D tc;
|
||||
int index;
|
||||
int_list strip_v;
|
||||
int_list strip_tc;
|
||||
int_list tri_v;
|
||||
int_list tri_tc;
|
||||
|
||||
for ( int k = 0; k < (int)rwy_strips.size(); ++k ) {
|
||||
cout << "strip " << k << endl;
|
||||
FGPolygon strip_poly = rwy_strips[k];
|
||||
for ( int i = 0; i < strip_poly.contours(); ++i ) {
|
||||
strip_v.clear();
|
||||
strip_tc.clear();
|
||||
for ( int j = 0; j < strip_poly.contour_size(i); ++j ) {
|
||||
p = strip_poly.get_pt( i, j );
|
||||
for ( int k = 0; k < (int)rwy_tris.size(); ++k ) {
|
||||
cout << "tri " << k << endl;
|
||||
FGPolygon tri_poly = rwy_tris[k];
|
||||
for ( int i = 0; i < tri_poly.contours(); ++i ) {
|
||||
tri_v.clear();
|
||||
tri_tc.clear();
|
||||
for ( int j = 0; j < tri_poly.contour_size(i); ++j ) {
|
||||
p = tri_poly.get_pt( i, j );
|
||||
index = nodes.unique_add( p );
|
||||
strip_v.push_back( index );
|
||||
tri_v.push_back( index );
|
||||
tc = rwy_txs[k].get_pt( i, j );
|
||||
index = texcoords.unique_add( tc );
|
||||
strip_tc.push_back( index );
|
||||
tri_tc.push_back( index );
|
||||
}
|
||||
strips_v.push_back( strip_v );
|
||||
strips_tc.push_back( strip_tc );
|
||||
strip_materials.push_back( "Concrete" );
|
||||
tris_v.push_back( tri_v );
|
||||
tris_tc.push_back( tri_tc );
|
||||
tri_materials.push_back( "Concrete" );
|
||||
}
|
||||
}
|
||||
|
||||
// add base points
|
||||
point_list base_txs;
|
||||
int_list base_tc;
|
||||
for ( int i = 0; i < base_strips.contours(); ++i ) {
|
||||
strip_v.clear();
|
||||
strip_tc.clear();
|
||||
for ( int j = 0; j < base_strips.contour_size(i); ++j ) {
|
||||
p = base_strips.get_pt( i, j );
|
||||
for ( int i = 0; i < base_tris.contours(); ++i ) {
|
||||
tri_v.clear();
|
||||
tri_tc.clear();
|
||||
for ( int j = 0; j < base_tris.contour_size(i); ++j ) {
|
||||
p = base_tris.get_pt( i, j );
|
||||
index = nodes.unique_add( p );
|
||||
strip_v.push_back( index );
|
||||
tri_v.push_back( index );
|
||||
}
|
||||
strips_v.push_back( strip_v );
|
||||
strip_materials.push_back( "Grass" );
|
||||
tris_v.push_back( tri_v );
|
||||
tri_materials.push_back( "Grass" );
|
||||
|
||||
base_txs.clear();
|
||||
base_txs = calc_tex_coords( b, nodes.get_node_list(), strip_v );
|
||||
base_txs = calc_tex_coords( b, nodes.get_node_list(), tri_v );
|
||||
|
||||
base_tc.clear();
|
||||
for ( int j = 0; j < (int)base_txs.size(); ++j ) {
|
||||
|
@ -1107,11 +737,12 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
index = texcoords.simple_add( tc );
|
||||
base_tc.push_back( index );
|
||||
}
|
||||
strips_tc.push_back( base_tc );
|
||||
tris_tc.push_back( base_tc );
|
||||
}
|
||||
|
||||
// calculate node elevations
|
||||
point_list geod_nodes = calc_elevations( root, nodes.get_node_list() );
|
||||
cout << "Done with calc_elevations()" << endl;
|
||||
|
||||
// calculate wgs84 mapping of nodes
|
||||
point_list wgs84_nodes;
|
||||
|
@ -1122,10 +753,11 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
wgs84_nodes.push_back( fgGeodToCart( p ) );
|
||||
}
|
||||
double gbs_radius = calc_bounding_radius( gbs_center, wgs84_nodes );
|
||||
cout << "Done with wgs84 node mapping" << endl;
|
||||
|
||||
// calculate normal(s) for this airport
|
||||
p.setx( rwy_strips[0].get_pt(0, 0).x() * DEG_TO_RAD );
|
||||
p.sety( rwy_strips[0].get_pt(0, 0).y() * DEG_TO_RAD );
|
||||
p.setx( base_tris.get_pt(0, 0).x() * DEG_TO_RAD );
|
||||
p.sety( base_tris.get_pt(0, 0).y() * DEG_TO_RAD );
|
||||
p.setz( 0 );
|
||||
Point3D tmp = fgGeodToCart( p );
|
||||
// cout << "geod = " << p << endl;
|
||||
|
@ -1139,20 +771,27 @@ void build_airport( string airport_raw, string_list& runways_raw,
|
|||
for ( int i = 0; i < (int)nodes.size(); ++i ) {
|
||||
normals.push_back( Point3D( vn[0], vn[1], vn[2] ) );
|
||||
}
|
||||
cout << "found normal for this airport = " << tmp << endl;
|
||||
|
||||
// null structures
|
||||
group_list fans_v; fans_v.clear();
|
||||
group_list fans_tc; fans_tc.clear();
|
||||
string_list fan_materials;
|
||||
fan_materials.clear();
|
||||
string_list fan_materials; fan_materials.clear();
|
||||
|
||||
// null structures
|
||||
group_list strips_v; strips_v.clear();
|
||||
group_list strips_tc; strips_tc.clear();
|
||||
string_list strip_materials; strip_materials.clear();
|
||||
|
||||
string objpath = root + "/AirportObj";
|
||||
string name = apt_code;
|
||||
|
||||
write( objpath, b, name, gbs_center, gbs_radius,
|
||||
wgs84_nodes, normals,
|
||||
texcoords.get_node_list(),
|
||||
strips_v, strips_tc, strip_materials,
|
||||
fans_v, fans_tc, fan_materials );
|
||||
write_obj( objpath, b, name, gbs_center, gbs_radius,
|
||||
wgs84_nodes, normals,
|
||||
texcoords.get_node_list(),
|
||||
tris_v, tris_tc, tri_materials,
|
||||
strips_v, strips_tc, strip_materials,
|
||||
fans_v, fans_tc, fan_materials );
|
||||
|
||||
write_index( objpath, b, name );
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ FGPolygon gen_area(Point3D origin, double angle, const FGPolygon& cart_list) {
|
|||
// cout << "Rotating points by " << angle << endl;
|
||||
for ( int i = 0; i < rad_list.contour_size( 0 ); ++i) {
|
||||
p = rad_list.get_pt( 0, i );
|
||||
double theta = p.y() - angle;
|
||||
double theta = p.y() + angle;
|
||||
while ( theta < FG_2PI ) {
|
||||
theta += FG_2PI;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue