1
0
Fork 0

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.
This commit is contained in:
curt 1999-05-12 02:09:02 +00:00
parent 28ee2efbf9
commit c062fe49c4
5 changed files with 127 additions and 30 deletions

View file

@ -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 // build the necessary output structures based on the triangulation
// data // data
int FGGenOutput::build( FGConstruct& c ) { 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 // calculate the global bounding sphere
calc_gbs( c ); calc_gbs( c );
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl; cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
@ -247,6 +325,14 @@ int FGGenOutput::write( FGConstruct &c ) {
} }
fprintf(fp, "\n"); 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) // write triangles (grouped by type for now)
Point3D center; Point3D center;
double radius; double radius;
@ -265,33 +351,13 @@ int FGGenOutput::write( FGConstruct &c ) {
fprintf(fp, "# bs %.4f %.4f %.4f %.2f\n", fprintf(fp, "# bs %.4f %.4f %.4f %.2f\n",
center.x(), center.y(), center.z(), radius); center.x(), center.y(), center.z(), radius);
fan_list_iterator f_current = fans[i].begin(); for ( int j = 0; j < (int)fans[i].size(); ++j ) {
fan_list_iterator f_last = fans[i].end();
for ( ; f_current != f_last; ++f_current ) {
fprintf( fp, "tf" ); fprintf( fp, "tf" );
total_tris += f_current->size() - 2; total_tris += fans[i][j].size() - 2;
int_list_iterator i_current = f_current->begin(); for ( int k = 0; k < (int)fans[i][j].size(); ++k ) {
int_list_iterator i_last = f_current->end(); fprintf( fp, " %d/%d", fans[i][j][k], textures[i][j][k] );
for ( ; i_current != i_last; ++i_current ) {
fprintf( fp, " %d", *i_current );
} }
fprintf( fp, "\n" ); 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" ); fprintf( fp, "\n" );

View file

@ -48,6 +48,10 @@ FG_USING_STD(string);
FG_USING_STD(vector); 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 { class FGGenOutput {
private: private:
@ -58,9 +62,15 @@ private:
// triangles (by index into point list) // triangles (by index into point list)
triele_list tri_elements; triele_list tri_elements;
// texture coordinates
FGTriNodes tex_coords;
// fan list // fan list
fan_list fans[FG_MAX_AREA_TYPES]; fan_list fans[FG_MAX_AREA_TYPES];
// textures pointer list
tex_list textures[FG_MAX_AREA_TYPES];
// global bounding sphere // global bounding sphere
Point3D gbs_center; Point3D gbs_center;
double gbs_radius; double gbs_radius;
@ -77,6 +87,10 @@ private:
void calc_bounding_sphere( FGConstruct& c, const FGTriEle& t, void calc_bounding_sphere( FGConstruct& c, const FGTriEle& t,
Point3D *center, double *radius ); 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: public:
// Constructor && Destructor // Constructor && Destructor

View file

@ -341,6 +341,9 @@ void construct_tile( FGConstruct& c ) {
// arbitrarily complex tiles. // arbitrarily complex tiles.
bool acceptable = false; bool acceptable = false;
bool growing = false;
bool shrinking = false;
double error = 200.0; double error = 200.0;
int count = 0; int count = 0;
@ -371,8 +374,14 @@ void construct_tile( FGConstruct& c ) {
cout << "produced too few nodes ..." << endl; cout << "produced too few nodes ..." << endl;
acceptable = false; acceptable = false;
growing = true;
if ( shrinking ) {
error /= 1.25;
shrinking = false;
} else {
error /= 1.5; error /= 1.5;
}
cout << "Setting error to " << error << " and retrying fit." cout << "Setting error to " << error << " and retrying fit."
<< endl; << endl;
} }
@ -383,8 +392,15 @@ void construct_tile( FGConstruct& c ) {
cout << "produced too many nodes ..." << endl; cout << "produced too many nodes ..." << endl;
acceptable = false; 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." cout << "Setting error to " << error << " and retrying fit."
<< endl; << endl;
} }

View file

@ -117,10 +117,10 @@ main(int argc, char **argv) {
FGBucket tmp1( 0.0, 0.0 ); FGBucket tmp1( 0.0, 0.0 );
double dy = tmp1.get_height(); double dy = tmp1.get_height();
lat = 44.25 + dy * 0.5; lat = 68.75 + dy * 0.5;
bool start_lon = true; bool start_lon = true;
lon = -85.75 + (1.0/16.0); lon = -152.9 /* + (1.0/16.0) */;
while ( lat <= 90.0 ) { while ( lat <= 90.0 ) {
FGBucket tmp2( 0.0, lat ); FGBucket tmp2( 0.0, lat );

View file

@ -413,9 +413,10 @@ int FGTriangle::run_triangulate( int pass ) {
if ( pass == 1 ) { if ( pass == 1 ) {
// use a quality value of 10 (q10) meaning no interior // use a quality value of 10 (q10) meaning no interior
// triangle angles less than 10 degrees // triangle angles less than 10 degrees
// tri_options = "pczAen";
tri_options = "pczq10Aen"; tri_options = "pczq10Aen";
// string tri_options = "pzAen"; // // string tri_options = "pzAen";
// string tri_options = "pczq15S400Aen"; // // string tri_options = "pczq15S400Aen";
} else if ( pass == 2 ) { } else if ( pass == 2 ) {
// no new points on boundary (Y), no internal segment // no new points on boundary (Y), no internal segment
// splitting (YY), no quality refinement () // splitting (YY), no quality refinement ()