From c3753bf6201d1482651f2cfb353476eb40ace4fe Mon Sep 17 00:00:00 2001 From: curt Date: Tue, 31 Aug 1999 23:23:04 +0000 Subject: [PATCH] Lighting/ssgSimpleState fixes. obj.cxx added code to generate an ocean tile on the fly if no tile exists. --- src/Objects/material.cxx | 8 +-- src/Objects/material.hxx | 4 +- src/Objects/materialmgr.cxx | 15 +++- src/Objects/obj.cxx | 133 ++++++++++++++++++++++++++++++++++-- 4 files changed, 145 insertions(+), 15 deletions(-) diff --git a/src/Objects/material.cxx b/src/Objects/material.cxx index 0a300253a..a6d9b7c97 100644 --- a/src/Objects/material.cxx +++ b/src/Objects/material.cxx @@ -60,7 +60,7 @@ FGMaterial::FGMaterial ( void ) ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0; diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0; specular[0] = specular[1] = specular[2] = specular[3] = 0.0; - emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0; + emission[0] = emission[1] = emission[2] = emission[3] = 0.0; } @@ -86,9 +86,9 @@ operator >> ( istream& in, FGMaterial& m ) } else if ( token == "specular" ) { in >> token >> m.specular[0] >> m.specular[1] >> m.specular[2] >> m.specular[3]; - } else if ( token == "emissive" ) { - in >> token >> m.emissive[0] >> m.emissive[1] - >> m.emissive[2] >> m.emissive[3]; + } else if ( token == "emission" ) { + in >> token >> m.emission[0] >> m.emission[1] + >> m.emission[2] >> m.emission[3]; } else if ( token == "alpha" ) { in >> token >> token; if ( token == "yes" ) { diff --git a/src/Objects/material.hxx b/src/Objects/material.hxx index ac103440f..24b0d6c9a 100644 --- a/src/Objects/material.hxx +++ b/src/Objects/material.hxx @@ -71,7 +71,7 @@ private: double xsize, ysize; // material properties - GLfloat ambient[4], diffuse[4], specular[4], emissive[4]; + GLfloat ambient[4], diffuse[4], specular[4], emission[4]; GLint texture_ptr; public: @@ -94,7 +94,7 @@ public: inline GLfloat *get_ambient() { return ambient; } inline GLfloat *get_diffuse() { return diffuse; } inline GLfloat *get_specular() { return specular; } - inline GLfloat *get_emissive() { return emissive; } + inline GLfloat *get_emission() { return emission; } }; diff --git a/src/Objects/materialmgr.cxx b/src/Objects/materialmgr.cxx index 292ac66e9..315b756f6 100644 --- a/src/Objects/materialmgr.cxx +++ b/src/Objects/materialmgr.cxx @@ -189,12 +189,17 @@ fgMATERIAL_MGR::load_lib ( void ) state->enable( GL_TEXTURE_2D ); state->setTexture( (char *)tex_file.c_str() ); state->setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ; + state->setMaterial ( GL_SPECULAR, 0, 0, 0, 0 ) ; + state->setMaterial ( GL_EMISSION, 0, 0, 0, 0 ) ; } else { state->disable( GL_TEXTURE_2D ); state->disable( GL_COLOR_MATERIAL ); - GLfloat *ambient, *diffuse; + GLfloat *ambient, *diffuse, *specular, *emission; ambient = m.get_ambient(); diffuse = m.get_diffuse(); + specular = m.get_specular(); + emission = m.get_emission(); + /* cout << "ambient = " << ambient[0] << "," << ambient[1] << "," << ambient[2] << endl; */ state->setMaterial ( GL_AMBIENT, @@ -203,7 +208,13 @@ fgMATERIAL_MGR::load_lib ( void ) state->setMaterial ( GL_DIFFUSE, diffuse[0], diffuse[1], diffuse[2], diffuse[3] ) ; - } + state->setMaterial ( GL_SPECULAR, + specular[0], specular[1], + specular[2], specular[3] ) ; + state->setMaterial ( GL_EMISSION, + emission[0], emission[1], + emission[2], emission[3] ) ; + } m_slot.set_state( state ); material_mgr.material_map[material_name] = m_slot; diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index cab9bbcf1..d1c19320c 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -29,14 +29,8 @@ # include #endif -// #ifdef HAVE_WINDOWS_H -// # include -// #endif - #include #include -// #include -// #include // #if defined ( __sun__ ) // extern "C" void *memmove(void *, const void *, size_t); @@ -55,6 +49,7 @@ #include #include
#include +#include #include #include #include @@ -134,6 +129,128 @@ static Point3D calc_tex_coords(const Point3D& node, const Point3D& ref) { } +// Generate a generic ocean tile on the fly +ssgBranch *fgGenTile( const string& path, FGTileEntry *t) { + fgFRAGMENT fragment; + fragment.init(); + fragment.tile_ptr = t; + + ssgSimpleState *state = NULL; + + ssgBranch *tile = new ssgBranch () ; + tile -> setName ( (char *)path.c_str() ) ; + + // find Ocean material in the properties list + if ( ! material_mgr.find( "Ocean", fragment.material_ptr )) { + FG_LOG( FG_TERRAIN, FG_ALERT, + "Ack! unknown usemtl name = " << "Ocean" + << " in " << path ); + } + + // set the texture width and height values for this + // material + FGMaterial m = fragment.material_ptr->get_m(); + double tex_width = m.get_xsize(); + double tex_height = m.get_ysize(); + + // set ssgState + state = fragment.material_ptr->get_state(); + + // Calculate center point + FGBucket b = t->tile_bucket; + double clon = b.get_center_lon(); + double clat = b.get_center_lat(); + double height = b.get_height(); + double width = b.get_width(); + + Point3D center = fgGeodToCart(Point3D(clon*DEG_TO_RAD,clat*DEG_TO_RAD,0.0)); + t->center = center; + fragment.center = center; + // cout << "center = " << center << endl;; + + // Caculate corner vertices + Point3D geod[4]; + geod[0] = Point3D( clon - width/2.0, clat - height/2.0, 0.0 ); + geod[1] = Point3D( clon + width/2.0, clat - height/2.0, 0.0 ); + geod[2] = Point3D( clon + width/2.0, clat + height/2.0, 0.0 ); + geod[3] = Point3D( clon - width/2.0, clat + height/2.0, 0.0 ); + + Point3D rad[4]; + for ( int i = 0; i < 4; ++i ) { + rad[i] = Point3D( geod[i].x() * DEG_TO_RAD, geod[i].y() * DEG_TO_RAD, + geod[i].z() ); + } + + Point3D cart[4], rel[4]; + for ( int i = 0; i < 4; ++i ) { + cart[i] = fgGeodToCart(rad[i]); + rel[i] = cart[i] - center; + t->nodes.push_back( rel[i] ); + // cout << "corner " << i << " = " << cart[i] << endl; + } + + t->ncount = 4; + + // Calculate bounding radius + t->bounding_radius = center.distance3D( cart[0] ); + fragment.bounding_radius = t->bounding_radius; + // cout << "bounding radius = " << t->bounding_radius << endl; + + // Calculate normals + Point3D normals[4]; + for ( int i = 0; i < 4; ++i ) { + normals[i] = cart[i]; + double length = normals[i].distance3D( Point3D(0.0) ); + normals[i] /= length; + // cout << "normal = " << normals[i] << endl; + } + + // Calculate texture coordinates + Point3D texs[4]; + for ( int i = 0; i < 4; ++i ) { + texs[i] = calc_tex_coords( rel[i], center ); + // cout << "texture coordinate = " << texs[i] << endl; + } + + // Build flight gear structure + fragment.add_face(1, 2, 3); + fragment.add_face(1, 3, 4); + t->fragment_list.push_back(fragment); + + // Build ssg structure + t->vtlist = new sgVec3 [ 4 ]; + t->vnlist = new sgVec3 [ 4 ]; + t->tclist = new sgVec2 [ 4 ]; + + for ( int i = 0; i < 4; ++i ) { + sgSetVec3( t->vtlist[i], + rel[i].x(), rel[i].y(), rel[i].z() ); + sgSetVec3( t->vnlist[i], + normals[i].x(), normals[i].y(), normals[i].z() ); + sgSetVec2( t->tclist[i], texs[i].x(), texs[i].y() ); + } + + unsigned short *vindex = new unsigned short [ 4 ]; + unsigned short *tindex = new unsigned short [ 4 ]; + for ( int i = 0; i < 4; ++i ) { + vindex[i] = i; + tindex[i] = i; + } + + ssgLeaf *leaf = + new ssgVTable ( GL_TRIANGLE_FAN, + 4, vindex, t->vtlist, + 4, vindex, t->vnlist, + 4, tindex, t->tclist, + 0, NULL, NULL ) ; + leaf->setState( state ); + + tile->addKid( leaf ); + + return tile; +} + + // Load a .obj file and build the fragment list ssgBranch *fgObjLoad( const string& path, FGTileEntry *t) { fgFRAGMENT fragment; @@ -165,7 +282,9 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t) { fg_gzifstream in( path ); if ( ! in.is_open() ) { FG_LOG( FG_TERRAIN, FG_ALERT, "Cannot open file: " << path ); - return NULL; + FG_LOG( FG_TERRAIN, FG_ALERT, "default to ocean tile: " << path ); + + return fgGenTile( path, t ); } shading = current_options.get_shading();