X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FObjects%2Fobj.cxx;h=a33178ae44783b18b51ce93a0cafa334d5e00983;hb=ab381e5c013292935c598dbe80bdd092bcbdd3ff;hp=43c5b959b0abfaf657990ad74953a10e662adf08;hpb=576432ec75ce0c8f860e5df503cab37e3b8d9024;p=flightgear.git diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index 43c5b959b..a33178ae4 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -25,18 +25,13 @@ # include #endif -#ifdef FG_MATH_EXCEPTION_CLASH +#ifdef SG_MATH_EXCEPTION_CLASH # include #endif #include #include -// #if defined ( __sun__ ) -// extern "C" void *memmove(void *, const void *, size_t); -// extern "C" void *memset(void *, int, size_t); -// #endif - #include #include @@ -51,7 +46,7 @@ #include #include #include -#include +#include #include #include @@ -62,8 +57,8 @@ #include "matlib.hxx" #include "obj.hxx" -FG_USING_STD(string); -FG_USING_STD(vector); +SG_USING_STD(string); +SG_USING_STD(vector); typedef vector < int > int_list; @@ -92,12 +87,12 @@ static Point3D local_calc_tex_coords(const Point3D& node, const Point3D& ref) { pp = sgCartToPolar3d(cp); - // tmplon = pp.lon() * RAD_TO_DEG; - // tmplat = pp.lat() * RAD_TO_DEG; + // tmplon = pp.lon() * SGD_RADIANS_TO_DEGREES; + // tmplat = pp.lat() * SGD_RADIANS_TO_DEGREES; // cout << tmplon << " " << tmplat << endl; - pp.setx( fmod(RAD_TO_DEG * FG_TEX_CONSTANT * pp.x(), 11.0) ); - pp.sety( fmod(RAD_TO_DEG * FG_TEX_CONSTANT * pp.y(), 11.0) ); + pp.setx( fmod(SGD_RADIANS_TO_DEGREES * FG_TEX_CONSTANT * pp.x(), 11.0) ); + pp.sety( fmod(SGD_RADIANS_TO_DEGREES * FG_TEX_CONSTANT * pp.y(), 11.0) ); if ( pp.x() < 0.0 ) { pp.setx( pp.x() + 11.0 ); @@ -120,6 +115,11 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { ssgSimpleState *state = NULL; ssgBranch *tile = new ssgBranch () ; + if ( !tile ) { + SG_LOG( SG_TERRAIN, SG_ALERT, "fgGenTile(): NO MEMORY" ); + return NULL; + } + tile -> setName ( (char *)path.c_str() ) ; double tex_width = 1000.0; @@ -136,7 +136,7 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { // set ssgState state = newmat->get_state(); } else { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown usemtl name = " << "Ocean" << " in " << path ); } @@ -148,7 +148,7 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { double height = b.get_height(); double width = b.get_width(); - Point3D center = sgGeodToCart(Point3D(clon*DEG_TO_RAD,clat*DEG_TO_RAD,0.0)); + Point3D center = sgGeodToCart(Point3D(clon*SGD_DEGREES_TO_RADIANS,clat*SGD_DEGREES_TO_RADIANS,0.0)); t->center = center; // cout << "center = " << center << endl;; @@ -162,8 +162,9 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { Point3D rad[4]; int i; for ( i = 0; i < 4; ++i ) { - rad[i] = Point3D( geod[i].x() * DEG_TO_RAD, geod[i].y() * DEG_TO_RAD, - geod[i].z() ); + rad[i] = Point3D( geod[i].x() * SGD_DEGREES_TO_RADIANS, + geod[i].y() * SGD_DEGREES_TO_RADIANS, + geod[i].z() ); } Point3D cart[4], rel[4]; @@ -184,21 +185,18 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { // Calculate normals Point3D normals[4]; for ( i = 0; i < 4; ++i ) { - normals[i] = cart[i]; - double length = normals[i].distance3D( Point3D(0.0) ); - normals[i] /= length; + double length = cart[i].distance3D( Point3D(0.0) ); + normals[i] = cart[i] / length; // cout << "normal = " << normals[i] << endl; } // Calculate texture coordinates point_list geod_nodes; geod_nodes.clear(); - for ( i = 0; i < 4; ++i ) { - geod_nodes.push_back( geod[i] ); - } int_list rectangle; rectangle.clear(); for ( i = 0; i < 4; ++i ) { + geod_nodes.push_back( geod[i] ); rectangle.push_back( i ); } point_list texs = calc_tex_coords( b, geod_nodes, rectangle, @@ -247,33 +245,6 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { } -static float fgTriArea( sgVec3 p0, sgVec3 p1, sgVec3 p2 ) { - /* - From comp.graph.algorithms FAQ - 2A(P) = abs(N.(sum_{i=0}^{n-1}(v_i x v_{i+1}))) - */ - sgVec3 sum; - sgZeroVec3( sum ); - - sgVec3 norm; - sgMakeNormal( norm, p0, p1, p2 ); - - float *vv[3]; - vv[0] = p0; - vv[1] = p1; - vv[2] = p2; - - for( int i=0; i<3; i++ ) { - int ii = (i+1) % 3; - sum[0] += (vv[i][1] * vv[ii][2] - vv[i][2] * vv[ii][1]) ; - sum[1] += (vv[i][2] * vv[ii][0] - vv[i][0] * vv[ii][2]) ; - sum[2] += (vv[i][0] * vv[ii][1] - vv[i][1] * vv[ii][0]) ; - } - - return( sgAbs(sgScalarProductVec3( norm, sum )) * SG_HALF ); -} - - static void random_pt_inside_tri( float *res, float *n1, float *n2, float *n3 ) { @@ -306,15 +277,15 @@ static void gen_random_surface_points( ssgLeaf *leaf, ssgVertexArray *lights, // generate a repeatable random seed p1 = leaf->getVertex( 0 ); - unsigned int *seed = (unsigned int *)p1; - sg_srandom( *seed ); + unsigned int seed = (unsigned int)p1[0]; + sg_srandom( seed ); for ( int i = 0; i < num; ++i ) { leaf->getTriangle( i, &n1, &n2, &n3 ); p1 = leaf->getVertex(n1); p2 = leaf->getVertex(n2); p3 = leaf->getVertex(n3); - double area = fgTriArea( p1, p2, p3 ); + double area = sgTriArea( p1, p2, p3 ); double num = area / factor; // generate a light point for each unit of area @@ -339,7 +310,7 @@ static void gen_random_surface_points( ssgLeaf *leaf, ssgVertexArray *lights, // Load an Ascii obj file -static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, +ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, ssgVertexArray *lights, const bool is_base) { FGNewMat *newmat = NULL; @@ -376,10 +347,12 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, tile -> setName ( (char *)path.c_str() ) ; // Attempt to open "path.gz" or "path" - fg_gzifstream in( path ); + sg_gzifstream in( path ); if ( ! in.is_open() ) { - FG_LOG( FG_TERRAIN, FG_DEBUG, "Cannot open file: " << path ); - FG_LOG( FG_TERRAIN, FG_DEBUG, "default to ocean tile: " << path ); + SG_LOG( SG_TERRAIN, SG_DEBUG, "Cannot open file: " << path ); + SG_LOG( SG_TERRAIN, SG_DEBUG, "default to ocean tile: " << path ); + + delete tile; return NULL; } @@ -396,8 +369,8 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, } center = t->center; - StopWatch stopwatch; - stopwatch.start(); + // StopWatch stopwatch; + // stopwatch.start(); // ignore initial comments and blank lines. (priming the pump) // in >> skipcomment; @@ -413,11 +386,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, while ( ! in.eof() ) { #endif -#if defined( macintosh ) || defined( _MSC_VER ) in >> ::skipws; -#else - in >> skipws; -#endif if ( in.get( c ) && c == '#' ) { // process a comment line @@ -432,7 +401,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, in >> scenery_version; // cout << "scenery_version = " << scenery_version << endl; if ( scenery_version > 0.4 ) { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "\nYou are attempting to load a tile format that\n" << "is newer than this version of flightgear can\n" << "handle. You should upgrade your copy of\n" @@ -467,7 +436,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, if ( ! shared_done ) { // sanity check if ( (int)nodes.size() != vncount ) { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Tile has mismatched nodes = " << nodes.size() << " and normals = " << vncount << " : " << path ); @@ -520,14 +489,14 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, file += material; cout << "current file = " << file << endl; if ( ! material_lib.add_item( file ) ) { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown usemtl name = " << material << " in " << path ); } else { // locate our newly created material newmat = material_lib.find( material ); if ( newmat == NULL ) { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! bad on the fly materia create = " << material << " in " << path ); } @@ -567,7 +536,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, >> normals[vncount][2]; vncount++; } else { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Read too many vertex normals in " << path << " ... dying :-(" ); exit(-1); @@ -579,7 +548,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, >> tex_coords[vtcount][1]; vtcount++; } else { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Read too many vertex texture coords in " << path << " ... dying :-(" ); @@ -597,14 +566,14 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, t->ncount++; } } else { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Read too many nodes in " << path << " ... dying :-("); exit(-1); } } else if ( (token == "tf") || (token == "ts") || (token == "f") ) { // triangle fan, strip, or individual face - // FG_LOG( FG_TERRAIN, FG_INFO, "new fan or strip"); + // SG_LOG( SG_TERRAIN, SG_INFO, "new fan or strip"); fan_vertices.clear(); fan_tex_coords.clear(); @@ -660,11 +629,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, // read all subsequent numbers until next thing isn't a number while ( true ) { -#if defined( macintosh ) || defined( _MSC_VER ) in >> ::skipws; -#else - in >> skipws; -#endif char c; in.get(c); @@ -758,7 +723,7 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, if ( is_base ) { if ( coverage > 0.0 ) { if ( coverage < 10000.0 ) { - FG_LOG(FG_INPUT, FG_ALERT, "Light coverage is " + SG_LOG(SG_INPUT, SG_ALERT, "Light coverage is " << coverage << ", pushing up to 10000"); coverage = 10000; } @@ -766,17 +731,13 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, } } } else { - FG_LOG( FG_TERRAIN, FG_WARN, "Unknown token in " + SG_LOG( SG_TERRAIN, SG_WARN, "Unknown token in " << path << " = " << token ); } // eat white space before start of while loop so if we are // done with useful input it is noticed before hand. -#if defined( macintosh ) || defined( _MSC_VER ) in >> ::skipws; -#else - in >> skipws; -#endif } } @@ -784,63 +745,27 @@ static ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t, t->nodes = nodes; } - stopwatch.stop(); - FG_LOG( FG_TERRAIN, FG_DEBUG, - "Loaded " << path << " in " - << stopwatch.elapsedSeconds() << " seconds" ); + // stopwatch.stop(); + // SG_LOG( SG_TERRAIN, SG_DEBUG, + // "Loaded " << path << " in " + // << stopwatch.elapsedSeconds() << " seconds" ); return tile; } -static ssgLeaf *gen_leaf( const string& path, - const GLenum ty, const string& material, - const point_list& nodes, const point_list& normals, - const point_list& texcoords, - const int_list node_index, - const int_list& tex_index, - const bool calc_lights, ssgVertexArray *lights ) +ssgLeaf *gen_leaf( const string& path, + const GLenum ty, const string& material, + const point_list& nodes, const point_list& normals, + const point_list& texcoords, + const int_list node_index, + const int_list& tex_index, + const bool calc_lights, ssgVertexArray *lights ) { double tex_width = 1000.0, tex_height = 1000.0; ssgSimpleState *state = NULL; float coverage = -1; - int size = node_index.size(); - ssgVertexArray *vl = new ssgVertexArray( size ); - ssgNormalArray *nl = new ssgNormalArray( size ); - ssgTexCoordArray *tl = new ssgTexCoordArray( size ); - ssgColourArray *cl = new ssgColourArray( 1 ); - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - - sgVec2 tmp2; - sgVec3 tmp3; - int i; - for ( i = 0; i < size; ++i ) { - Point3D node = nodes[ node_index[i] ]; - sgSetVec3( tmp3, node[0], node[1], node[2] ); - vl -> add( tmp3 ); - - Point3D normal = normals[ node_index[i] ]; - sgSetVec3( tmp3, normal[0], normal[1], normal[2] ); - nl -> add( tmp3 ); - - Point3D texcoord = texcoords[ tex_index[i] ]; - sgSetVec2( tmp2, texcoord[0], texcoord[1] ); - tl -> add( tmp2 ); - } - - // cout << "before leaf create" << endl; - ssgLeaf *leaf = new ssgVtxTable ( ty, vl, nl, tl, cl ); - // cout << "after leaf create" << endl; - - // lookup the state record - // cout << "looking up material = " << endl; - // cout << material << endl; - // cout << "'" << endl; - FGNewMat *newmat = material_lib.find( material ); if ( newmat == NULL ) { // see if this is an on the fly texture @@ -852,15 +777,15 @@ static ssgLeaf *gen_leaf( const string& path, file += material; cout << "current file = " << file << endl; if ( ! material_lib.add_item( file ) ) { - FG_LOG( FG_TERRAIN, FG_ALERT, + SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown usemtl name = " << material << " in " << path ); } else { // locate our newly created material newmat = material_lib.find( material ); if ( newmat == NULL ) { - FG_LOG( FG_TERRAIN, FG_ALERT, - "Ack! bad on the fly materia create = " + SG_LOG( SG_TERRAIN, SG_ALERT, + "Ack! bad on the fly material create = " << material << " in " << path ); } } @@ -879,12 +804,96 @@ static ssgLeaf *gen_leaf( const string& path, coverage = -1; } + // cout << "before list allocs" << endl; + + // cout << "before vl, size = " << size << endl; + // cout << "before nl" << endl; + // cout << "before tl" << endl; + // cout << "before cl" << endl; + + sgVec2 tmp2; + sgVec3 tmp3; + sgVec4 tmp4; + int i; + + // vertices + int size = node_index.size(); + if ( size < 1 ) { + SG_LOG( SG_TERRAIN, SG_ALERT, "Woh! node list size < 1" ); + exit(-1); + } + ssgVertexArray *vl = new ssgVertexArray( size ); + Point3D node; + for ( i = 0; i < size; ++i ) { + node = nodes[ node_index[i] ]; + sgSetVec3( tmp3, node[0], node[1], node[2] ); + vl -> add( tmp3 ); + } + + // colors + ssgColourArray *cl = new ssgColourArray( 1 ); + sgSetVec4( tmp4, 1.0, 1.0, 1.0, 1.0 ); + cl->add( tmp4 ); + + // normals + Point3D normal; + ssgNormalArray *nl = new ssgNormalArray( size ); + if ( normals.size() == 1 ) { + normal = normals[ 0 ]; + sgSetVec3( tmp3, normal[0], normal[1], normal[2] ); + nl -> add( tmp3 ); + } else if ( normals.size() > 1 ) { + for ( i = 0; i < size; ++i ) { + normal = normals[ node_index[i] ]; + sgSetVec3( tmp3, normal[0], normal[1], normal[2] ); + nl -> add( tmp3 ); + } + } + + // texture coordinates + size = tex_index.size(); + Point3D texcoord; + ssgTexCoordArray *tl = new ssgTexCoordArray( size ); + if ( size == 1 ) { + texcoord = texcoords[ tex_index[0] ]; + sgSetVec2( tmp2, texcoord[0], texcoord[1] ); + sgSetVec2( tmp2, texcoord[0], texcoord[1] ); + if ( tex_width > 0 ) { + tmp2[0] *= (1000.0 / tex_width); + } + if ( tex_height > 0 ) { + tmp2[1] *= (1000.0 / tex_height); + } + tl -> add( tmp2 ); + } else if ( size > 1 ) { + for ( i = 0; i < size; ++i ) { + texcoord = texcoords[ tex_index[i] ]; + sgSetVec2( tmp2, texcoord[0], texcoord[1] ); + if ( tex_width > 0 ) { + tmp2[0] *= (1000.0 / tex_width); + } + if ( tex_height > 0 ) { + tmp2[1] *= (1000.0 / tex_height); + } + tl -> add( tmp2 ); + } + } + + // cout << "before leaf create" << endl; + ssgLeaf *leaf = new ssgVtxTable ( ty, vl, nl, tl, cl ); + // cout << "after leaf create" << endl; + + // lookup the state record + // cout << "looking up material = " << endl; + // cout << material << endl; + // cout << "'" << endl; + leaf->setState( state ); if ( calc_lights ) { if ( coverage > 0.0 ) { if ( coverage < 10000.0 ) { - FG_LOG(FG_INPUT, FG_ALERT, "Light coverage is " + SG_LOG(SG_INPUT, SG_ALERT, "Light coverage is " << coverage << ", pushing up to 10000"); coverage = 10000; } @@ -897,8 +906,8 @@ static ssgLeaf *gen_leaf( const string& path, // Load an Binary obj file -static ssgBranch *fgBinObjLoad( const string& path, FGTileEntry *t, - ssgVertexArray *lights, const bool is_base) +ssgBranch *fgBinObjLoad( const string& path, FGTileEntry *t, + ssgVertexArray *lights, const bool is_base) { int i; @@ -922,6 +931,7 @@ static ssgBranch *fgBinObjLoad( const string& path, FGTileEntry *t, } point_list nodes = obj.get_wgs84_nodes(); + point_list colors = obj.get_colors(); point_list normals = obj.get_normals(); point_list texcoords = obj.get_texcoords(); @@ -929,6 +939,22 @@ static ssgBranch *fgBinObjLoad( const string& path, FGTileEntry *t, int_list vertex_index; int_list tex_index; + // generate points + string_list pt_materials = obj.get_pt_materials(); + group_list pts_v = obj.get_pts_v(); + for ( i = 0; i < (int)pts_v.size(); ++i ) { + cout << "pts_v.size() = " << pts_v.size() << endl; + material = pt_materials[i]; + vertex_index = pts_v[i]; + tex_index.clear(); + ssgLeaf *leaf = gen_leaf( path, GL_POINTS, material, + nodes, normals, texcoords, + vertex_index, tex_index, + false, lights ); + + object->addKid( leaf ); + } + // generate triangles string_list tri_materials = obj.get_tri_materials(); group_list tris_v = obj.get_tris_v(); @@ -979,24 +1005,3 @@ static ssgBranch *fgBinObjLoad( const string& path, FGTileEntry *t, return object; } - - -// Load an obj file -ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, - ssgVertexArray *lights, const bool is_base) -{ - ssgBranch *result = NULL; - - // try loading binary format - result = fgBinObjLoad( path, t, lights, is_base ); - if ( result == NULL ) { - // next try the older ascii format - result = fgAsciiObjLoad( path, t, lights, is_base ); - if ( result == NULL ) { - // default to an ocean tile - result = fgGenTile( path, t ); - } - } - - return result; -}