]> git.mxchange.org Git - flightgear.git/blobdiff - Airports/genapt.cxx
Optimizations from Norman Vine.
[flightgear.git] / Airports / genapt.cxx
index 1d78771c372c721df22da757f91c5cf8ecb1c204..22ad167367c8488c789a00b88581ce8f2fe7f5f0 100644 (file)
@@ -1,5 +1,5 @@
 //
-// getapt.cxx -- generate airport scenery from the given definition file
+// genapt.cxx -- generate airport scenery from the given definition file
 //
 // Written by Curtis Olson, started September 1998.
 //
 using namespace std;
 #endif
 
-#include <Debug/fg_debug.h>
-#include <Include/fg_types.h>
-#include <Math/fg_geodesy.h>
+#ifdef __BORLANDC__
+#  define exception c_exception
+#endif
+#include <math.h>
+
+#include <Debug/logstream.hxx>
+// #include <Include/fg_types.h>
+#include <Math/fg_geodesy.hxx>
 #include <Math/mat3.h>
+#include <Math/point3d.hxx>
 #include <Math/polar3d.hxx>
 #include <Misc/fgstream.hxx>
 #include <Objects/material.hxx>
@@ -44,96 +50,31 @@ using namespace std;
 #include "genapt.hxx"
 
 
-typedef vector < fgPoint3d > container;
+typedef vector < Point3D > container;
 typedef container::iterator iterator;
 typedef container::const_iterator const_iterator;
 
 
-// Calculate distance between to fgPoint3d's
-static double calc_dist(const fgPoint3d& p1, const fgPoint3d& p2) {
-    double x, y, z;
-    x = p1.x - p2.x;
-    y = p1.y - p2.y;
-    z = p1.z - p2.z;
-    return sqrt(x*x + y*y + z*z);
-}
-
-
-// convert a geodetic point lon(degrees), lat(degrees), elev(meter) to a
-// cartesian point
-static fgPoint3d geod_to_cart(fgPoint3d geod) {
-    fgPoint3d cart;
-    fgPoint3d geoc;
-    double sl_radius;
-
-    // printf("A geodetic point is (%.2f, %.2f, %.2f)\n", geod[0],
-    //        geod[1], geod[2]);
-
-    geoc.lon = geod.lon*DEG_TO_RAD;
-    fgGeodToGeoc(geod.lat*DEG_TO_RAD, geod.radius, &sl_radius, &geoc.lat);
-
-    // printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon, 
-    //        gc_lat, sl_radius+geod[2]); */
-
-    geoc.radius = sl_radius + geod.radius;
-    cart = fgPolarToCart3d(geoc);
-    
-    // printf("A cart point is (%.8f, %.8f, %.8f)\n", cp.x, cp.y, cp.z);
-
-    return cart;
-}
-
-
 #define FG_APT_BASE_TEX_CONSTANT 2000.0
 
-#ifdef OLD_TEX_COORDS
 // Calculate texture coordinates for a given point.
-static fgPoint3d
-calc_tex_coords(const fgPoint3d& p) {
-    fgPoint3d tex;
-
-    cout << "Texture coordinates = " << 
-       FG_APT_BASE_TEX_CONSTANT * p.lon << "  " << 
-       FG_APT_BASE_TEX_CONSTANT * p.lat << "\n";
-
-    tex.x = fmod(FG_APT_BASE_TEX_CONSTANT * p.lon, 10.0);
-    tex.y = fmod(FG_APT_BASE_TEX_CONSTANT * p.lat, 10.0);
-
-    if ( tex.x < 0.0 ) {
-       tex.x += 10.0;
-    }
-
-    if ( tex.y < 0.0 ) {
-       tex.y += 10.0;
-    }
+static Point3D calc_tex_coords(double *node, const Point3D& ref) {
+    Point3D cp;
+    Point3D pp;
 
-    cout << "Texture coordinates = " << tex.x << "  " << tex.y << "\n";
-
-    return tex;
-}
-#endif
-
-
-// Calculate texture coordinates for a given point.
-static fgPoint3d calc_tex_coords(double *node, fgPoint3d *ref) {
-    fgPoint3d cp;
-    fgPoint3d pp;
-
-    cp.x = node[0] + ref->x; 
-    cp.y = node[1] + ref->y;
-    cp.z = node[2] + ref->z;
+    cp = Point3D( node[0] + ref.x(), node[1] + ref.y(), node[2] + ref.z() );
 
     pp = fgCartToPolar3d(cp);
 
-    pp.lon = fmod(FG_APT_BASE_TEX_CONSTANT * pp.lon, 10.0);
-    pp.lat = fmod(FG_APT_BASE_TEX_CONSTANT * pp.lat, 10.0);
+    pp.setx( fmod(FG_APT_BASE_TEX_CONSTANT * pp.x(), 10.0) );
+    pp.sety( fmod(FG_APT_BASE_TEX_CONSTANT * pp.y(), 10.0) );
 
-    if ( pp.lon < 0.0 ) {
-       pp.lon += 10.0;
+    if ( pp.x() < 0.0 ) {
+       pp.setx( pp.x() + 10.0 );
     }
 
-    if ( pp.lat < 0.0 ) {
-       pp.lat += 10.0;
+    if ( pp.y() < 0.0 ) {
+       pp.sety( pp.y() + 10.0 );
     }
 
     return(pp);
@@ -142,10 +83,10 @@ static fgPoint3d calc_tex_coords(double *node, fgPoint3d *ref) {
 
 // generate the actual base area for the airport
 static void
-gen_base( const fgPoint3d& average, const container& perimeter, fgTILE *t)
+gen_base( const Point3D& average, const container& perimeter, fgTILE *t)
 {
     GLint display_list;
-    fgPoint3d ave_cart, cart, cart_trans, tex;
+    Point3D cart, cart_trans, tex;
     MAT3vec normal;
     double dist, max_dist, temp;
     int center_num, i;
@@ -154,32 +95,30 @@ gen_base( const fgPoint3d& average, const container& perimeter, fgTILE *t)
 
     max_dist = 0.0;
 
-    cout << "generating airport base for size = " << perimeter.size() << "\n";
+    FG_LOG( FG_TERRAIN, FG_INFO, 
+           "generating airport base for size = " << perimeter.size() );
 
     fragment.init();
     fragment.tile_ptr = t;
 
     // find airport base material in the properties list
     if ( ! material_mgr.find( APT_BASE_MATERIAL, fragment.material_ptr )) {
-       fgPrintf( FG_TERRAIN, FG_ALERT, 
-                 "Ack! unknown material name = %s in fgAptGenerat()\n",
-                 APT_BASE_MATERIAL );
+       FG_LOG( FG_TERRAIN, FG_ALERT, 
+               "Ack! unknown material name = " << APT_BASE_MATERIAL 
+               << " in fgAptGenerat()" );
     }
 
-    ave_cart = geod_to_cart( average );
-    printf(" tile center = %.2f %.2f %.2f\n", 
-          t->center.x, t->center.y, t->center.z);
-    printf(" airport center = %.2f %.2f %.2f\n", 
-          average.x, average.y, average.z);
-    printf(" airport center = %.2f %.2f %.2f\n", 
-          ave_cart.x, ave_cart.y, ave_cart.z);
-    fragment.center.x = ave_cart.x;
-    fragment.center.y = ave_cart.y;
-    fragment.center.z = ave_cart.z;
-
-    normal[0] = ave_cart.x;
-    normal[1] = ave_cart.y;
-    normal[2] = ave_cart.z;
+    FG_LOG( FG_TERRAIN, FG_INFO, 
+           " tile center = " 
+           << t->center.x() << " " << t->center.y() << " " << t->center.z() );
+    FG_LOG( FG_TERRAIN, FG_INFO, 
+           " airport center = "
+           << average.x() << " " << average.y() << " " << average.z() );
+    fragment.center = average;
+
+    normal[0] = average.x();
+    normal[1] = average.y();
+    normal[2] = average.z();
     MAT3_NORMALIZE_VEC(normal, temp);
     
     display_list = xglGenLists(1);
@@ -187,80 +126,72 @@ gen_base( const fgPoint3d& average, const container& perimeter, fgTILE *t)
     xglBegin(GL_TRIANGLE_FAN);
 
     // first point center of fan
-    cart_trans.x = ave_cart.x - t->center.x;
-    cart_trans.y = ave_cart.y - t->center.y;
-    cart_trans.z = ave_cart.z - t->center.z;
-    t->nodes[t->ncount][0] = cart_trans.x;
-    t->nodes[t->ncount][1] = cart_trans.y;
-    t->nodes[t->ncount][2] = cart_trans.z;
+    cart_trans = average - t->center;
+    t->nodes[t->ncount][0] = cart_trans.x();
+    t->nodes[t->ncount][1] = cart_trans.y();
+    t->nodes[t->ncount][2] = cart_trans.z();
     center_num = t->ncount;
     t->ncount++;
 
-    tex = calc_tex_coords( t->nodes[t->ncount-1], &(t->center) );
-    xglTexCoord2f(tex.x, tex.y);
+    tex = calc_tex_coords( t->nodes[t->ncount-1], t->center );
+    xglTexCoord2f(tex.x(), tex.y());
     xglNormal3dv(normal);
     xglVertex3dv(t->nodes[t->ncount-1]);
 
     // first point on perimeter
-    iterator current = perimeter.begin();
-    cart = geod_to_cart( *current );
-    cart_trans.x = cart.x - t->center.x;
-    cart_trans.y = cart.y - t->center.y;
-    cart_trans.z = cart.z - t->center.z;
-    t->nodes[t->ncount][0] = cart_trans.x;
-    t->nodes[t->ncount][1] = cart_trans.y;
-    t->nodes[t->ncount][2] = cart_trans.z;
+    const_iterator current = perimeter.begin();
+    cart = fgGeodToCart( *current );
+    cart_trans = cart - t->center;
+    t->nodes[t->ncount][0] = cart_trans.x();
+    t->nodes[t->ncount][1] = cart_trans.y();
+    t->nodes[t->ncount][2] = cart_trans.z();
     t->ncount++;
 
     i = 1;
-    tex = calc_tex_coords( t->nodes[i], &(t->center) );
-    dist = calc_dist(ave_cart, cart);
+    tex = calc_tex_coords( t->nodes[i], t->center );
+    dist = cart.distance3Dsquared(average);
     if ( dist > max_dist ) {
        max_dist = dist;
     }
-    xglTexCoord2f(tex.x, tex.y);
+    xglTexCoord2f(tex.x(), tex.y());
     xglVertex3dv(t->nodes[i]);
     ++current;
     ++i;
 
     const_iterator last = perimeter.end();
     for ( ; current != last; ++current ) {
-       cart = geod_to_cart( *current );
-       cart_trans.x = cart.x - t->center.x;
-       cart_trans.y = cart.y - t->center.y;
-       cart_trans.z = cart.z - t->center.z;
-       t->nodes[t->ncount][0] = cart_trans.x;
-       t->nodes[t->ncount][1] = cart_trans.y;
-       t->nodes[t->ncount][2] = cart_trans.z;
+       cart = fgGeodToCart( *current );
+       cart_trans = cart - t->center;
+       t->nodes[t->ncount][0] = cart_trans.x();
+       t->nodes[t->ncount][1] = cart_trans.y();
+       t->nodes[t->ncount][2] = cart_trans.z();
        t->ncount++;
        fragment.add_face(center_num, i - 1, i);
 
-       tex = calc_tex_coords( t->nodes[i], &(t->center) );
-       dist = calc_dist(ave_cart, cart);
+       tex = calc_tex_coords( t->nodes[i], t->center );
+       dist = cart.distance3Dsquared(average);
        if ( dist > max_dist ) {
            max_dist = dist;
        }
-       xglTexCoord2f(tex.x, tex.y);
+       xglTexCoord2f(tex.x(), tex.y());
        xglVertex3dv(t->nodes[i]);
        i++;
     }
 
     // last point (first point in perimeter list)
     current = perimeter.begin();
-    cart = geod_to_cart( *current );
-    cart_trans.x = cart.x - t->center.x;
-    cart_trans.y = cart.y - t->center.y;
-    cart_trans.z = cart.z - t->center.z;
+    cart = fgGeodToCart( *current );
+    cart_trans = cart - t->center;
     fragment.add_face(center_num, i - 1, 1);
 
-    tex = calc_tex_coords( t->nodes[1], &(t->center) );
-    xglTexCoord2f(tex.x, tex.y);
+    tex = calc_tex_coords( t->nodes[1], t->center );
+    xglTexCoord2f(tex.x(), tex.y());
     xglVertex3dv(t->nodes[1]);
 
     xglEnd();
     xglEndList();
 
-    fragment.bounding_radius = max_dist;
+    fragment.bounding_radius = sqrt(max_dist);
     fragment.display_list = display_list;
 
     t->fragment_list.push_back(fragment);
@@ -275,10 +206,12 @@ fgAptGenerate(const string& path, fgTILE *tile)
     string token;
     string apt_id, apt_name;
     char c;
+    int i = 1;
 
     // face list (this indexes into the master tile vertex list)
     container perimeter;
-    fgPoint3d p, average;
+    Point3D p, average;
+    double avex = 0.0, avey = 0.0, avez = 0.0;
     int size;
 
     // gpc_vertex p_2d, list_2d[MAX_PERIMETER];
@@ -294,10 +227,10 @@ fgAptGenerate(const string& path, fgTILE *tile)
     apt_id = "";
 
     // read in each line of the file
-    in.eat_comments();
+    in >> skipcomment;
     while ( ! in.eof() )
     {
-       in.stream() >> token;
+       in >> token;
 
        if ( token == "a" ) {
            // airport info record (start of airport)
@@ -308,44 +241,46 @@ fgAptGenerate(const string& path, fgTILE *tile)
                gen_base(average, perimeter, tile);
            }
 
-           cout << "Reading airport record\n";
-           in.stream() >> apt_id;
+           FG_LOG( FG_TERRAIN, FG_INFO, "Reading airport record" );
+           in >> apt_id;
            apt_name = "";
-           average.lon = average.lat = average.radius = 0.0;
+           i = 1;
+           avex = avey = avez = 0.0;
            perimeter.erase( perimeter.begin(), perimeter.end() );
            // skip to end of line.
            while ( in.get(c) && c != '\n' ) {
                apt_name += c;
            }
-           cout << "\tID = " + apt_id + "  Name = " + apt_name + "\n";
+           FG_LOG( FG_TERRAIN, FG_INFO, 
+                   "\tID = " << apt_id << "  Name = " << apt_name );
        } else if ( token == "p" ) {
            // airport area bounding polygon coordinate.  These
            // specify a convex hull that should already have been cut
            // out of the base terrain.  The points are given in
            // counter clockwise order and are specified in lon/lat
            // degrees.
-           in.stream() >> p.lon >> p.lat >> p.radius;
-           average.lon += p.lon;
-           average.lat += p.lat;
-           average.radius += p.radius;
+           in >> p;
+           avex += tile->nodes[i][0];
+           avey += tile->nodes[i][1];
+           avez += tile->nodes[i][2];
            perimeter.push_back(p);
+           ++i;
        } else if ( token == "r" ) {
            // runway record
            // skip for now
            while ( in.get(c) && c != '\n' );
        }
 
-       // airports.insert(a);
-       in.eat_comments();
+       in >> skipcomment;
     }
 
     if ( apt_id != "" ) {
        // we have just finished reading and airport record.
        // process the info
        size = perimeter.size();
-       average.lon /= (double)size;
-       average.lat /= (double)size;
-       average.radius /= (double)size;
+       average = Point3D( avex / (double)size + tile->center.x(),
+                          avey / (double)size + tile->center.y(),
+                          avez / (double)size + tile->center.z() );
 
        gen_base(average, perimeter, tile);
     }
@@ -355,6 +290,41 @@ fgAptGenerate(const string& path, fgTILE *tile)
 
 
 // $Log$
+// Revision 1.12  1999/02/01 21:08:33  curt
+// Optimizations from Norman Vine.
+//
+// Revision 1.11  1998/11/23 21:48:09  curt
+// Borland portability tweaks.
+//
+// Revision 1.10  1998/11/07 19:07:06  curt
+// Enable release builds using the --without-logging option to the configure
+// script.  Also a couple log message cleanups, plus some C to C++ comment
+// conversion.
+//
+// Revision 1.9  1998/11/06 21:17:32  curt
+// Converted to new logstream debugging facility.  This allows release
+// builds with no messages at all (and no performance impact) by using
+// the -DFG_NDEBUG flag.
+//
+// Revision 1.8  1998/11/06 14:46:59  curt
+// Changes to track Bernie's updates to fgstream.
+//
+// Revision 1.7  1998/10/20 18:26:06  curt
+// Updates to point3d.hxx
+//
+// Revision 1.6  1998/10/18 01:17:16  curt
+// Point3D tweaks.
+//
+// Revision 1.5  1998/10/16 23:27:14  curt
+// C++-ifying.
+//
+// Revision 1.4  1998/10/16 00:51:46  curt
+// Converted to Point3D class.
+//
+// Revision 1.3  1998/09/21 20:55:00  curt
+// Used the cartesian form of the airport area coordinates to determine the
+// center.
+//
 // Revision 1.2  1998/09/14 12:44:30  curt
 // Don't recalculate perimeter points since it is not likely that they will match
 // exactly with the previously calculated points, which will leave an ugly gap
@@ -363,5 +333,3 @@ fgAptGenerate(const string& path, fgTILE *tile)
 // Revision 1.1  1998/09/14 02:14:01  curt
 // Initial revision of genapt.[ch]xx for generating airport scenery.
 //
-//
-