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 ) {
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 ) {
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 ) {
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 ) {
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,
};
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
};
}
}
+ float readInt()
+ {
+ unsigned int* p = reinterpret_cast<unsigned int*>(ptr + offset);
+ if ( sgIsBigEndian() ) {
+ sgEndianSwap((uint32_t *) p);
+ }
+
+ offset += sizeof(unsigned int);
+ return *p;
+ }
+
SGVec3d readVec3d()
{
double* p = reinterpret_cast<double*>(ptr + offset);
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<T*>(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
}
template <class T>
-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<T>(vertices[i]));
if (indexMask & SG_IDX_COLORS) {
write_indice(fp, static_cast<T>(colors[i]));
}
- if (indexMask & SG_IDX_TEXCOORDS) {
- write_indice(fp, static_cast<T>(texCoords[i]));
+ if (indexMask & SG_IDX_TEXCOORDS_0) {
+ write_indice(fp, static_cast<T>(texCoords[0][i]));
+ }
+ if (indexMask & SG_IDX_TEXCOORDS_1) {
+ write_indice(fp, static_cast<T>(texCoords[1][i]));
+ }
+ if (indexMask & SG_IDX_TEXCOORDS_2) {
+ write_indice(fp, static_cast<T>(texCoords[2][i]));
+ }
+ if (indexMask & SG_IDX_TEXCOORDS_3) {
+ write_indice(fp, static_cast<T>(texCoords[3][i]));
+ }
+
+ if (vaMask) {
+ if (vaMask & SG_VA_INTEGER_0) {
+ write_indice(fp, static_cast<T>(vas[0][i]));
+ }
+ if (vaMask & SG_VA_INTEGER_1) {
+ write_indice(fp, static_cast<T>(vas[1][i]));
+ }
+ if (vaMask & SG_VA_INTEGER_2) {
+ write_indice(fp, static_cast<T>(vas[2][i]));
+ }
+ if (vaMask & SG_VA_INTEGER_3) {
+ write_indice(fp, static_cast<T>(vas[3][i]));
+ }
+
+ if (vaMask & SG_VA_FLOAT_0) {
+ write_indice(fp, static_cast<T>(vas[4][i]));
+ }
+ if (vaMask & SG_VA_FLOAT_1) {
+ write_indice(fp, static_cast<T>(vas[5][i]));
+ }
+ if (vaMask & SG_VA_FLOAT_2) {
+ write_indice(fp, static_cast<T>(vas[6][i]));
+ }
+ if (vaMask & SG_VA_FLOAT_3) {
+ write_indice(fp, static_cast<T>(vas[7][i]));
+ }
}
}
}
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];
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;
}
}
int_list vs;
int_list ns;
int_list cs;
- int_list tcs;
+ tci_list tcs;
+ vai_list vas;
+
if (version >= 10) {
- read_indices<uint32_t>(ptr, nbytes, idx_mask, vs, ns, cs, tcs);
+ read_indices<uint32_t>(ptr, nbytes, idx_mask, vertex_attrib_mask, vs, ns, cs, tcs, vas );
} else {
- read_indices<uint16_t>(ptr, nbytes, idx_mask, vs, ns, cs, tcs);
+ read_indices<uint16_t>(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
}
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;
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);
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));
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 );
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]) );
}
}
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 );
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;
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<va_count; va++ ) {
+ if ( !vertexAttribs[va].empty() && !vertexAttribs[va].front().empty() ) {
+ va_mask |= ( 1 << va );
+ }
+ }
+
+ if ( va_mask ) {
+ write_header(fp, type, 3, count);
+ } else {
+ write_header(fp, type, 2, count);
+ }
// properties
+ // material property
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, m.length() ); // nbytes
sgWriteBytes( fp, m.length(), m.c_str() );
+ // index mask property
unsigned char idx_mask = 0;
- if ( !verts.empty() && !verts.front().empty()) idx_mask |= SG_IDX_VERTICES;
- if ( !normals.empty() && !normals.front().empty()) idx_mask |= SG_IDX_NORMALS;
- if ( !colors.empty() && !colors.front().empty()) idx_mask |= SG_IDX_COLORS;
- if ( !texCoords.empty() && !texCoords.front().empty()) idx_mask |= SG_IDX_TEXCOORDS;
+ if ( !verts.empty() && !verts[start].empty()) idx_mask |= SG_IDX_VERTICES;
+ if ( !normals.empty() && !normals[start].empty()) idx_mask |= SG_IDX_NORMALS;
+ if ( !colors.empty() && !colors[start].empty()) idx_mask |= SG_IDX_COLORS;
+ if ( !texCoords.empty() && !texCoords[start][0].empty()) idx_mask |= SG_IDX_TEXCOORDS_0;
+ if ( !texCoords.empty() && !texCoords[start][1].empty()) idx_mask |= SG_IDX_TEXCOORDS_1;
+ if ( !texCoords.empty() && !texCoords[start][2].empty()) idx_mask |= SG_IDX_TEXCOORDS_2;
+ if ( !texCoords.empty() && !texCoords[start][3].empty()) idx_mask |= SG_IDX_TEXCOORDS_3;
if (idx_mask == 0) {
SG_LOG(SG_IO, SG_ALERT, "SGBinObject::write_objects: object with material:"
<< m << "has no indices set");
}
-
-
+
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
sgWriteUInt( fp, 1 ); // nbytes
sgWriteChar( fp, idx_mask );
-
-// cout << "material:" << m << ", count =" << count << endl;
+
+ // vertex attribute property
+ if (va_mask != 0) {
+ sgWriteChar( fp, (char)SG_VERT_ATTRIBS ); // property
+ sgWriteUInt( fp, 4 ); // nbytes
+ sgWriteChar( fp, va_mask );
+ }
+
// elements
for (unsigned int i=start; i < end; ++i) {
const int_list& va(verts[i]);
const int_list& na((idx_mask & SG_IDX_NORMALS) ? normals[i] : emptyList);
const int_list& ca((idx_mask & SG_IDX_COLORS) ? colors[i] : emptyList);
- const int_list& tca((idx_mask & SG_IDX_TEXCOORDS) ? texCoords[i] : emptyList);
+
+ // pass the whole texcoord array - we'll figure out which indicies to write
+ // in write_indices
+ const tci_list& tca( texCoords[i] );
+
+ // pass the whole vertex array - we'll figure out which indicies to write
+ // in write_indices
+ const vai_list& vaa( vertexAttribs[i] );
if (version == 7) {
- write_indices<uint16_t>(fp, idx_mask, va, na, ca, tca);
+ write_indices<uint16_t>(fp, idx_mask, va_mask, va, na, ca, tca, vaa);
} else {
- write_indices<uint32_t>(fp, idx_mask, va, na, ca, tca);
+ write_indices<uint32_t>(fp, idx_mask, va_mask, va, na, ca, tca, vaa);
}
}
SGPath file2(file);
file2.create_dir( 0755 );
- cout << "Output file = " << file.str() << endl;
gzFile fp;
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
sgClearWriteError();
- cout << "points size = " << pts_v.size() << " pt_materials = "
- << pt_materials.size() << endl;
- 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;
+ SG_LOG(SG_IO, SG_DEBUG, "points size = " << pts_v.size()
+ << " pt_materials = " << pt_materials.size() );
+ SG_LOG(SG_IO, SG_DEBUG, "triangles size = " << tris_v.size()
+ << " tri_materials = " << tri_materials.size() );
+ SG_LOG(SG_IO, SG_DEBUG, "strips size = " << strips_v.size()
+ << " strip_materials = " << strip_materials.size() );
+ SG_LOG(SG_IO, SG_DEBUG, "fans size = " << fans_v.size()
+ << " fan_materials = " << fan_materials.size() );
- cout << "nodes = " << wgs84_nodes.size() << endl;
- cout << "colors = " << colors.size() << endl;
- cout << "normals = " << normals.size() << endl;
- cout << "tex coords = " << texcoords.size() << endl;
+ SG_LOG(SG_IO, SG_DEBUG, "nodes = " << wgs84_nodes.size() );
+ SG_LOG(SG_IO, SG_DEBUG, "colors = " << colors.size() );
+ SG_LOG(SG_IO, SG_DEBUG, "normals = " << normals.size() );
+ SG_LOG(SG_IO, SG_DEBUG, "tex coords = " << texcoords.size() );
version = 10;
bool shortMaterialsRanges =
nobjects += count_objects(strip_materials);
nobjects += count_objects(fan_materials);
- cout << "total top level objects = " << nobjects << endl;
+ SG_LOG(SG_IO, SG_DEBUG, "total top level objects = " << nobjects);
+
if (version == 7) {
sgWriteUShort( fp, (uint16_t) nobjects );
} else {
sgWriteVec2( fp, texcoords[i]);
}
- write_objects(fp, SG_POINTS, pts_v, pts_n, pts_c, pts_tc, pt_materials);
- write_objects(fp, SG_TRIANGLE_FACES, tris_v, tris_n, tris_c, tris_tc, tri_materials);
- write_objects(fp, SG_TRIANGLE_STRIPS, strips_v, strips_n, strips_c, strips_tc, strip_materials);
- write_objects(fp, SG_TRIANGLE_FANS, fans_v, fans_n, fans_c, fans_tc, fan_materials);
+ write_objects(fp, SG_POINTS, pts_v, pts_n, pts_c, pts_tcs, pts_vas, pt_materials);
+ write_objects(fp, SG_TRIANGLE_FACES, tris_v, tris_n, tris_c, tris_tcs, tris_vas, tri_materials);
+ write_objects(fp, SG_TRIANGLE_STRIPS, strips_v, strips_n, strips_c, strips_tcs, strips_vas, strip_materials);
+ write_objects(fp, SG_TRIANGLE_FANS, fans_v, fans_n, fans_c, fans_tcs, fans_vas, fan_materials);
// close the file
gzclose(fp);
}
// cout << "group = " << start << " to " << end - 1 << endl;
- SGSphered d;
+ SGSphered d( SGVec3d(0.0, 0.0, 0.0), -1.0 );
for ( i = start; i < end; ++i ) {
for ( j = 0; j < (int)tris_v[i].size(); ++j ) {
d.expandBy(wgs84_nodes[ tris_v[i][j] ]);
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, " %d/%d", tris_v[i][j], tris_tcs[i][0][j] );
}
fprintf(fp, "\n");
}
// cout << "group = " << start << " to " << end - 1 << endl;
- SGSphered d;
+ SGSphered d( SGVec3d(0.0, 0.0, 0.0), -1.0 );
for ( i = start; i < end; ++i ) {
for ( j = 0; j < (int)tris_v[i].size(); ++j ) {
d.expandBy(wgs84_nodes[ tris_v[i][j] ]);
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, " %d/%d", strips_v[i][j], strips_tcs[i][0][j] );
}
fprintf(fp, "\n");
}
}
}
+bool SGBinObject::add_point( const SGBinObjectPoint& pt )
+{
+ // add the point info
+ pt_materials.push_back( pt.material );
+
+ pts_v.push_back( pt.v_list );
+ pts_n.push_back( pt.n_list );
+ pts_c.push_back( pt.c_list );
+
+ return true;
+}
+
+bool SGBinObject::add_triangle( const SGBinObjectTriangle& tri )
+{
+ // add the triangle info and keep lists aligned
+ tri_materials.push_back( tri.material );
+ tris_v.push_back( tri.v_list );
+ tris_n.push_back( tri.n_list );
+ tris_c.push_back( tri.c_list );
+ tris_tcs.push_back( tri.tc_list );
+ tris_vas.push_back( tri.va_list );
+
+ return true;
+}
\ No newline at end of file
#include <vector>
#include <string>
+#include <boost/array.hpp>
-/** 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<int_list, MAX_TC_SETS> tci_list;
+typedef boost::array<int_list, MAX_VAS> 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<MAX_TC_SETS; i++ ) {
+ tc_list[i].clear();
+ }
+ for ( unsigned int i=0; i<MAX_VAS; i++ ) {
+ va_list[i].clear();
+ }
+ };
+
+};
+
+
+
/**
* A class to manipulate the simgear 3d object format.
* This class provides functionality to both read and write the binary format.
SGVec3d gbs_center;
float gbs_radius;
- std::vector<SGVec3d> wgs84_nodes; // vertex list
- std::vector<SGVec4f> colors; // color list
- std::vector<SGVec3f> normals; // normal list
- std::vector<SGVec2f> 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<SGVec3d> wgs84_nodes; // vertex list
+ std::vector<SGVec4f> colors; // color list
+ std::vector<SGVec3f> normals; // normal list
+ std::vector<SGVec2f> texcoords; // texture coordinate list
+ std::vector<float> va_flt; // vertex attribute list (floats)
+ std::vector<int> 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);
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; }
inline float get_gbs_radius() const { return gbs_radius; }
inline void set_gbs_radius( float r ) { gbs_radius = r; }
- inline const std::vector<SGVec3d>& get_wgs84_nodes() const
- { return wgs84_nodes; }
- inline void set_wgs84_nodes( const std::vector<SGVec3d>& n )
- { wgs84_nodes = n; }
+ inline const std::vector<SGVec3d>& get_wgs84_nodes() const { return wgs84_nodes; }
+ inline void set_wgs84_nodes( const std::vector<SGVec3d>& n ) { wgs84_nodes = n; }
inline const std::vector<SGVec4f>& get_colors() const { return colors; }
inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; }
inline const std::vector<SGVec2f>& get_texcoords() const { return texcoords; }
inline void set_texcoords( const std::vector<SGVec2f>& 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.
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();
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; t<count; ++t) {
- v.push_back(make_tri(maxVertices));
- n.push_back(make_tri(maxNormals));
- tc.push_back(make_tri(maxTCs));
- materials.push_back("material1");
+ sgboTri.material = "material1";
+ sgboTri.v_list = make_tri(maxVertices);
+ sgboTri.n_list = make_tri(maxNormals);
+ sgboTri.tc_list[0] = make_tri(maxTCs);
+
+ b.add_triangle( sgboTri );
}
-
- b.set_tris_v(v);
- b.set_tris_n(n);
- b.set_tris_tc(tc);
- b.set_tri_materials(materials);
}
void test_basic()
struct SGVertNormTex {
- SGVertNormTex()
- { }
- SGVertNormTex(const SGVec3f& v, const SGVec3f& n, const SGVec2f& t) :
- vertex(v), normal(n), texCoord(t)
- { }
+ SGVertNormTex() {
+ tc_mask = 0;
+ }
+
struct less
{
+ inline bool tc_is_less ( const SGVertNormTex& l,
+ const SGVertNormTex& r,
+ int idx ) const
+ {
+ if ( r.tc_mask & 1<<idx ) {
+ if ( l.tc_mask & 1<<idx ) {
+ if (l.texCoord[idx] < r.texCoord[idx]) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+
inline bool operator() (const SGVertNormTex& l,
const SGVertNormTex& r) const
{
else if (r.vertex < l.vertex) return false;
else if (l.normal < r.normal) return true;
else if (r.normal < l.normal) return false;
- else return l.texCoord < r.texCoord;
+ else if ( tc_is_less( l, r, 0 ) ) return true;
+ else if ( tc_is_less( r, l, 0 ) ) return false;
+ else if ( tc_is_less( l, r, 1 ) ) return true;
+ else if ( tc_is_less( r, l, 1 ) ) return false;
+ else if ( tc_is_less( l, r, 2 ) ) return true;
+ else if ( tc_is_less( r, l, 2 ) ) return false;
+ else if ( tc_is_less( l, r, 3 ) ) return true;
+ else return false;
}
};
+ void SetVertex( const SGVec3f& v ) { vertex = v; }
+ const SGVec3f& GetVertex( void ) const { return vertex; }
+
+ void SetNormal( const SGVec3f& n ) { normal = n; }
+ const SGVec3f& GetNormal( void ) const { return normal; }
+
+ void SetTexCoord( unsigned idx, const SGVec2f& tc ) {
+ texCoord[idx] = tc;
+ tc_mask |= 1 << idx;
+ }
+ const SGVec2f& GetTexCoord( unsigned idx ) const { return texCoord[idx]; }
+
+private:
SGVec3f vertex;
SGVec3f normal;
- SGVec2f texCoord;
+ SGVec2f texCoord[4];
+
+ unsigned tc_mask;
};
// Use a DrawElementsUShort if there are few enough vertices,
SGTexturedTriangleBin()
{
mt_init(&seed, 123);
+ has_sec_tcs = false;
}
// Computes and adds random surface points to the points list.
unsigned num = getNumTriangles();
for (unsigned i = 0; i < num; ++i) {
triangle_ref triangleRef = getTriangleRef(i);
- SGVec3f v0 = getVertex(triangleRef[0]).vertex;
- SGVec3f v1 = getVertex(triangleRef[1]).vertex;
- SGVec3f v2 = getVertex(triangleRef[2]).vertex;
- SGVec2f t0 = getVertex(triangleRef[0]).texCoord;
- SGVec2f t1 = getVertex(triangleRef[1]).texCoord;
- SGVec2f t2 = getVertex(triangleRef[2]).texCoord;
+ SGVec3f v0 = getVertex(triangleRef[0]).GetVertex();
+ SGVec3f v1 = getVertex(triangleRef[1]).GetVertex();
+ SGVec3f v2 = getVertex(triangleRef[2]).GetVertex();
+ SGVec2f t0 = getVertex(triangleRef[0]).GetTexCoord(0);
+ SGVec2f t1 = getVertex(triangleRef[1]).GetTexCoord(0);
+ SGVec2f t2 = getVertex(triangleRef[2]).GetTexCoord(0);
SGVec3f normal = cross(v1 - v0, v2 - v0);
// Compute the area
unsigned num = getNumTriangles();
for (unsigned i = 0; i < num; ++i) {
triangle_ref triangleRef = getTriangleRef(i);
- SGVec3f v0 = getVertex(triangleRef[0]).vertex;
- SGVec3f v1 = getVertex(triangleRef[1]).vertex;
- SGVec3f v2 = getVertex(triangleRef[2]).vertex;
- SGVec2f t0 = getVertex(triangleRef[0]).texCoord;
- SGVec2f t1 = getVertex(triangleRef[1]).texCoord;
- SGVec2f t2 = getVertex(triangleRef[2]).texCoord;
+ SGVec3f v0 = getVertex(triangleRef[0]).GetVertex();
+ SGVec3f v1 = getVertex(triangleRef[1]).GetVertex();
+ SGVec3f v2 = getVertex(triangleRef[2]).GetVertex();
+ SGVec2f t0 = getVertex(triangleRef[0]).GetTexCoord(0);
+ SGVec2f t1 = getVertex(triangleRef[1]).GetTexCoord(0);
+ SGVec2f t2 = getVertex(triangleRef[2]).GetTexCoord(0);
SGVec3f normal = cross(v1 - v0, v2 - v0);
// Ensure the slope isn't too steep by checking the
unsigned num = getNumTriangles();
for (unsigned i = 0; i < num; ++i) {
triangle_ref triangleRef = getTriangleRef(i);
- SGVec3f v0 = getVertex(triangleRef[0]).vertex;
- SGVec3f v1 = getVertex(triangleRef[1]).vertex;
- SGVec3f v2 = getVertex(triangleRef[2]).vertex;
- SGVec2f t0 = getVertex(triangleRef[0]).texCoord;
- SGVec2f t1 = getVertex(triangleRef[1]).texCoord;
- SGVec2f t2 = getVertex(triangleRef[2]).texCoord;
+ SGVec3f v0 = getVertex(triangleRef[0]).GetVertex();
+ SGVec3f v1 = getVertex(triangleRef[1]).GetVertex();
+ SGVec3f v2 = getVertex(triangleRef[2]).GetVertex();
+ SGVec2f t0 = getVertex(triangleRef[0]).GetTexCoord(0);
+ SGVec2f t1 = getVertex(triangleRef[1]).GetTexCoord(0);
+ SGVec2f t2 = getVertex(triangleRef[2]).GetTexCoord(0);
SGVec3f normal = cross(v1 - v0, v2 - v0);
// Compute the area
// FIXME: do not include all values here ...
osg::Vec3Array* vertices = new osg::Vec3Array;
osg::Vec3Array* normals = new osg::Vec3Array;
- osg::Vec2Array* texCoords = new osg::Vec2Array;
+ osg::Vec2Array* priTexCoords = new osg::Vec2Array;
+ osg::Vec2Array* secTexCoords = new osg::Vec2Array;
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1, 1, 1, 1));
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<unsigned> indexMap(getNumVertices(), invalid);
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]]);
}
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
static void
addTriangleGeometry(SGTexturedTriangleBin& triangles,
- const std::vector<SGVec3d>& vertices,
- const std::vector<SGVec3f>& normals,
- const std::vector<SGVec2f>& 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<SGVec3d>& vertices(obj.get_wgs84_nodes());
+ const std::vector<SGVec3f>& normals(obj.get_normals());
+ const std::vector<SGVec2f>& 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<SGVec3d>& vertices,
- const std::vector<SGVec3f>& normals,
- const std::vector<SGVec2f>& 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<SGVec3d>& vertices(obj.get_wgs84_nodes());
+ const std::vector<SGVec3f>& normals(obj.get_normals());
+ const std::vector<SGVec2f>& 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
static void
addFanGeometry(SGTexturedTriangleBin& triangles,
- const std::vector<SGVec3d>& vertices,
- const std::vector<SGVec3f>& normals,
- const std::vector<SGVec2f>& 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<SGVec3d>& vertices(obj.get_wgs84_nodes());
+ const std::vector<SGVec3f>& normals(obj.get_normals());
+ const std::vector<SGVec2f>& 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;
}
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;
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;
}
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)
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
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);