From c33841329dd425836e79960225c33c9fb8bc6e0c Mon Sep 17 00:00:00 2001 From: curt Date: Sat, 6 Jan 2001 04:07:45 +0000 Subject: [PATCH] Simplified calling interface to read/write obj functions. --- simgear/io/sg_binobj.cxx | 474 +++++++++++++++++++++------------------ simgear/io/sg_binobj.hxx | 98 +++++--- 2 files changed, 318 insertions(+), 254 deletions(-) diff --git a/simgear/io/sg_binobj.cxx b/simgear/io/sg_binobj.cxx index 41c47072..1cb467a0 100644 --- a/simgear/io/sg_binobj.cxx +++ b/simgear/io/sg_binobj.cxx @@ -107,219 +107,27 @@ double sgCalcBoundingRadius( Point3D center, point_list& wgs84_nodes ) { } -// write out the structures to an ASCII 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. -bool sgWriteAsciiObj( const string& base, const string& name, const SGBucket& b, - Point3D gbs_center, float gbs_radius, - const point_list& wgs84_nodes, const point_list& normals, - const point_list& texcoords, - const group_list& tris_v, const group_list& tris_tc, - const string_list& tri_materials, - 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; - int i, j; - - string dir = base + "/" + b.gen_base_path(); - string command = "mkdir -p " + dir; -#ifdef _MSC_VER - fg_mkdir( dir.c_str() ); -#else - system(command.c_str()); -#endif - - // 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; - return false; - } - - cout << "triangles size = " << tris_v.size() << " tri_materials = " - << tri_materials.size() << endl; - cout << "strips size = " << strips_v.size() << " strip_materials = " - << strip_materials.size() << endl; - cout << "fans size = " << fans_v.size() << " fan_materials = " - << fan_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", SG_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 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 ( 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 ( 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 ( i = 0; i < (int)texcoords.size(); ++i ) { - p = texcoords[i]; - fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y() ); - } - fprintf(fp, "\n"); - - // dump individual triangles if they exist - if ( tris_v.size() > 0 ) { - fprintf(fp, "# triangle groups\n"); - - int start = 0; - int end = 1; - string material; - while ( start < (int)tri_materials.size() ) { - // find next group - material = tri_materials[start]; - while ( (end < (int)tri_materials.size()) && - (material == tri_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 = 0; - for ( i = start; i < end; ++i ) { - for ( j = 0; j < (int)tris_v[i].size(); ++j ) { - group_nodes.push_back( wgs84_nodes[ tris_v[i][j] ] ); - bs_center = calc_center( group_nodes ); - bs_radius = sgCalcBoundingRadius( 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 ( i = start; i < end; ++i ) { - fprintf(fp, "f"); - for ( j = 0; j < (int)tris_v[i].size(); ++j ) { - fprintf(fp, " %d/%d", tris_v[i][j], tris_tc[i][j] ); - } - fprintf(fp, "\n"); - } - - start = end; - end = start + 1; - } - } - - // dump triangle groups - if ( strips_v.size() > 0 ) { - fprintf(fp, "# triangle strips\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 = 0; - for ( i = start; i < end; ++i ) { - for ( 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 = sgCalcBoundingRadius( 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 ( i = start; i < end; ++i ) { - fprintf(fp, "ts"); - for ( 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; - } - } - - // close the file - fclose(fp); - - command = "gzip --force --best " + file; - system(command.c_str()); - - return true; -} - - // read a binary file and populate the provided structures. -bool sgReadBinObj( const string& file, - Point3D &gbs_center, float *gbs_radius, - point_list& wgs84_nodes, point_list& normals, - point_list& texcoords, - group_list& tris_v, group_list& tris_tc, - string_list& tri_materials, - group_list& strips_v, group_list& strips_tc, - string_list& strip_materials, - group_list& fans_v, group_list& fans_tc, - string_list& fan_materials ) -{ +bool sgReadBinObj( const string& file, SGBinObject* obj ) { Point3D p; int i, j, k; char material[256]; + Point3D gbs_center = Point3D( 0 ); + float gbs_radius = 0.0; + point_list wgs84_nodes; + point_list normals; + point_list texcoords; + group_list tris_v; + group_list tris_tc; + string_list tri_materials; + group_list strips_v; + group_list strips_tc; + string_list strip_materials; + group_list fans_v; + group_list fans_tc; + string_list fan_materials; + // zero out structures wgs84_nodes.clear(); normals.clear(); @@ -419,8 +227,8 @@ bool sgReadBinObj( const string& file, ptr += sizeof(double) * 3; float *fptr = (float *)ptr; - *gbs_radius = fptr[0]; - cout << "Bounding radius = " << *gbs_radius << endl; + gbs_radius = fptr[0]; + cout << "Bounding radius = " << gbs_radius << endl; } } else if ( obj_type == SG_VERTEX_LIST ) { // read vertex list properties @@ -473,7 +281,7 @@ bool sgReadBinObj( const string& file, sgReadInt( fp, &nbytes ); cout << "element size = " << nbytes << endl; char buf[nbytes]; - char *ptr = buf; + unsigned char *ptr = (unsigned char *)buf; sgReadBytes( fp, nbytes, ptr ); int count = nbytes / 3; for ( k = 0; k < count; ++k ) { @@ -673,6 +481,21 @@ bool sgReadBinObj( const string& file, // close the file gzclose(fp); + obj->set_gbs_center( gbs_center ); + obj->set_gbs_radius( gbs_radius ); + obj->set_wgs84_nodes( wgs84_nodes ); + obj->set_normals( normals ); + obj->set_texcoords( texcoords ); + obj->set_tris_v( tris_v ); + obj->set_tris_tc( tris_tc ); + obj->set_tri_materials( tri_materials ); + obj->set_strips_v( strips_v ); + obj->set_strips_tc( strips_tc ); + obj->set_strip_materials( strip_materials ); + obj->set_fans_v( fans_v ); + obj->set_fans_tc( fans_tc ); + obj->set_fan_materials( fan_materials ); + if ( sgReadError() ) { cout << "We detected an error while reading the file." << endl; return false; @@ -686,21 +509,28 @@ bool sgReadBinObj( const string& file, // groups come to us sorted by material property. If not, things // don't break, but the result won't be as optimal. bool sgWriteBinObj( const string& base, const string& name, const SGBucket& b, - Point3D gbs_center, float gbs_radius, - const point_list& wgs84_nodes, const point_list& normals, - const point_list& texcoords, - const group_list& tris_v, const group_list& tris_tc, - const string_list& tri_materials, - 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 ) + const SGBinObject* obj ) { Point3D p; sgVec2 t; sgVec3 pt; int i, j; + Point3D gbs_center = obj->get_gbs_center(); + float gbs_radius = obj->get_gbs_radius(); + point_list wgs84_nodes = obj->get_wgs84_nodes(); + point_list normals = obj->get_normals(); + point_list texcoords = obj->get_texcoords(); + group_list tris_v = obj->get_tris_v(); + group_list tris_tc = obj->get_tris_tc(); + string_list tri_materials = obj->get_tri_materials(); + group_list strips_v = obj->get_strips_v(); + group_list strips_tc = obj->get_strips_tc(); + string_list strip_materials = obj->get_strip_materials(); + group_list fans_v = obj->get_fans_v(); + group_list fans_tc = obj->get_fans_tc(); + string_list fan_materials = obj->get_fan_materials(); + string dir = base + "/" + b.gen_base_path(); string command = "mkdir -p " + dir; #ifdef _MSC_VER @@ -967,3 +797,207 @@ bool sgWriteBinObj( const string& base, const string& name, const SGBucket& b, return true; } + + +// write out the structures to an ASCII 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. +bool sgWriteAsciiObj( const string& base, const string& name, const SGBucket& b, + SGBinObject *obj ) +{ + Point3D p; + int i, j; + + Point3D gbs_center = obj->get_gbs_center(); + float gbs_radius = obj->get_gbs_radius(); + point_list wgs84_nodes = obj->get_wgs84_nodes(); + point_list normals = obj->get_normals(); + point_list texcoords = obj->get_texcoords(); + group_list tris_v = obj->get_tris_v(); + group_list tris_tc = obj->get_tris_tc(); + string_list tri_materials = obj->get_tri_materials(); + group_list strips_v = obj->get_strips_v(); + group_list strips_tc = obj->get_strips_tc(); + string_list strip_materials = obj->get_strip_materials(); + group_list fans_v = obj->get_fans_v(); + group_list fans_tc = obj->get_fans_tc(); + string_list fan_materials = obj->get_fan_materials(); + + string dir = base + "/" + b.gen_base_path(); + string command = "mkdir -p " + dir; +#ifdef _MSC_VER + fg_mkdir( dir.c_str() ); +#else + system(command.c_str()); +#endif + + // 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; + return false; + } + + cout << "triangles size = " << tris_v.size() << " tri_materials = " + << tri_materials.size() << endl; + cout << "strips size = " << strips_v.size() << " strip_materials = " + << strip_materials.size() << endl; + cout << "fans size = " << fans_v.size() << " fan_materials = " + << fan_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", SG_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 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 ( 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 ( 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 ( i = 0; i < (int)texcoords.size(); ++i ) { + p = texcoords[i]; + fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y() ); + } + fprintf(fp, "\n"); + + // dump individual triangles if they exist + if ( tris_v.size() > 0 ) { + fprintf(fp, "# triangle groups\n"); + + int start = 0; + int end = 1; + string material; + while ( start < (int)tri_materials.size() ) { + // find next group + material = tri_materials[start]; + while ( (end < (int)tri_materials.size()) && + (material == tri_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 = 0; + for ( i = start; i < end; ++i ) { + for ( j = 0; j < (int)tris_v[i].size(); ++j ) { + group_nodes.push_back( wgs84_nodes[ tris_v[i][j] ] ); + bs_center = calc_center( group_nodes ); + bs_radius = sgCalcBoundingRadius( 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 ( i = start; i < end; ++i ) { + fprintf(fp, "f"); + for ( j = 0; j < (int)tris_v[i].size(); ++j ) { + fprintf(fp, " %d/%d", tris_v[i][j], tris_tc[i][j] ); + } + fprintf(fp, "\n"); + } + + start = end; + end = start + 1; + } + } + + // dump triangle groups + if ( strips_v.size() > 0 ) { + fprintf(fp, "# triangle strips\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 = 0; + for ( i = start; i < end; ++i ) { + for ( 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 = sgCalcBoundingRadius( 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 ( i = start; i < end; ++i ) { + fprintf(fp, "ts"); + for ( 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; + } + } + + // close the file + fclose(fp); + + command = "gzip --force --best " + file; + system(command.c_str()); + + return true; +} diff --git a/simgear/io/sg_binobj.hxx b/simgear/io/sg_binobj.hxx index f50614c4..566427ff 100644 --- a/simgear/io/sg_binobj.hxx +++ b/simgear/io/sg_binobj.hxx @@ -53,6 +53,62 @@ typedef group_list::const_iterator const_group_list_iterator; #define SG_FILE_MAGIC_NUMBER ( ('S'<<24) + ('G'<<16) + SG_BINOBJ_VERSION ) +class SGBinObject { + Point3D gbs_center; + float gbs_radius; + point_list wgs84_nodes; + point_list normals; + point_list texcoords; + group_list tris_v; + group_list tris_tc; + string_list tri_materials; + group_list strips_v; + group_list strips_tc; + string_list strip_materials; + group_list fans_v; + group_list fans_tc; + string_list fan_materials; + +public: + + inline Point3D get_gbs_center() const { return gbs_center; } + inline void set_gbs_center( Point3D p ) { gbs_center = p; } + + inline float get_gbs_radius() const { return gbs_radius; } + inline void set_gbs_radius( float r ) { gbs_radius = r; } + + inline point_list get_wgs84_nodes() const { return wgs84_nodes; } + inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; } + + inline point_list get_normals() const { return normals; } + inline void set_normals( point_list n ) { normals = n; } + + inline point_list get_texcoords() const { return texcoords; } + inline void set_texcoords( point_list t ) { texcoords = t; } + + inline group_list get_tris_v() const { return tris_v; } + inline void set_tris_v( group_list g ) { tris_v = g; } + inline group_list get_tris_tc() const { return tris_tc; } + inline void set_tris_tc( group_list g ) { tris_tc = g; } + inline string_list get_tri_materials() const { return tri_materials; } + inline void set_tri_materials( string_list s ) { tri_materials = s; } + + inline group_list get_strips_v() const { return strips_v; } + inline void set_strips_v( group_list g ) { strips_v = g; } + inline group_list get_strips_tc() const { return strips_tc; } + inline void set_strips_tc( group_list g ) { strips_tc = g; } + inline string_list get_strip_materials() const { return strip_materials; } + inline void set_strip_materials( string_list s ) { strip_materials = s; } + + inline group_list get_fans_v() const { return fans_v; } + inline void set_fans_v( group_list g ) { fans_v = g; } + inline group_list get_fans_tc() const { return fans_tc; } + inline void set_fans_tc( group_list g ) { fans_tc = g; } + inline string_list get_fan_materials() const { return fan_materials; } + inline void set_fan_materials( string_list s ) { fan_materials = s; } +}; + + /* scenery-file: magic, nobjects, object+ magic: "TG" + version @@ -77,46 +133,20 @@ typedef group_list::const_iterator const_group_list_iterator; double sgCalcBoundingRadius( Point3D center, point_list& wgs84_nodes ); -// write out the structures to an ASCII 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. -bool sgWriteAsciiObj( const string& base, const string& name, const SGBucket& b, - Point3D gbs_center, float gbs_radius, - const point_list& wgs84_nodes, const point_list& normals, - const point_list& texcoords, - const group_list& tris_v, const group_list& tris_tc, - const string_list& tri_materials, - 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 ); - - // read a binary file object and populate the provided structures. -bool sgReadBinObj( const string& file, - Point3D &gbs_center, float *gbs_radius, - point_list& wgs84_nodes, point_list& normals, - point_list& texcoords, - group_list& tris_v, group_list& tris_tc, - string_list& tri_materials, - group_list& strips_v, group_list& strips_tc, - string_list& strip_materials, - group_list& fans_v, group_list& fans_tc, - string_list& fan_materials ); +bool sgReadBinObj( const string& file, SGBinObject* obj ); // write out the structures to a binary 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. bool sgWriteBinObj( const string& base, const string& name, const SGBucket& b, - Point3D gbs_center, float gbs_radius, - const point_list& wgs84_nodes, const point_list& normals, - const point_list& texcoords, - const group_list& tris_v, const group_list& tris_tc, - const string_list& tri_materials, - 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 ); + const SGBinObject* obj ); + +// write out the structures to an ASCII 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. +bool sgWriteAsciiObj( const string& base, const string& name, const SGBucket& b, + SGBinObject* obj ); #endif // _SG_BINOBJ_HXX -- 2.39.5