From c062fe49c48f1c2a1cb31909a5aecefee1f108f8 Mon Sep 17 00:00:00 2001 From: curt Date: Wed, 12 May 1999 02:09:02 +0000 Subject: [PATCH] Start of support for precalculating texture coordinates. Try to avoid a situation where you cycle between too many nodes and two few nodes with just a single increment of error level. --- Tools/Construct/GenOutput/genobj.cxx | 114 ++++++++++++++++++----- Tools/Construct/GenOutput/genobj.hxx | 14 +++ Tools/Construct/Main/main.cxx | 20 +++- Tools/Construct/Main/master.cxx | 4 +- Tools/Construct/Triangulate/triangle.cxx | 5 +- 5 files changed, 127 insertions(+), 30 deletions(-) diff --git a/Tools/Construct/GenOutput/genobj.cxx b/Tools/Construct/GenOutput/genobj.cxx index 1a1cafe41..2c161786a 100644 --- a/Tools/Construct/GenOutput/genobj.cxx +++ b/Tools/Construct/GenOutput/genobj.cxx @@ -60,6 +60,70 @@ void FGGenOutput::calc_gbs( FGConstruct& c ) { } +#define FG_TEX_CONSTANT 69.0 + +// traverse the specified fan and attempt to calculate "none +// stretching" texture coordinates +int_list FGGenOutput::calc_tex_coords( point_list geod_nodes, int_list fan ) { + // cout << "calculating texture coordinates for a specific fan of size = " + // << fan.size() << endl; + + // find min/max of fan + Point3D min, max, p, t; + bool first = true; + + for ( int i = 0; i < (int)fan.size(); ++i ) { + p = geod_nodes[ fan[i] ]; + t.setx( p.x() * FG_TEX_CONSTANT ); + t.sety( p.y() * FG_TEX_CONSTANT ); + + if ( first ) { + min = max = t; + first = false; + } else { + if ( t.x() < min.x() ) { + min.setx( t.x() ); + } + if ( t.y() < min.y() ) { + min.sety( t.y() ); + } + if ( t.x() > max.x() ) { + max.setx( t.x() ); + } + if ( t.y() > max.y() ) { + max.sety( t.y() ); + } + } + } + min.setx( (double)( (int)min.x() - 1 ) ); + min.sety( (double)( (int)min.y() - 1 ) ); + // cout << "found min = " << min << endl; + + // generate tex_list + Point3D shifted_t; + int index; + int_list tex; + tex.clear(); + for ( int i = 0; i < (int)fan.size(); ++i ) { + p = geod_nodes[ fan[i] ]; + t.setx( p.x() * FG_TEX_CONSTANT ); + t.sety( p.y() * FG_TEX_CONSTANT ); + shifted_t = t - min; + if ( shifted_t.x() < FG_EPSILON ) { + shifted_t.setx( 0.0 ); + } + if ( shifted_t.y() < FG_EPSILON ) { + shifted_t.sety( 0.0 ); + } + shifted_t.setz( 0.0 ); + index = tex_coords.unique_add( shifted_t ); + tex.push_back( index ); + } + + return tex; +} + + // build the necessary output structures based on the triangulation // data int FGGenOutput::build( FGConstruct& c ) { @@ -92,6 +156,20 @@ int FGGenOutput::build( FGConstruct& c ) { } } + // build the texture coordinate list and make a parallel structure + // to the fan list for pointers into the texture list + cout << "calculating texture coordinates" << endl; + tex_coords.clear(); + + for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) { + for ( int j = 0; j < (int)fans[i].size(); ++j ) { + int_list t_list = calc_tex_coords( geod_nodes, fans[i][j] ); + // cout << fans[i][j].size() << " === " + // << t_list.size() << endl; + textures[i].push_back( t_list ); + } + } + // calculate the global bounding sphere calc_gbs( c ); cout << "center = " << gbs_center << " radius = " << gbs_radius << endl; @@ -247,6 +325,14 @@ int FGGenOutput::write( FGConstruct &c ) { } fprintf(fp, "\n"); + // write texture coordinates + point_list tex_coord_list = tex_coords.get_node_list(); + for ( int i = 0; i < (int)tex_coord_list.size(); ++i ) { + p = tex_coord_list[i]; + fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y()); + } + fprintf(fp, "\n"); + // write triangles (grouped by type for now) Point3D center; double radius; @@ -265,33 +351,13 @@ int FGGenOutput::write( FGConstruct &c ) { fprintf(fp, "# bs %.4f %.4f %.4f %.2f\n", center.x(), center.y(), center.z(), radius); - fan_list_iterator f_current = fans[i].begin(); - fan_list_iterator f_last = fans[i].end(); - for ( ; f_current != f_last; ++f_current ) { + for ( int j = 0; j < (int)fans[i].size(); ++j ) { fprintf( fp, "tf" ); - total_tris += f_current->size() - 2; - int_list_iterator i_current = f_current->begin(); - int_list_iterator i_last = f_current->end(); - for ( ; i_current != i_last; ++i_current ) { - fprintf( fp, " %d", *i_current ); + total_tris += fans[i][j].size() - 2; + for ( int k = 0; k < (int)fans[i][j].size(); ++k ) { + fprintf( fp, " %d/%d", fans[i][j][k], textures[i][j][k] ); } fprintf( fp, "\n" ); - -#if 0 - { - int_list_iterator i_current = f_current->begin(); - int_list_iterator i_last = f_current->end(); - int center = *i_current; - ++i_current; - int n2 = *i_current; - ++i_current; - for ( ; i_current != i_last; ++i_current ) { - int n3 = *i_current; - fprintf( fp, "f %d %d %d\n", center, n2, n3 ); - n2 = n3; - } - } -#endif } fprintf( fp, "\n" ); diff --git a/Tools/Construct/GenOutput/genobj.hxx b/Tools/Construct/GenOutput/genobj.hxx index b38f58eb7..ddb57e8d2 100644 --- a/Tools/Construct/GenOutput/genobj.hxx +++ b/Tools/Construct/GenOutput/genobj.hxx @@ -48,6 +48,10 @@ FG_USING_STD(string); FG_USING_STD(vector); +typedef vector < int_list > tex_list; +typedef tex_list::iterator tex_list_iterator; +typedef tex_list::const_iterator const_tex_list_iterator; + class FGGenOutput { private: @@ -58,9 +62,15 @@ private: // triangles (by index into point list) triele_list tri_elements; + // texture coordinates + FGTriNodes tex_coords; + // fan list fan_list fans[FG_MAX_AREA_TYPES]; + // textures pointer list + tex_list textures[FG_MAX_AREA_TYPES]; + // global bounding sphere Point3D gbs_center; double gbs_radius; @@ -77,6 +87,10 @@ private: void calc_bounding_sphere( FGConstruct& c, const FGTriEle& t, Point3D *center, double *radius ); + // traverse the specified fan and attempt to calculate "none + // stretching" texture coordinates + int_list calc_tex_coords( point_list geod_nodes, int_list fan ); + public: // Constructor && Destructor diff --git a/Tools/Construct/Main/main.cxx b/Tools/Construct/Main/main.cxx index c59080f2b..27f5a4aaa 100644 --- a/Tools/Construct/Main/main.cxx +++ b/Tools/Construct/Main/main.cxx @@ -341,6 +341,9 @@ void construct_tile( FGConstruct& c ) { // arbitrarily complex tiles. bool acceptable = false; + bool growing = false; + bool shrinking = false; + double error = 200.0; int count = 0; @@ -371,8 +374,14 @@ void construct_tile( FGConstruct& c ) { cout << "produced too few nodes ..." << endl; acceptable = false; + growing = true; - error /= 1.5; + if ( shrinking ) { + error /= 1.25; + shrinking = false; + } else { + error /= 1.5; + } cout << "Setting error to " << error << " and retrying fit." << endl; } @@ -383,8 +392,15 @@ void construct_tile( FGConstruct& c ) { cout << "produced too many nodes ..." << endl; acceptable = false; + shrinking = true; + + if ( growing ) { + error *= 1.25; + growing = false; + } else { + error *= 1.5; + } - error *= 1.5; cout << "Setting error to " << error << " and retrying fit." << endl; } diff --git a/Tools/Construct/Main/master.cxx b/Tools/Construct/Main/master.cxx index 159f1549e..86b3bfad1 100644 --- a/Tools/Construct/Main/master.cxx +++ b/Tools/Construct/Main/master.cxx @@ -117,10 +117,10 @@ main(int argc, char **argv) { FGBucket tmp1( 0.0, 0.0 ); double dy = tmp1.get_height(); - lat = 44.25 + dy * 0.5; + lat = 68.75 + dy * 0.5; bool start_lon = true; - lon = -85.75 + (1.0/16.0); + lon = -152.9 /* + (1.0/16.0) */; while ( lat <= 90.0 ) { FGBucket tmp2( 0.0, lat ); diff --git a/Tools/Construct/Triangulate/triangle.cxx b/Tools/Construct/Triangulate/triangle.cxx index f3adb95f4..1270e79f6 100644 --- a/Tools/Construct/Triangulate/triangle.cxx +++ b/Tools/Construct/Triangulate/triangle.cxx @@ -413,9 +413,10 @@ int FGTriangle::run_triangulate( int pass ) { if ( pass == 1 ) { // use a quality value of 10 (q10) meaning no interior // triangle angles less than 10 degrees + // tri_options = "pczAen"; tri_options = "pczq10Aen"; - // string tri_options = "pzAen"; - // string tri_options = "pczq15S400Aen"; + // // string tri_options = "pzAen"; + // // string tri_options = "pczq15S400Aen"; } else if ( pass == 2 ) { // no new points on boundary (Y), no internal segment // splitting (YY), no quality refinement ()