]> git.mxchange.org Git - flightgear.git/commitdiff
Worked on creating data to output ... normals, bounding spheres, etc.
authorcurt <curt>
Tue, 23 Mar 1999 22:02:03 +0000 (22:02 +0000)
committercurt <curt>
Tue, 23 Mar 1999 22:02:03 +0000 (22:02 +0000)
GenOutput/genobj.cxx
GenOutput/genobj.hxx
Main/construct.cxx

index 634765d1d2691b8b5499183d25500743ba577ab2..06c5a07994b8260d2d52e8f04b5fbf22d7cd6c07 100644 (file)
 // (Log is kept at end of this file)
 
 
+#include <time.h>
+
+#include <Tools/scenery_version.hxx>
+#include <Math/mat3.h>
+
 #include "genobj.hxx"
 
 
-// Calculate the global bounding sphere from all the input points.
-// Center is the average of the points.
-static void calc_gbs( const trinode_list& nodelist, Point3D *center, 
-                     double *radius )
-{
+// build the wgs-84 point list
+void FGGenOutput::gen_wgs84_points() {
+    cout << "calculating wgs84 point" << endl;
+    Point3D geod, radians, cart;
+
+    const_point_list_iterator current = geod_nodes.begin();
+    const_point_list_iterator last = geod_nodes.end();
+
+    for ( ; current != last; ++current ) {
+       geod = *current;
+
+       // convert to radians
+       radians = Point3D( geod.x() * DEG_TO_RAD,
+                          geod.y() * DEG_TO_RAD,
+                          geod.z() );
+
+        cart = fgGeodToCart(radians);
+       // cout << cart << endl;
+        wgs84_nodes.push_back(cart);
+    }
+}
+
+
+// build the node -> element (triangle) reverse lookup table.  there
+// is an entry for each point containing a list of all the triangles
+// that share that point.
+void FGGenOutput::gen_node_ele_lookup_table() {
+    belongs_to ele_list;
+    ele_list.erase( ele_list.begin(), ele_list.end() );
+
+    // initialize reverse_ele_lookup structure by creating an empty
+    // list for each point
+    const_point_list_iterator w_current = wgs84_nodes.begin();
+    const_point_list_iterator w_last = wgs84_nodes.end();
+    for ( ; w_current != w_last; ++w_current ) {
+       reverse_ele_lookup.push_back( ele_list );
+    }
+
+    // traverse triangle structure building reverse lookup table
+    const_triele_list_iterator current = tri_elements.begin();
+    const_triele_list_iterator last = tri_elements.end();
+    int counter = 0;
+    for ( ; current != last; ++current ) {
+       reverse_ele_lookup[ current->get_n1() ].push_back( counter );
+       reverse_ele_lookup[ current->get_n2() ].push_back( counter );
+       reverse_ele_lookup[ current->get_n3() ].push_back( counter );
+       ++counter;
+    }
+}
+
+
+// caclulate the normal for the specified triangle face
+Point3D FGGenOutput::calc_normal( int i ) {
+    double v1[3], v2[3], normal[3];
+    double temp;
+
+    Point3D p1 = wgs84_nodes[ tri_elements[i].get_n1() ];
+    Point3D p2 = wgs84_nodes[ tri_elements[i].get_n2() ];
+    Point3D p3 = wgs84_nodes[ tri_elements[i].get_n3() ];
+
+    v1[0] = p2.x() - p1.x(); v1[1] = p2.y() - p1.y(); v1[2] = p2.z() - p1.z();
+    v2[0] = p3.x() - p1.x(); v2[1] = p3.y() - p1.y(); v2[2] = p3.z() - p1.z();
+
+    MAT3cross_product(normal, v1, v2);
+    MAT3_NORMALIZE_VEC(normal,temp);
+
+    return Point3D( normal[0], normal[1], normal[2] );
+}
+
+
+// build the face normal list
+void FGGenOutput::gen_face_normals() {
+    // traverse triangle structure building the face normal table
+
+    cout << "calculating face normals" << endl;
+
+    for ( int i = 0; i < (int)tri_elements.size(); i++ ) {
+       // cout << calc_normal( i ) << endl;
+       face_normals.push_back( calc_normal( i ) );
+    }
+
+}
+
+
+// calculate the normals for each point in wgs84_nodes
+void FGGenOutput::gen_normals() {
+    Point3D normal;
+    cout << "caculating node normals" << endl;
+
+    // for each node
+    for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
+       belongs_to tri_list = reverse_ele_lookup[i];
+
+       belongs_to_iterator current = tri_list.begin();
+       belongs_to_iterator last = tri_list.end();
+
+       Point3D average( 0.0 );
+
+       // for each triangle that shares this node
+       for ( ; current != last; ++current ) {
+           normal = face_normals[ *current ];
+           average += normal;
+           // cout << normal << endl;
+       }
+
+       average /= tri_list.size();
+       // cout << "average = " << average << endl;
+
+       point_normals.push_back( average );
+    }
+}
+
+
+// calculate the global bounding sphere.  Center is the average of the
+// points.
+void FGGenOutput::calc_gbs() {
     double x = 0;
     double y = 0;
     double z = 0;
@@ -38,8 +154,8 @@ static void calc_gbs( const trinode_list& nodelist, Point3D *center,
     double dist_squared;
     double radius_squared = 0;
     
-    const_trinode_list_iterator current = nodelist.begin();
-    const_trinode_list_iterator last = nodelist.end();
+    const_point_list_iterator current = wgs84_nodes.begin();
+    const_point_list_iterator last = wgs84_nodes.end();
 
     for ( ; current != last; ++current ) {
        x += current->x();
@@ -47,39 +163,163 @@ static void calc_gbs( const trinode_list& nodelist, Point3D *center,
        z += current->z();
     }
 
-    x /= nodelist.size();
-    y /= nodelist.size();
-    z /= nodelist.size();
+    x /= wgs84_nodes.size();
+    y /= wgs84_nodes.size();
+    z /= wgs84_nodes.size();
 
-    *center = Point3D(x, y, z);
+    gbs_center = Point3D(x, y, z);
 
-    current = nodelist.begin();
+    current =  wgs84_nodes.begin();
     for ( ; current != last; ++current ) {
-        dist_squared = center->distance3Dsquared(*current);
+        dist_squared = gbs_center.distance3Dsquared(*current);
        if ( dist_squared > radius_squared ) {
             radius_squared = dist_squared;
         }
     }
 
-    *radius = sqrt(radius_squared);
+    gbs_radius = sqrt(radius_squared);
 }
 
 
-// generate the flight gear format from the triangulation
-int fgGenOutput( const FGTriangle& t ) {
-    Point3D gbs;
-    double gradius;
-
+// build the necessary output structures based on the triangulation
+// data
+int FGGenOutput::build( const FGTriangle& t ) {
     FGTriNodes trinodes = t.get_out_nodes();
-    trinode_list nodelist = trinodes.get_node_list();
 
-    calc_gbs( nodelist, &gbs, &gradius );
-    cout << "center = " << gbs << " radius = " << gradius << endl;
+    // copy the geodetic node list into this class
+    geod_nodes = trinodes.get_node_list();
+
+    // copy the triangle list into this class
+    tri_elements = t.get_elelist();
+
+    // generate the point list in wgs-84 coordinates
+    gen_wgs84_points();
+
+    // calculate the global bounding sphere
+    calc_gbs();
+    cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
+
+    // build the node -> element (triangle) reverse lookup table
+    gen_node_ele_lookup_table();
+
+    // build the face normal list
+    gen_face_normals();
+
+    // calculate the normals for each point in wgs84_nodes
+    gen_normals();
+
+    return 1;
+}
+
+
+// caclulate the bounding sphere for the specified triangle face
+void FGGenOutput::calc_bounding_sphere( int i, Point3D *center, 
+                                       double *radius ) {
+    Point3D c( 0.0 );
+
+    Point3D p1 = wgs84_nodes[ tri_elements[i].get_n1() ];
+    Point3D p2 = wgs84_nodes[ tri_elements[i].get_n2() ];
+    Point3D p3 = wgs84_nodes[ tri_elements[i].get_n3() ];
+
+    c = p1 + p2 + p3;
+    c /= 3;
+
+    double dist_squared;
+    double max_squared = 0;
+
+    dist_squared = c.distance3Dsquared(p1);
+    if ( dist_squared > max_squared ) {
+       max_squared = dist_squared;
+    }
+
+    dist_squared = c.distance3Dsquared(p2);
+    if ( dist_squared > max_squared ) {
+       max_squared = dist_squared;
+    }
+
+    dist_squared = c.distance3Dsquared(p3);
+    if ( dist_squared > max_squared ) {
+       max_squared = dist_squared;
+    }
+
+    *center = c;
+    *radius = sqrt(max_squared);
+}
+
+
+// write out the fgfs scenery file
+int FGGenOutput::write( const string& path ) {
+    Point3D p;
+
+    FILE *fp;
+    if ( (fp = fopen( path.c_str(), "w" )) == NULL ) {
+       cout << "ERROR: opening " << path << " for writing!" << endl;
+       exit(-1);
+    }
+
+    // write headers
+    fprintf(fp, "# FGFS Scenery 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 spher
+    fprintf(fp, "# gbs %.5f %.5f %.5f %.2f\n",
+           gbs_center.x(), gbs_center.y(), gbs_center.z(), gbs_radius);
+    fprintf(fp, "\n");
+
+    // write nodes
+    fprintf(fp, "# vertex list\n");
+    const_point_list_iterator w_current = wgs84_nodes.begin();
+    const_point_list_iterator w_last = wgs84_nodes.end();
+    for ( ; w_current != w_last; ++w_current ) {
+       p = *w_current - gbs_center;
+       fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
+    }
+    fprintf(fp, "\n");
+    
+    // write vertex normals
+    fprintf(fp, "# vertex normal list\n");
+    const_point_list_iterator n_current = point_normals.begin();
+    const_point_list_iterator n_last = point_normals.end();
+    for ( ; n_current != n_last; ++n_current ) {
+       p = *n_current;
+       fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
+    }
+    fprintf(fp, "\n");
+
+    // write triangles
+    Point3D center;
+    double radius;
+    fprintf(fp, "# triangle list\n");
+    fprintf(fp, "\n");
+    const_triele_list_iterator t_current = tri_elements.begin();
+    const_triele_list_iterator t_last = tri_elements.end();
+    int counter = 0;
+    for ( ; t_current != t_last; ++t_current ) {
+       calc_bounding_sphere( counter, &center, &radius );
+       fprintf(fp, "# usemtl desert1\n");
+       fprintf(fp, "# bs %.2f %.2f %.2f %.2f\n", 
+               center.x(), center.y(), center.z(), radius);
+       fprintf(fp, "f %d %d %d\n", 
+               t_current->get_n1(), t_current->get_n2(), t_current->get_n3());
+       fprintf(fp, "\n");
+       ++counter;
+    }
+
     return 1;
 }
 
 
 // $Log$
+// Revision 1.2  1999/03/23 22:02:03  curt
+// Worked on creating data to output ... normals, bounding spheres, etc.
+//
 // Revision 1.1  1999/03/22 23:51:51  curt
 // Initial revision.
 //
index 76ce3aee203a78b249d0de3b406f514f5eadcc27..7afb3076d5047dc2945a4be77cb86317ce956659 100644 (file)
 #endif                                   
 
 
+#include <Math/fg_geodesy.hxx>
 #include <Math/point3d.hxx>
 #include <Triangulate/triangle.hxx>
 
 
-typedef vector < Point3D > wgs84_node_list;
-typedef wgs84_node_list::iterator wgs84_node_list_iterator;
-typedef wgs84_node_list::const_iterator const_wgs84_node_list_iterator;
+typedef vector < int > belongs_to;
+typedef belongs_to::iterator belongs_to_iterator;
+typedef belongs_to::const_iterator belongs_to_tripoly_iterator;
+
+typedef vector < belongs_to > belongs_to_list;
+typedef belongs_to_list::iterator belongs_to_list_iterator;
+typedef belongs_to_list::const_iterator belongs_to_list_tripoly_iterator;
 
-typedef vector < Point3D > normal_list;
-typedef normal_list::iterator normal_list_iterator;
-typedef normal_list::const_iterator const_normal_list_iterator;
 
 class FGGenOutput {
 
 private:
 
-    wgs84_node_list wgs84_nodes;
-    normal_list normals;
+    // node list in geodetic coordinats
+    point_list geod_nodes;
+
+    // node list in cartesian coords (wgs84 model)
+    point_list wgs84_nodes;
+
+    // face normal list (for flat shading)
+    point_list face_normals;
+
+    // normal list (for each point) in cart coords (for smooth
+    // shading)
+    point_list point_normals;
+
+    // triangles (by index into point list)
+    triele_list tri_elements;
+
+    // for each node, a list of triangle indices that contain this node
+    belongs_to_list reverse_ele_lookup;
+
+    // global bounding sphere
+    Point3D gbs_center;
+    double gbs_radius;
+
+    // build the wgs-84 point list
+    void gen_wgs84_points();
+
+    // build the node -> element (triangle) reverse lookup table.
+    // there is an entry for each point containing a list of all the
+    // triangles that share that point.
+    void gen_node_ele_lookup_table();
+
+    // calculate the normals for each point in wgs84_nodes
+    void gen_normals();
+
+    // build the face normal list
+    void gen_face_normals();
+
+    // caclulate the normal for the specified triangle face
+    Point3D calc_normal( int i );
+
+    // calculate the global bounding sphere.  Center is the average of
+    // the points.
+    void calc_gbs();
+
+    // caclulate the bounding sphere for the specified triangle face
+    void calc_bounding_sphere( int i, Point3D *center, double *radius );
 
 public:
-    
-};
 
+    // Constructor && Destructor
+    inline FGGenOutput() { }
+    inline ~FGGenOutput() { }
+
+    // build the necessary output structures based on the
+    // triangulation data
+    int build( const FGTriangle& t );
 
-// generate the flight gear format from the triangulation
-int fgGenOutput( const FGTriangle& t );
+    // write out the fgfs scenery file
+    int write( const string& path );
+};
 
 
 #endif // _GENOBJ_HXX
 
 
 // $Log$
+// Revision 1.3  1999/03/23 22:02:04  curt
+// Worked on creating data to output ... normals, bounding spheres, etc.
+//
 // Revision 1.2  1999/03/23 17:44:49  curt
 // Beginning work on generating output scenery.
 //
index 629df1918158945ddafcfcc92100528ed0ca0243..23899f79710ef9681ff37efebbb7e10ebaae6763 100644 (file)
@@ -156,6 +156,13 @@ void do_triangulate( const FGArray& array, const FGClipper& clipper,
 }
 
 
+// generate the flight gear scenery file
+void do_output( const FGTriangle& t, FGGenOutput& output ) {
+    output.build( t );
+    output.write( "output" );
+}
+
+
 main(int argc, char **argv) {
     fitnode_list fit_list;
     double lon, lat;
@@ -188,11 +195,15 @@ main(int argc, char **argv) {
     do_triangulate( array, clipper, t );
 
     // generate the output
-    fgGenOutput( t );
+    FGGenOutput output;
+    do_output( t, output );
 }
 
 
 // $Log$
+// Revision 1.8  1999/03/23 22:02:17  curt
+// Worked on creating data to output ... normals, bounding spheres, etc.
+//
 // Revision 1.7  1999/03/22 23:48:29  curt
 // Added GenOutput/
 //