From 5b2b420c48363060cda0b91137316fa4ac045673 Mon Sep 17 00:00:00 2001 From: Peter Sadrozinski Date: Fri, 10 Jan 2014 22:42:16 -0500 Subject: [PATCH] - secondary tc and vertex attribs in .btg file - decrease debug when writing btg files - deprecate some set_xxx apis --- simgear/io/decode_binobj.cxx | 36 +- simgear/io/sg_binobj.cxx | 398 ++++++++++++++----- simgear/io/sg_binobj.hxx | 196 +++++---- simgear/io/test_binobj.cxx | 32 +- simgear/scene/tgdb/SGTexturedTriangleBin.hxx | 131 ++++-- simgear/scene/tgdb/obj.cxx | 272 ++++++++----- 6 files changed, 732 insertions(+), 333 deletions(-) diff --git a/simgear/io/decode_binobj.cxx b/simgear/io/decode_binobj.cxx index 41880e12..a6aa9101 100644 --- a/simgear/io/decode_binobj.cxx +++ b/simgear/io/decode_binobj.cxx @@ -82,9 +82,9 @@ int main( int argc, char **argv ) { group_list pts_v = obj.get_pts_v(); group_list pts_n = obj.get_pts_n(); for ( i = 0; i < (int)pts_v.size(); ++i ) { - material = pt_materials[i]; - vertex_index = pts_v[i]; - normal_index = pts_n[i]; + material = pt_materials[i]; + vertex_index = pts_v[i]; + normal_index = pts_n[i]; cout << "# usemtl " << material << endl; cout << "pt "; for ( j = 0; j < (int)vertex_index.size(); ++j ) { @@ -97,12 +97,12 @@ int main( int argc, char **argv ) { string_list tri_materials = obj.get_tri_materials(); group_list tris_v = obj.get_tris_v(); group_list tris_n = obj.get_tris_n(); - group_list tris_tc = obj.get_tris_tc(); + group_tci_list tris_tc = obj.get_tris_tcs(); for ( i = 0; i < (int)tris_v.size(); ++i ) { - material = tri_materials[i]; - vertex_index = tris_v[i]; - normal_index = tris_n[i]; - tex_index = tris_tc[i]; + material = tri_materials[i]; + vertex_index = tris_v[i]; + normal_index = tris_n[i]; + tex_index = tris_tc[0][i]; cout << "# usemtl " << material << endl; cout << "f "; for ( j = 0; j < (int)vertex_index.size(); ++j ) { @@ -120,12 +120,12 @@ int main( int argc, char **argv ) { string_list strip_materials = obj.get_strip_materials(); group_list strips_v = obj.get_strips_v(); group_list strips_n = obj.get_strips_n(); - group_list strips_tc = obj.get_strips_tc(); + group_tci_list strips_tc = obj.get_strips_tcs(); for ( i = 0; i < (int)strips_v.size(); ++i ) { - material = strip_materials[i]; - vertex_index = strips_v[i]; - normal_index = strips_n[i]; - tex_index = strips_tc[i]; + material = strip_materials[i]; + vertex_index = strips_v[i]; + normal_index = strips_n[i]; + tex_index = strips_tc[0][i]; cout << "# usemtl " << material << endl; cout << "ts "; for ( j = 0; j < (int)vertex_index.size(); ++j ) { @@ -142,12 +142,12 @@ int main( int argc, char **argv ) { string_list fan_materials = obj.get_fan_materials(); group_list fans_v = obj.get_fans_v(); group_list fans_n = obj.get_fans_n(); - group_list fans_tc = obj.get_fans_tc(); + group_tci_list fans_tc = obj.get_fans_tcs(); for ( i = 0; i < (int)fans_v.size(); ++i ) { - material = fan_materials[i]; - vertex_index = fans_v[i]; - normal_index = fans_n[i]; - tex_index = fans_tc[i]; + material = fan_materials[i]; + vertex_index = fans_v[i]; + normal_index = fans_n[i]; + tex_index = fans_tc[0][i]; cout << "# usemtl " << material << endl; cout << "tf "; for ( j = 0; j < (int)vertex_index.size(); ++j ) { diff --git a/simgear/io/sg_binobj.cxx b/simgear/io/sg_binobj.cxx index 69cdd477..5e5dafff 100644 --- a/simgear/io/sg_binobj.cxx +++ b/simgear/io/sg_binobj.cxx @@ -58,9 +58,11 @@ enum sgObjectTypes { SG_BOUNDING_SPHERE = 0, SG_VERTEX_LIST = 1, - SG_COLOR_LIST = 4, SG_NORMAL_LIST = 2, SG_TEXCOORD_LIST = 3, + SG_COLOR_LIST = 4, + SG_VA_FLOAT_LIST = 5, + SG_VA_INTEGER_LIST = 6, SG_POINTS = 9, @@ -70,15 +72,32 @@ enum sgObjectTypes { }; enum sgIndexTypes { - SG_IDX_VERTICES = 0x01, - SG_IDX_NORMALS = 0x02, - SG_IDX_COLORS = 0x04, - SG_IDX_TEXCOORDS = 0x08 + SG_IDX_VERTICES = 0x01, + SG_IDX_NORMALS = 0x02, + SG_IDX_COLORS = 0x04, + SG_IDX_TEXCOORDS_0 = 0x08, + SG_IDX_TEXCOORDS_1 = 0x10, + SG_IDX_TEXCOORDS_2 = 0x20, + SG_IDX_TEXCOORDS_3 = 0x40, +}; + +enum sgVertexAttributeTypes { + // vertex attributes + SG_VA_INTEGER_0 = 0x00000001, + SG_VA_INTEGER_1 = 0x00000002, + SG_VA_INTEGER_2 = 0x00000004, + SG_VA_INTEGER_3 = 0x00000008, + + SG_VA_FLOAT_0 = 0x00000100, + SG_VA_FLOAT_1 = 0x00000200, + SG_VA_FLOAT_2 = 0x00000400, + SG_VA_FLOAT_3 = 0x00000800, }; enum sgPropertyTypes { SG_MATERIAL = 0, - SG_INDEX_TYPES = 1 + SG_INDEX_TYPES = 1, + SG_VERT_ATTRIBS = 2 }; @@ -130,6 +149,17 @@ public: } } + float readInt() + { + unsigned int* p = reinterpret_cast(ptr + offset); + if ( sgIsBigEndian() ) { + sgEndianSwap((uint32_t *) p); + } + + offset += sizeof(unsigned int); + return *p; + } + SGVec3d readVec3d() { double* p = reinterpret_cast(ptr + offset); @@ -202,15 +232,19 @@ template static void read_indices(char* buffer, size_t bytes, int indexMask, + int vaMask, int_list& vertices, int_list& normals, int_list& colors, - int_list& texCoords) + tci_list& texCoords, + vai_list& vas + ) { const int indexSize = sizeof(T) * std::bitset<32>(indexMask).count(); - const int count = bytes / indexSize; + const int vaSize = sizeof(T) * std::bitset<32>(vaMask).count(); + const int count = bytes / (indexSize + vaSize); -// fix endian-ness of the whole lot, if required + // fix endian-ness of the whole lot, if required if (sgIsBigEndian()) { int indices = bytes / sizeof(T); T* src = reinterpret_cast(buffer); @@ -224,7 +258,21 @@ static void read_indices(char* buffer, if (indexMask & SG_IDX_VERTICES) vertices.push_back(*src++); if (indexMask & SG_IDX_NORMALS) normals.push_back(*src++); if (indexMask & SG_IDX_COLORS) colors.push_back(*src++); - if (indexMask & SG_IDX_TEXCOORDS) texCoords.push_back(*src++); + if (indexMask & SG_IDX_TEXCOORDS_0) texCoords[0].push_back(*src++); + if (indexMask & SG_IDX_TEXCOORDS_1) texCoords[1].push_back(*src++); + if (indexMask & SG_IDX_TEXCOORDS_2) texCoords[2].push_back(*src++); + if (indexMask & SG_IDX_TEXCOORDS_3) texCoords[3].push_back(*src++); + + if ( vaMask ) { + if (vaMask & SG_VA_INTEGER_0) vas[0].push_back(*src++); + if (vaMask & SG_VA_INTEGER_1) vas[1].push_back(*src++); + if (vaMask & SG_VA_INTEGER_2) vas[2].push_back(*src++); + if (vaMask & SG_VA_INTEGER_3) vas[3].push_back(*src++); + if (vaMask & SG_VA_FLOAT_0) vas[4].push_back(*src++); + if (vaMask & SG_VA_FLOAT_1) vas[5].push_back(*src++); + if (vaMask & SG_VA_FLOAT_2) vas[6].push_back(*src++); + if (vaMask & SG_VA_FLOAT_3) vas[7].push_back(*src++); + } } // of elements in the index } @@ -249,15 +297,19 @@ void write_indice(gzFile fp, uint32_t value) template -void write_indices(gzFile fp, unsigned char indexMask, +void write_indices(gzFile fp, + unsigned char indexMask, + unsigned int vaMask, const int_list& vertices, const int_list& normals, const int_list& colors, - const int_list& texCoords) + const tci_list& texCoords, + const vai_list& vas ) { unsigned int count = vertices.size(); const int indexSize = sizeof(T) * std::bitset<32>(indexMask).count(); - sgWriteUInt(fp, indexSize * count); + const int vaSize = sizeof(T) * std::bitset<32>(vaMask).count(); + sgWriteUInt(fp, (indexSize + vaSize) * count); for (unsigned int i=0; i < count; ++i) { write_indice(fp, static_cast(vertices[i])); @@ -268,8 +320,45 @@ void write_indices(gzFile fp, unsigned char indexMask, if (indexMask & SG_IDX_COLORS) { write_indice(fp, static_cast(colors[i])); } - if (indexMask & SG_IDX_TEXCOORDS) { - write_indice(fp, static_cast(texCoords[i])); + if (indexMask & SG_IDX_TEXCOORDS_0) { + write_indice(fp, static_cast(texCoords[0][i])); + } + if (indexMask & SG_IDX_TEXCOORDS_1) { + write_indice(fp, static_cast(texCoords[1][i])); + } + if (indexMask & SG_IDX_TEXCOORDS_2) { + write_indice(fp, static_cast(texCoords[2][i])); + } + if (indexMask & SG_IDX_TEXCOORDS_3) { + write_indice(fp, static_cast(texCoords[3][i])); + } + + if (vaMask) { + if (vaMask & SG_VA_INTEGER_0) { + write_indice(fp, static_cast(vas[0][i])); + } + if (vaMask & SG_VA_INTEGER_1) { + write_indice(fp, static_cast(vas[1][i])); + } + if (vaMask & SG_VA_INTEGER_2) { + write_indice(fp, static_cast(vas[2][i])); + } + if (vaMask & SG_VA_INTEGER_3) { + write_indice(fp, static_cast(vas[3][i])); + } + + if (vaMask & SG_VA_FLOAT_0) { + write_indice(fp, static_cast(vas[4][i])); + } + if (vaMask & SG_VA_FLOAT_1) { + write_indice(fp, static_cast(vas[5][i])); + } + if (vaMask & SG_VA_FLOAT_2) { + write_indice(fp, static_cast(vas[6][i])); + } + if (vaMask & SG_VA_FLOAT_3) { + write_indice(fp, static_cast(vas[7][i])); + } } } } @@ -281,13 +370,15 @@ void SGBinObject::read_object( gzFile fp, int nproperties, int nelements, group_list& vertices, - group_list& normals, - group_list& colors, - group_list& texCoords, - string_list& materials) + group_list& normals, + group_list& colors, + group_tci_list& texCoords, + group_vai_list& vertexAttribs, + string_list& materials) { - unsigned int nbytes; + unsigned int nbytes; unsigned char idx_mask; + unsigned int vertex_attrib_mask; int j; sgSimpleBuffer buf( 32768 ); // 32 Kb char material[256]; @@ -296,26 +387,49 @@ void SGBinObject::read_object( gzFile fp, if ( obj_type == SG_POINTS ) { idx_mask = SG_IDX_VERTICES; } else { - idx_mask = (char)(SG_IDX_VERTICES | SG_IDX_TEXCOORDS); + idx_mask = (char)(SG_IDX_VERTICES | SG_IDX_TEXCOORDS_0); } - + vertex_attrib_mask = 0; + for ( j = 0; j < nproperties; ++j ) { char prop_type; sgReadChar( fp, &prop_type ); sgReadUInt( fp, &nbytes ); + buf.resize(nbytes); char *ptr = buf.get_ptr(); - sgReadBytes( fp, nbytes, ptr ); - if ( prop_type == SG_MATERIAL ) { - if (nbytes > 255) { - nbytes = 255; - } - strncpy( material, ptr, nbytes ); - material[nbytes] = '\0'; - // cout << "material type = " << material << endl; - } else if ( prop_type == SG_INDEX_TYPES ) { - idx_mask = ptr[0]; - //cout << std::hex << "index mask:" << idx_mask << std::dec << endl; + + switch( prop_type ) + { + case SG_MATERIAL: + sgReadBytes( fp, nbytes, ptr ); + if (nbytes > 255) { + nbytes = 255; + } + strncpy( material, ptr, nbytes ); + material[nbytes] = '\0'; + break; + + case SG_INDEX_TYPES: + if (nbytes == 1) { + sgReadChar( fp, (char *)&idx_mask ); + } else { + sgReadBytes( fp, nbytes, ptr ); + } + break; + + case SG_VERT_ATTRIBS: + if (nbytes == 4) { + sgReadUInt( fp, &vertex_attrib_mask ); + } else { + sgReadBytes( fp, nbytes, ptr ); + } + break; + + default: + sgReadBytes( fp, nbytes, ptr ); + SG_LOG(SG_IO, SG_ALERT, "Found UNKNOWN property type with nbytes == " << nbytes << " mask is " << (int)idx_mask ); + break; } } @@ -345,17 +459,20 @@ void SGBinObject::read_object( gzFile fp, int_list vs; int_list ns; int_list cs; - int_list tcs; + tci_list tcs; + vai_list vas; + if (version >= 10) { - read_indices(ptr, nbytes, idx_mask, vs, ns, cs, tcs); + read_indices(ptr, nbytes, idx_mask, vertex_attrib_mask, vs, ns, cs, tcs, vas ); } else { - read_indices(ptr, nbytes, idx_mask, vs, ns, cs, tcs); + read_indices(ptr, nbytes, idx_mask, vertex_attrib_mask, vs, ns, cs, tcs, vas ); } vertices.push_back( vs ); normals.push_back( ns ); colors.push_back( cs ); texCoords.push_back( tcs ); + vertexAttribs.push_back( vas ); materials.push_back( material ); } // of element iteration } @@ -380,25 +497,29 @@ bool SGBinObject::read_bin( const string& file ) { pts_v.clear(); pts_n.clear(); pts_c.clear(); - pts_tc.clear(); + pts_tcs.clear(); + pts_vas.clear(); pt_materials.clear(); tris_v.clear(); tris_n.clear(); tris_c.clear(); - tris_tc.clear(); + tris_tcs.clear(); + tris_vas.clear(); tri_materials.clear(); strips_v.clear(); strips_n.clear(); strips_c.clear(); - strips_tc.clear(); + strips_tcs.clear(); + strips_vas.clear(); strip_materials.clear(); fans_v.clear(); fans_n.clear(); fans_c.clear(); - fans_tc.clear(); + fans_tcs.clear(); + fans_vas.clear(); fan_materials.clear(); gzFile fp; @@ -419,10 +540,9 @@ bool SGBinObject::read_bin( const string& file ) { sgReadUInt( fp, &header ); if ( ((header & 0xFF000000) >> 24) == 'S' && ((header & 0x00FF0000) >> 16) == 'G' ) { - // cout << "Good header" << endl; + // read file version version = (header & 0x0000FFFF); - // cout << "File version = " << version << endl; } else { // close the file before we return gzclose(fp); @@ -460,7 +580,7 @@ bool SGBinObject::read_bin( const string& file ) { nobjects = v; } - //cout << "Total objects to read = " << nobjects << endl; + SG_LOG(SG_IO, SG_DEBUG, "SGBinObject::read_bin Total objects to read = " << nobjects); if ( sgReadError() ) { throw sg_io_exception("Error reading BTG file header", sg_location(file)); @@ -489,9 +609,10 @@ bool SGBinObject::read_bin( const string& file ) { nelements = v; } - //cout << "object " << i << " = " << (int)obj_type << " props = " - // << nproperties << " elements = " << nelements << endl; - + SG_LOG(SG_IO, SG_DEBUG, "SGBinObject::read_bin object " << i << + " = " << (int)obj_type << " props = " << nproperties << + " elements = " << nelements); + if ( obj_type == SG_BOUNDING_SPHERE ) { // read bounding sphere properties read_properties( fp, nproperties ); @@ -521,7 +642,7 @@ bool SGBinObject::read_bin( const string& file ) { wgs84_nodes.reserve( count ); for ( k = 0; k < count; ++k ) { SGVec3f v = buf.readVec3f(); - // extend from float to double, hmmm + // extend from float to double, hmmm wgs84_nodes.push_back( SGVec3d(v[0], v[1], v[2]) ); } } @@ -581,23 +702,60 @@ bool SGBinObject::read_bin( const string& file ) { texcoords.push_back( buf.readVec2f() ); } } + } else if ( obj_type == SG_VA_FLOAT_LIST ) { + // read vertex attribute (float) properties + read_properties( fp, nproperties ); + + // read vertex attribute list elements + for ( j = 0; j < nelements; ++j ) { + sgReadUInt( fp, &nbytes ); + buf.resize( nbytes ); + buf.reset(); + char *ptr = buf.get_ptr(); + sgReadBytes( fp, nbytes, ptr ); + int count = nbytes / (sizeof(float)); + va_flt.reserve(count); + for ( k = 0; k < count; ++k ) { + va_flt.push_back( buf.readFloat() ); + } + } + } else if ( obj_type == SG_VA_INTEGER_LIST ) { + // read vertex attribute (integer) properties + read_properties( fp, nproperties ); + + // read vertex attribute list elements + for ( j = 0; j < nelements; ++j ) { + sgReadUInt( fp, &nbytes ); + buf.resize( nbytes ); + buf.reset(); + char *ptr = buf.get_ptr(); + sgReadBytes( fp, nbytes, ptr ); + int count = nbytes / (sizeof(unsigned int)); + va_int.reserve(count); + for ( k = 0; k < count; ++k ) { + va_int.push_back( buf.readInt() ); + } + } } else if ( obj_type == SG_POINTS ) { // read point elements read_object( fp, SG_POINTS, nproperties, nelements, - pts_v, pts_n, pts_c, pts_tc, pt_materials ); + pts_v, pts_n, pts_c, pts_tcs, + pts_vas, pt_materials ); } else if ( obj_type == SG_TRIANGLE_FACES ) { // read triangle face properties read_object( fp, SG_TRIANGLE_FACES, nproperties, nelements, - tris_v, tris_n, tris_c, tris_tc, tri_materials ); + tris_v, tris_n, tris_c, tris_tcs, + tris_vas, tri_materials ); } else if ( obj_type == SG_TRIANGLE_STRIPS ) { // read triangle strip properties read_object( fp, SG_TRIANGLE_STRIPS, nproperties, nelements, - strips_v, strips_n, strips_c, strips_tc, - strip_materials ); + strips_v, strips_n, strips_c, strips_tcs, + strips_vas, strip_materials ); } else if ( obj_type == SG_TRIANGLE_FANS ) { // read triangle fan properties read_object( fp, SG_TRIANGLE_FANS, nproperties, nelements, - fans_v, fans_n, fans_c, fans_tc, fan_materials ); + fans_v, fans_n, fans_c, fans_tcs, + fans_vas, fan_materials ); } else { // unknown object type, just skip read_properties( fp, nproperties ); @@ -652,9 +810,13 @@ unsigned int SGBinObject::count_objects(const string_list& materials) return result; } -void SGBinObject::write_objects(gzFile fp, int type, const group_list& verts, - const group_list& normals, const group_list& colors, - const group_list& texCoords, const string_list& materials) +void SGBinObject::write_objects(gzFile fp, int type, + const group_list& verts, + const group_list& normals, + const group_list& colors, + const group_tci_list& texCoords, + const group_vai_list& vertexAttribs, + const string_list& materials) { if (verts.empty()) { return; @@ -666,45 +828,77 @@ void SGBinObject::write_objects(gzFile fp, int type, const group_list& verts, while (start < materials.size()) { m = materials[start]; - // find range of objects with identical material, write out as a single object + // find range of objects with identical material, write out as a single object for (end = start+1; (end < materials.size()) && (m == materials[end]); ++end) {} + // calc the number of elements const int count = end - start; - write_header(fp, type, 2, count); + + // calc the number of properties + unsigned int va_mask = 0; + unsigned int va_count = vertexAttribs.size(); + for ( unsigned int va=0; va #include +#include -/** STL Structure used to store object information */ +#define MAX_TC_SETS (4) +#define MAX_VAS (8) + +// I really want to pass around fixed length arrays, as the size +// has to be hardcoded +// but it's a C++0x feature use boost in its absence +typedef boost::array tci_list; +typedef boost::array vai_list; + +/** STL Structure used to store (integer index) object information */ typedef std::vector < int_list > group_list; typedef group_list::iterator group_list_iterator; typedef group_list::const_iterator const_group_list_iterator; +/** STL Structure used to store (tc index) object information */ +typedef std::vector < tci_list > group_tci_list; +typedef group_tci_list::iterator group_tci_list_iterator; +typedef group_tci_list::const_iterator const_group_tci_list_iterator; + +/** STL Structure used to store (va index) object information */ +typedef std::vector < vai_list > group_vai_list; +typedef group_vai_list::iterator group_vai_list_iterator; +typedef group_vai_list::const_iterator const_group_vai_list_iterator; + + // forward decls class SGBucket; class SGPath; +class SGBinObjectPoint { +public: + std::string material; + int_list v_list; + int_list n_list; + int_list c_list; + + void clear( void ) { + material = ""; + v_list.clear(); + n_list.clear(); + c_list.clear(); + }; +}; + +class SGBinObjectTriangle { +public: + std::string material; + int_list v_list; + int_list n_list; + int_list c_list; + + tci_list tc_list; + vai_list va_list; + + void clear( void ) { + material = ""; + v_list.clear(); + n_list.clear(); + c_list.clear(); + for ( unsigned int i=0; i wgs84_nodes; // vertex list - std::vector colors; // color list - std::vector normals; // normal list - std::vector texcoords; // texture coordinate list - - group_list pts_v; // points vertex index - group_list pts_n; // points normal index - group_list pts_c; // points color index - group_list pts_tc; // points texture coordinate index - string_list pt_materials; // points materials - - group_list tris_v; // triangles vertex index - group_list tris_n; // triangles normal index - group_list tris_c; // triangles color index - group_list tris_tc; // triangles texture coordinate index - string_list tri_materials; // triangles materials - - group_list strips_v; // tristrips vertex index - group_list strips_n; // tristrips normal index - group_list strips_c; // tristrips color index - group_list strips_tc; // tristrips texture coordinate index - string_list strip_materials;// tristrips materials - - group_list fans_v; // fans vertex index - group_list fans_n; // fans normal index - group_list fans_c; // fans color index - group_list fans_tc; // fans texture coordinate index - string_list fan_materials; // fans materials + std::vector wgs84_nodes; // vertex list + std::vector colors; // color list + std::vector normals; // normal list + std::vector texcoords; // texture coordinate list + std::vector va_flt; // vertex attribute list (floats) + std::vector va_int; // vertex attribute list (ints) + + group_list pts_v; // points vertex index + group_list pts_n; // points normal index + group_list pts_c; // points color index + group_tci_list pts_tcs; // points texture coordinates ( up to 4 sets ) + group_vai_list pts_vas; // points vertex attributes ( up to 8 sets ) + string_list pt_materials; // points materials + + group_list tris_v; // triangles vertex index + group_list tris_n; // triangles normal index + group_list tris_c; // triangles color index + group_tci_list tris_tcs; // triangles texture coordinates ( up to 4 sets ) + group_vai_list tris_vas; // triangles vertex attributes ( up to 8 sets ) + string_list tri_materials; // triangles materials + + group_list strips_v; // tristrips vertex index + group_list strips_n; // tristrips normal index + group_list strips_c; // tristrips color index + group_tci_list strips_tcs; // tristrips texture coordinates ( up to 4 sets ) + group_vai_list strips_vas; // tristrips vertex attributes ( up to 8 sets ) + string_list strip_materials; // tristrips materials + + group_list fans_v; // fans vertex index + group_list fans_n; // fans normal index + group_list fans_c; // fans color index + group_tci_list fans_tcs; // fanss texture coordinates ( up to 4 sets ) + group_vai_list fans_vas; // fans vertex attributes ( up to 8 sets ) + string_list fan_materials; // fans materials void read_properties(gzFile fp, int nproperties); @@ -124,17 +193,23 @@ private: group_list& vertices, group_list& normals, group_list& colors, - group_list& texCoords, + group_tci_list& texCoords, + group_vai_list& vertexAttribs, string_list& materials); void write_header(gzFile fp, int type, int nProps, int nElements); - void write_objects(gzFile fp, int type, const group_list& verts, - const group_list& normals, const group_list& colors, - const group_list& texCoords, const string_list& materials); + void write_objects(gzFile fp, + int type, + const group_list& verts, + const group_list& normals, + const group_list& colors, + const group_tci_list& texCoords, + const group_vai_list& vertexAttribs, + const string_list& materials); unsigned int count_objects(const string_list& materials); -public: - + +public: inline unsigned short get_version() const { return version; } inline const SGVec3d& get_gbs_center() const { return gbs_center; } @@ -143,10 +218,8 @@ public: inline float get_gbs_radius() const { return gbs_radius; } inline void set_gbs_radius( float r ) { gbs_radius = r; } - inline const std::vector& get_wgs84_nodes() const - { return wgs84_nodes; } - inline void set_wgs84_nodes( const std::vector& n ) - { wgs84_nodes = n; } + inline const std::vector& get_wgs84_nodes() const { return wgs84_nodes; } + inline void set_wgs84_nodes( const std::vector& n ) { wgs84_nodes = n; } inline const std::vector& get_colors() const { return colors; } inline void set_colors( const std::vector& c ) { colors = c; } @@ -157,51 +230,38 @@ public: inline const std::vector& get_texcoords() const { return texcoords; } inline void set_texcoords( const std::vector& t ) { texcoords = t; } + // Points API + bool add_point( const SGBinObjectPoint& pt ); inline const group_list& get_pts_v() const { return pts_v; } - inline void set_pts_v( const group_list& g ) { pts_v = g; } - inline const group_list& get_pts_n() const { return pts_n; } - inline void set_pts_n( const group_list& g ) { pts_n = g; } - inline const group_list& get_pts_c() const { return pts_c; } - inline void set_pts_c( const group_list& g ) { pts_c = g; } - inline const group_list& get_pts_tc() const { return pts_tc; } - inline void set_pts_tc( const group_list& g ) { pts_tc = g; } + inline const group_list& get_pts_n() const { return pts_n; } + inline const group_tci_list& get_pts_tcs() const { return pts_tcs; } + inline const group_vai_list& get_pts_vas() const { return pts_vas; } inline const string_list& get_pt_materials() const { return pt_materials; } - inline void set_pt_materials( const string_list& s ) { pt_materials = s; } + // Triangles API + bool add_triangle( const SGBinObjectTriangle& tri ); inline const group_list& get_tris_v() const { return tris_v; } - inline void set_tris_v( const group_list& g ) { tris_v = g; } inline const group_list& get_tris_n() const { return tris_n; } - inline void set_tris_n( const group_list& g ) { tris_n = g; } inline const group_list& get_tris_c() const { return tris_c; } - inline void set_tris_c( const group_list& g ) { tris_c = g; } - inline const group_list& get_tris_tc() const { return tris_tc; } - inline void set_tris_tc( const group_list& g ) { tris_tc = g; } + inline const group_tci_list& get_tris_tcs() const { return tris_tcs; } + inline const group_vai_list& get_tris_vas() const { return tris_vas; } inline const string_list& get_tri_materials() const { return tri_materials; } - inline void set_tri_materials( const string_list& s ) { tri_materials = s; } + // Strips API (deprecated - read only) inline const group_list& get_strips_v() const { return strips_v; } - inline void set_strips_v( const group_list& g ) { strips_v = g; } inline const group_list& get_strips_n() const { return strips_n; } - inline void set_strips_n( const group_list& g ) { strips_n = g; } inline const group_list& get_strips_c() const { return strips_c; } - inline void set_strips_c( const group_list& g ) { strips_c = g; } - - inline const group_list& get_strips_tc() const { return strips_tc; } - inline void set_strips_tc( const group_list& g ) { strips_tc = g; } + inline const group_tci_list& get_strips_tcs() const { return strips_tcs; } + inline const group_vai_list& get_strips_vas() const { return strips_vas; } inline const string_list& get_strip_materials() const { return strip_materials; } - inline void set_strip_materials( const string_list& s ) { strip_materials = s; } - + + // Fans API (deprecated - read only ) inline const group_list& get_fans_v() const { return fans_v; } - inline void set_fans_v( const group_list& g ) { fans_v = g; } inline const group_list& get_fans_n() const { return fans_n; } - inline void set_fans_n( const group_list& g ) { fans_n = g; } inline const group_list& get_fans_c() const { return fans_c; } - inline void set_fans_c( const group_list& g ) { fans_c = g; } - - inline const group_list& get_fans_tc() const { return fans_tc; } - inline void set_fans_tc( const group_list& g ) { fans_tc = g; } + inline const group_tci_list& get_fans_tcs() const { return fans_tcs; } + inline const group_vai_list& get_fans_vas() const { return fans_vas; } inline const string_list& get_fan_materials() const { return fan_materials; } - inline void set_fan_materials( const string_list& s ) { fan_materials = s; } /** * Read a binary file object and populate the provided structures. diff --git a/simgear/io/test_binobj.cxx b/simgear/io/test_binobj.cxx index 00b69790..f51a9a19 100644 --- a/simgear/io/test_binobj.cxx +++ b/simgear/io/test_binobj.cxx @@ -103,6 +103,15 @@ int_list make_tri(int maxIndex) return r; } +tci_list make_tri_tcs(int maxIndex) +{ + tci_list tci; + tci[0].push_back(random() % maxIndex); + tci[0].push_back(random() % maxIndex); + tci[0].push_back(random() % maxIndex); + return tci; +} + void compareTris(const SGBinObject& a, const SGBinObject& b) { unsigned int count = a.get_tri_materials().size(); @@ -113,32 +122,31 @@ void compareTris(const SGBinObject& a, const SGBinObject& b) COMPARE(a.get_tri_materials()[i], b.get_tri_materials()[i]); - const int_list& tA(a.get_tris_tc()[i]); - const int_list& tB(b.get_tris_tc()[i]); + const int_list& tA(a.get_tris_tcs()[i][0]); + const int_list& tB(b.get_tris_tcs()[i][0]); VERIFY(tA == tB); } } void generate_tris(SGBinObject& b, int count) { - group_list v, n, tc; + group_list v, n; + group_tci_list tc; string_list materials; int maxVertices = b.get_wgs84_nodes().size(); int maxNormals = b.get_normals().size(); int maxTCs = b.get_texcoords().size(); + SGBinObjectTriangle sgboTri; for (int t=0; tpush_back(osg::Vec4(1, 1, 1, 1)); @@ -341,7 +379,12 @@ public: geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); geometry->setColorArray(colors); geometry->setColorBinding(osg::Geometry::BIND_OVERALL); - geometry->setTexCoordArray(0, texCoords); + if ( has_sec_tcs ) { + geometry->setTexCoordArray(0, priTexCoords); + geometry->setTexCoordArray(1, secTexCoords); + } else { + geometry->setTexCoordArray(0, priTexCoords); + } const unsigned invalid = ~unsigned(0); std::vector indexMap(getNumVertices(), invalid); @@ -351,25 +394,34 @@ public: triangle_ref triangle = triangles[i]; if (indexMap[triangle[0]] == invalid) { indexMap[triangle[0]] = vertices->size(); - vertices->push_back(toOsg(getVertex(triangle[0]).vertex)); - normals->push_back(toOsg(getVertex(triangle[0]).normal)); - texCoords->push_back(toOsg(getVertex(triangle[0]).texCoord)); + vertices->push_back(toOsg(getVertex(triangle[0]).GetVertex())); + normals->push_back(toOsg(getVertex(triangle[0]).GetNormal())); + priTexCoords->push_back(toOsg(getVertex(triangle[0]).GetTexCoord(0))); + if ( has_sec_tcs ) { + secTexCoords->push_back(toOsg(getVertex(triangle[0]).GetTexCoord(1))); + } } deFacade.push_back(indexMap[triangle[0]]); if (indexMap[triangle[1]] == invalid) { indexMap[triangle[1]] = vertices->size(); - vertices->push_back(toOsg(getVertex(triangle[1]).vertex)); - normals->push_back(toOsg(getVertex(triangle[1]).normal)); - texCoords->push_back(toOsg(getVertex(triangle[1]).texCoord)); + vertices->push_back(toOsg(getVertex(triangle[1]).GetVertex())); + normals->push_back(toOsg(getVertex(triangle[1]).GetNormal())); + priTexCoords->push_back(toOsg(getVertex(triangle[1]).GetTexCoord(0))); + if ( has_sec_tcs ) { + secTexCoords->push_back(toOsg(getVertex(triangle[1]).GetTexCoord(1))); + } } deFacade.push_back(indexMap[triangle[1]]); if (indexMap[triangle[2]] == invalid) { indexMap[triangle[2]] = vertices->size(); - vertices->push_back(toOsg(getVertex(triangle[2]).vertex)); - normals->push_back(toOsg(getVertex(triangle[2]).normal)); - texCoords->push_back(toOsg(getVertex(triangle[2]).texCoord)); + vertices->push_back(toOsg(getVertex(triangle[2]).GetVertex())); + normals->push_back(toOsg(getVertex(triangle[2]).GetNormal())); + priTexCoords->push_back(toOsg(getVertex(triangle[2]).GetTexCoord(0))); + if ( has_sec_tcs ) { + secTexCoords->push_back(toOsg(getVertex(triangle[2]).GetTexCoord(1))); + } } deFacade.push_back(indexMap[triangle[2]]); } @@ -387,14 +439,19 @@ public: return 0; triangle_ref triangleRef = getTriangleRef(0); - SGVec3f v0 = getVertex(triangleRef[0]).vertex; + SGVec3f v0 = getVertex(triangleRef[0]).GetVertex(); return floor(v0.x()); } + + void hasSecondaryTexCoord( bool sec_tc ) { has_sec_tcs = sec_tc; } private: // Random seed for the triangle. mt seed; + + // does the triangle array have secondary texture coordinates + bool has_sec_tcs; }; #endif diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx index 8885e405..1b55325d 100644 --- a/simgear/scene/tgdb/obj.cxx +++ b/simgear/scene/tgdb/obj.cxx @@ -219,72 +219,107 @@ public: static void addTriangleGeometry(SGTexturedTriangleBin& triangles, - const std::vector& vertices, - const std::vector& normals, - const std::vector& texCoords, - const int_list& tris_v, - const int_list& tris_n, - const int_list& tris_tc, - const SGVec2f& tcScale) + const SGBinObject& obj, unsigned grp, + const SGVec2f& tc0Scale, + const SGVec2f& tc1Scale) { + const std::vector& vertices(obj.get_wgs84_nodes()); + const std::vector& normals(obj.get_normals()); + const std::vector& texCoords(obj.get_texcoords()); + const int_list& tris_v(obj.get_tris_v()[grp]); + const int_list& tris_n(obj.get_tris_n()[grp]); + const tci_list& tris_tc(obj.get_tris_tcs()[grp]); + bool num_norms_is_num_verts = true; + if (tris_v.size() != tris_n.size()) { - // If the normal indices do not match, they should be inmplicitly - // the same than the vertex indices. So just call ourselves again - // with the matching index vector. - addTriangleGeometry(triangles, vertices, normals, texCoords, - tris_v, tris_v, tris_tc, tcScale); - return; + // If the normal indices do not match, they should be inmplicitly + // the same than the vertex indices. + num_norms_is_num_verts = false; } + if ( !tris_tc[1].empty() ) { + triangles.hasSecondaryTexCoord(true); + } + for (unsigned i = 2; i < tris_v.size(); i += 3) { - SGVertNormTex v0; - v0.vertex = toVec3f(vertices[tris_v[i-2]]); - v0.normal = normals[tris_n[i-2]]; - v0.texCoord = getTexCoord(texCoords, tris_tc, tcScale, i-2); - SGVertNormTex v1; - v1.vertex = toVec3f(vertices[tris_v[i-1]]); - v1.normal = normals[tris_n[i-1]]; - v1.texCoord = getTexCoord(texCoords, tris_tc, tcScale, i-1); - SGVertNormTex v2; - v2.vertex = toVec3f(vertices[tris_v[i]]); - v2.normal = normals[tris_n[i]]; - v2.texCoord = getTexCoord(texCoords, tris_tc, tcScale, i); - triangles.insert(v0, v1, v2); + SGVertNormTex v0; + v0.SetVertex( toVec3f(vertices[tris_v[i-2]]) ); + v0.SetNormal( num_norms_is_num_verts ? normals[tris_n[i-2]] : + normals[tris_v[i-2]] ); + v0.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i-2) ); + if (!tris_tc[1].empty()) { + v0.SetTexCoord( 1, getTexCoord(texCoords, tris_tc[1], tc1Scale, i-2) ); + } + SGVertNormTex v1; + v1.SetVertex( toVec3f(vertices[tris_v[i-1]]) ); + v1.SetNormal( num_norms_is_num_verts ? normals[tris_n[i-1]] : + normals[tris_v[i-1]] ); + v1.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i-1) ); + if (!tris_tc[1].empty()) { + v1.SetTexCoord( 1, getTexCoord(texCoords, tris_tc[1], tc1Scale, i-1) ); + } + SGVertNormTex v2; + v2.SetVertex( toVec3f(vertices[tris_v[i]]) ); + v2.SetNormal( num_norms_is_num_verts ? normals[tris_n[i]] : + normals[tris_v[i]] ); + v2.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i) ); + if (!tris_tc[1].empty()) { + v2.SetTexCoord( 1, getTexCoord(texCoords, tris_tc[1], tc1Scale, i) ); + } + + triangles.insert(v0, v1, v2); } } static void addStripGeometry(SGTexturedTriangleBin& triangles, - const std::vector& vertices, - const std::vector& normals, - const std::vector& texCoords, - const int_list& strips_v, - const int_list& strips_n, - const int_list& strips_tc, - const SGVec2f& tcScale) + const SGBinObject& obj, unsigned grp, + const SGVec2f& tc0Scale, + const SGVec2f& tc1Scale) { - if (strips_v.size() != strips_n.size()) { - // If the normal indices do not match, they should be inmplicitly - // the same than the vertex indices. So just call ourselves again - // with the matching index vector. - addStripGeometry(triangles, vertices, normals, texCoords, - strips_v, strips_v, strips_tc, tcScale); - return; - } - + const std::vector& vertices(obj.get_wgs84_nodes()); + const std::vector& normals(obj.get_normals()); + const std::vector& texCoords(obj.get_texcoords()); + const int_list& strips_v(obj.get_strips_v()[grp]); + const int_list& strips_n(obj.get_strips_n()[grp]); + const tci_list& strips_tc(obj.get_strips_tcs()[grp]); + bool num_norms_is_num_verts = true; + + if (strips_v.size() != strips_n.size()) { + // If the normal indices do not match, they should be inmplicitly + // the same than the vertex indices. + num_norms_is_num_verts = false; + } + + if ( !strips_tc[1].empty() ) { + triangles.hasSecondaryTexCoord(true); + } + for (unsigned i = 2; i < strips_v.size(); ++i) { SGVertNormTex v0; - v0.vertex = toVec3f(vertices[strips_v[i-2]]); - v0.normal = normals[strips_n[i-2]]; - v0.texCoord = getTexCoord(texCoords, strips_tc, tcScale, i-2); + v0.SetVertex( toVec3f(vertices[strips_v[i-2]]) ); + v0.SetNormal( num_norms_is_num_verts ? normals[strips_n[i-2]] : + normals[strips_v[i-2]] ); + v0.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[0], tc0Scale, i-2) ); + if (!strips_tc[1].empty()) { + v0.SetTexCoord( 1, getTexCoord(texCoords, strips_tc[1], tc1Scale, i-2) ); + } SGVertNormTex v1; - v1.vertex = toVec3f(vertices[strips_v[i-1]]); - v1.normal = normals[strips_n[i-1]]; - v1.texCoord = getTexCoord(texCoords, strips_tc, tcScale, i-1); + v1.SetVertex( toVec3f(vertices[strips_v[i-1]]) ); + v1.SetNormal( num_norms_is_num_verts ? normals[strips_n[i-1]] : + normals[strips_v[i-1]] ); + v1.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[1], tc0Scale, i-1) ); + if (!strips_tc[1].empty()) { + v1.SetTexCoord( 1, getTexCoord(texCoords, strips_tc[1], tc1Scale, i-1) ); + } SGVertNormTex v2; - v2.vertex = toVec3f(vertices[strips_v[i]]); - v2.normal = normals[strips_n[i]]; - v2.texCoord = getTexCoord(texCoords, strips_tc, tcScale, i); + v2.SetVertex( toVec3f(vertices[strips_v[i]]) ); + v2.SetNormal( num_norms_is_num_verts ? normals[strips_n[i]] : + normals[strips_v[i]] ); + v2.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[0], tc0Scale, i) ); + if (!strips_tc[1].empty()) { + v2.SetTexCoord( 1, getTexCoord(texCoords, strips_tc[1], tc1Scale, i) ); + } if (i%2) triangles.insert(v1, v0, v2); else @@ -294,36 +329,53 @@ public: static void addFanGeometry(SGTexturedTriangleBin& triangles, - const std::vector& vertices, - const std::vector& normals, - const std::vector& texCoords, - const int_list& fans_v, - const int_list& fans_n, - const int_list& fans_tc, - const SGVec2f& tcScale) + const SGBinObject& obj, unsigned grp, + const SGVec2f& tc0Scale, + const SGVec2f& tc1Scale) { - if (fans_v.size() != fans_n.size()) { - // If the normal indices do not match, they should be implicitly - // the same than the vertex indices. So just call ourselves again - // with the matching index vector. - addFanGeometry(triangles, vertices, normals, texCoords, - fans_v, fans_v, fans_tc, tcScale); - return; - } - + const std::vector& vertices(obj.get_wgs84_nodes()); + const std::vector& normals(obj.get_normals()); + const std::vector& texCoords(obj.get_texcoords()); + const int_list& fans_v(obj.get_fans_v()[grp]); + const int_list& fans_n(obj.get_fans_n()[grp]); + const tci_list& fans_tc(obj.get_fans_tcs()[grp]); + bool num_norms_is_num_verts = true; + + if (fans_v.size() != fans_n.size()) { + // If the normal indices do not match, they should be inmplicitly + // the same than the vertex indices. + num_norms_is_num_verts = false; + } + + if ( !fans_tc[1].empty() ) { + triangles.hasSecondaryTexCoord(true); + } + SGVertNormTex v0; - v0.vertex = toVec3f(vertices[fans_v[0]]); - v0.normal = normals[fans_n[0]]; - v0.texCoord = getTexCoord(texCoords, fans_tc, tcScale, 0); + v0.SetVertex( toVec3f(vertices[fans_v[0]]) ); + v0.SetNormal( num_norms_is_num_verts ? normals[fans_n[0]] : + normals[fans_v[0]] ); + v0.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, 0) ); + if (!fans_tc[1].empty()) { + v0.SetTexCoord( 1, getTexCoord(texCoords, fans_tc[1], tc1Scale, 0) ); + } SGVertNormTex v1; - v1.vertex = toVec3f(vertices[fans_v[1]]); - v1.normal = normals[fans_n[1]]; - v1.texCoord = getTexCoord(texCoords, fans_tc, tcScale, 1); + v1.SetVertex( toVec3f(vertices[fans_v[1]]) ); + v1.SetNormal( num_norms_is_num_verts ? normals[fans_n[1]] : + normals[fans_v[1]] ); + v1.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, 1) ); + if (!fans_tc[1].empty()) { + v1.SetTexCoord( 1, getTexCoord(texCoords, fans_tc[1], tc1Scale, 1) ); + } for (unsigned i = 2; i < fans_v.size(); ++i) { SGVertNormTex v2; - v2.vertex = toVec3f(vertices[fans_v[i]]); - v2.normal = normals[fans_n[i]]; - v2.texCoord = getTexCoord(texCoords, fans_tc, tcScale, i); + v2.SetVertex( toVec3f(vertices[fans_v[i]]) ); + v2.SetNormal( num_norms_is_num_verts ? normals[fans_n[i]] : + normals[fans_v[i]] ); + v2.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, i) ); + if (!fans_tc[1].empty()) { + v2.SetTexCoord( 1, getTexCoord(texCoords, fans_tc[1], tc1Scale, i) ); + } triangles.insert(v0, v1, v2); v1 = v2; } @@ -344,7 +396,7 @@ public: insertSurfaceGeometry(const SGBinObject& obj, SGMaterialLib* matlib) { if (obj.get_tris_n().size() < obj.get_tris_v().size() || - obj.get_tris_tc().size() < obj.get_tris_v().size()) { + obj.get_tris_tcs().size() < obj.get_tris_v().size()) { SG_LOG(SG_TERRAIN, SG_ALERT, "Group list sizes for triangles do not match!"); return false; @@ -352,44 +404,38 @@ public: for (unsigned grp = 0; grp < obj.get_tris_v().size(); ++grp) { std::string materialName = obj.get_tri_materials()[grp]; - SGVec2f tcScale = getTexCoordScale(materialName, matlib); + SGVec2f tc0Scale = getTexCoordScale(materialName, matlib); + SGVec2f tc1Scale(1.0, 1.0); addTriangleGeometry(materialTriangleMap[materialName], - obj.get_wgs84_nodes(), obj.get_normals(), - obj.get_texcoords(), obj.get_tris_v()[grp], - obj.get_tris_n()[grp], obj.get_tris_tc()[grp], - tcScale); + obj, grp, tc0Scale, tc1Scale ); } if (obj.get_strips_n().size() < obj.get_strips_v().size() || - obj.get_strips_tc().size() < obj.get_strips_v().size()) { + obj.get_strips_tcs().size() < obj.get_strips_v().size()) { SG_LOG(SG_TERRAIN, SG_ALERT, "Group list sizes for strips do not match!"); return false; } for (unsigned grp = 0; grp < obj.get_strips_v().size(); ++grp) { std::string materialName = obj.get_strip_materials()[grp]; - SGVec2f tcScale = getTexCoordScale(materialName, matlib); + SGVec2f tc0Scale = getTexCoordScale(materialName, matlib); + SGVec2f tc1Scale(1.0, 1.0); addStripGeometry(materialTriangleMap[materialName], - obj.get_wgs84_nodes(), obj.get_normals(), - obj.get_texcoords(), obj.get_strips_v()[grp], - obj.get_strips_n()[grp], obj.get_strips_tc()[grp], - tcScale); + obj, grp, tc0Scale, tc1Scale); } if (obj.get_fans_n().size() < obj.get_fans_v().size() || - obj.get_fans_tc().size() < obj.get_fans_v().size()) { + obj.get_fans_tcs().size() < obj.get_fans_v().size()) { SG_LOG(SG_TERRAIN, SG_ALERT, "Group list sizes for fans do not match!"); return false; } for (unsigned grp = 0; grp < obj.get_fans_v().size(); ++grp) { std::string materialName = obj.get_fan_materials()[grp]; - SGVec2f tcScale = getTexCoordScale(materialName, matlib); + SGVec2f tc0Scale = getTexCoordScale(materialName, matlib); + SGVec2f tc1Scale(1.0, 1.0); addFanGeometry(materialTriangleMap[materialName], - obj.get_wgs84_nodes(), obj.get_normals(), - obj.get_texcoords(), obj.get_fans_v()[grp], - obj.get_fans_n()[grp], obj.get_fans_tc()[grp], - tcScale); + obj, grp, tc0Scale, tc1Scale ); } return true; } @@ -399,30 +445,37 @@ public: if (materialTriangleMap.empty()) return 0; - EffectGeode* eg = 0; - osg::Group* group = (materialTriangleMap.size() > 1 ? new osg::Group : 0); + EffectGeode* eg = NULL; + osg::Group* group = (materialTriangleMap.size() > 1 ? new osg::Group : NULL); + if (group) { + group->setName("surfaceGeometryGroup"); + } + //osg::Geode* geode = new osg::Geode; SGMaterialTriangleMap::const_iterator i; for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) { osg::Geometry* geometry = i->second.buildGeometry(useVBOs); - SGMaterial *mat = 0; - if (matlib) + SGMaterial *mat = NULL; + if (matlib) { mat = matlib->findCached(i->first); + } eg = new EffectGeode; eg->setName("EffectGeode"); - if (mat) + if (mat) { eg->setEffect(mat->get_effect(i->second)); + } eg->addDrawable(geometry); eg->runGenerators(geometry); // Generate extra data needed by effect if (group) { - group->setName("surfaceGeometryGroup"); group->addChild(eg); } } - if (group) + + if (group) { return group; - else + } else { return eg; + } } void computeRandomSurfaceLights(SGMaterialLib* matlib) @@ -522,12 +575,12 @@ public: for (unsigned i = 0; i < num; ++i) { SGTexturedTriangleBin::triangle_ref triangleRef = triangleBin.getTriangleRef(i); - SGVec3f vorigin = triangleBin.getVertex(triangleRef[0]).vertex; - SGVec3f v0 = triangleBin.getVertex(triangleRef[1]).vertex - vorigin; - SGVec3f v1 = triangleBin.getVertex(triangleRef[2]).vertex - vorigin; - SGVec2f torigin = triangleBin.getVertex(triangleRef[0]).texCoord; - SGVec2f t0 = triangleBin.getVertex(triangleRef[1]).texCoord - torigin; - SGVec2f t1 = triangleBin.getVertex(triangleRef[2]).texCoord - torigin; + SGVec3f vorigin = triangleBin.getVertex(triangleRef[0]).GetVertex(); + SGVec3f v0 = triangleBin.getVertex(triangleRef[1]).GetVertex() - vorigin; + SGVec3f v1 = triangleBin.getVertex(triangleRef[2]).GetVertex() - vorigin; + SGVec2f torigin = triangleBin.getVertex(triangleRef[0]).GetTexCoord(0); + SGVec2f t0 = triangleBin.getVertex(triangleRef[1]).GetTexCoord(0) - torigin; + SGVec2f t1 = triangleBin.getVertex(triangleRef[2]).GetTexCoord(0) - torigin; SGVec3f normal = cross(v0, v1); // Ensure the slope isn't too steep by checking the @@ -941,6 +994,9 @@ public: maxError = propertyNode->getDoubleValue("/sim/rendering/terrain/simplifier/max-error", maxError); } + // PSADRO TODO : we can do this in terragear + // - why not add a bitmask of flags to the btg so we can precompute this? + // and only do it if it hasn't been done already SGVec3d center = tile.get_gbs_center(); SGGeod geodPos = SGGeod::fromCart(center); SGQuatd hlOr = SGQuatd::fromLonLat(geodPos)*SGQuatd::fromEulerDeg(0, 0, 180); -- 2.39.5