In the original flightgear native/binary scenery terrain data format, we

used short's extensively to represent counts of objects (number of points,
number of texture coordinates, number of traingle strips, etc.) and we used
shorts to index into larger structures.  But this capped many of our structure
sizes to a maximum of 32768.

By switching to unsigned shorts in the future, we can double the maximum
object/index counts without losing anything.  This was a pretty major
oversight in our original specification.

I have bumped up the native object file version from 6 to 7 and added code
in the reader to maintain full backwards compatibilty with version 6
scenery files (i.e. the current 0.9.10 scenery release.)

Curt.
This commit is contained in:
curt
2007-11-05 21:42:29 +00:00
parent 0c8358ae67
commit 7ed51be4e6
2 changed files with 69 additions and 51 deletions
+67 -49
View File
@@ -364,18 +364,32 @@ bool SGBinObject::read_bin( const string& file ) {
#endif #endif
// read number of top level objects // read number of top level objects
short nobjects; unsigned short nobjects;
sgReadShort( fp, &nobjects ); if ( version >= 7 ) {
sgReadUShort( fp, &nobjects );
} else {
short tmp;
sgReadShort( fp, &tmp );
nobjects = tmp;
}
// cout << "Total objects to read = " << nobjects << endl; // cout << "Total objects to read = " << nobjects << endl;
// read in objects // read in objects
for ( i = 0; i < nobjects; ++i ) { for ( i = 0; i < nobjects; ++i ) {
// read object header // read object header
char obj_type; char obj_type;
short nproperties, nelements; unsigned short nproperties, nelements;
sgReadChar( fp, &obj_type ); sgReadChar( fp, &obj_type );
sgReadShort( fp, &nproperties ); if ( version >= 7 ) {
sgReadShort( fp, &nelements ); sgReadUShort( fp, &nproperties );
sgReadUShort( fp, &nelements );
} else {
short tmp;
sgReadShort( fp, &tmp );
nproperties = tmp;
sgReadShort( fp, &tmp );
nelements = tmp;
}
// cout << "object " << i << " = " << (int)obj_type << " props = " // cout << "object " << i << " = " << (int)obj_type << " props = "
// << nproperties << " elements = " << nelements << endl; // << nproperties << " elements = " << nelements << endl;
@@ -649,7 +663,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
string material; string material;
int start; int start;
int end; int end;
short nobjects = 0; unsigned short nobjects = 0;
nobjects++; // for gbs nobjects++; // for gbs
nobjects++; // for vertices nobjects++; // for vertices
nobjects++; // for colors nobjects++; // for colors
@@ -657,7 +671,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects++; // for texcoords nobjects++; // for texcoords
// points // points
short npts = 0; unsigned short npts = 0;
start = 0; end = 1; start = 0; end = 1;
while ( start < (int)pt_materials.size() ) { while ( start < (int)pt_materials.size() ) {
material = pt_materials[start]; material = pt_materials[start];
@@ -671,7 +685,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += npts; nobjects += npts;
// tris // tris
short ntris = 0; unsigned short ntris = 0;
start = 0; end = 1; start = 0; end = 1;
while ( start < (int)tri_materials.size() ) { while ( start < (int)tri_materials.size() ) {
material = tri_materials[start]; material = tri_materials[start];
@@ -685,7 +699,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += ntris; nobjects += ntris;
// strips // strips
short nstrips = 0; unsigned short nstrips = 0;
start = 0; end = 1; start = 0; end = 1;
while ( start < (int)strip_materials.size() ) { while ( start < (int)strip_materials.size() ) {
material = strip_materials[start]; material = strip_materials[start];
@@ -699,7 +713,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += nstrips; nobjects += nstrips;
// fans // fans
short nfans = 0; unsigned short nfans = 0;
start = 0; end = 1; start = 0; end = 1;
while ( start < (int)fan_materials.size() ) { while ( start < (int)fan_materials.size() ) {
material = fan_materials[start]; material = fan_materials[start];
@@ -713,12 +727,12 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += nfans; nobjects += nfans;
cout << "total top level objects = " << nobjects << endl; cout << "total top level objects = " << nobjects << endl;
sgWriteShort( fp, nobjects ); sgWriteUShort( fp, nobjects );
// write bounding sphere // write bounding sphere
sgWriteChar( fp, (char)SG_BOUNDING_SPHERE ); // type sgWriteChar( fp, (char)SG_BOUNDING_SPHERE ); // type
sgWriteShort( fp, 0 ); // nproperties sgWriteUShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, sizeof(double) * 3 + sizeof(float) ); // nbytes sgWriteUInt( fp, sizeof(double) * 3 + sizeof(float) ); // nbytes
sgdVec3 center; sgdVec3 center;
@@ -728,8 +742,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump vertex list // dump vertex list
sgWriteChar( fp, (char)SG_VERTEX_LIST ); // type sgWriteChar( fp, (char)SG_VERTEX_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties sgWriteUShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) { for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
SGVec3f p = toVec3f(wgs84_nodes[i] - gbs_center); SGVec3f p = toVec3f(wgs84_nodes[i] - gbs_center);
@@ -738,8 +752,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump vertex color list // dump vertex color list
sgWriteChar( fp, (char)SG_COLOR_LIST ); // type sgWriteChar( fp, (char)SG_COLOR_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties sgWriteUShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
for ( i = 0; i < (int)colors.size(); ++i ) { for ( i = 0; i < (int)colors.size(); ++i ) {
sgWriteVec4( fp, colors[i].data() ); sgWriteVec4( fp, colors[i].data() );
@@ -747,8 +761,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump vertex normal list // dump vertex normal list
sgWriteChar( fp, (char)SG_NORMAL_LIST ); // type sgWriteChar( fp, (char)SG_NORMAL_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties sgWriteUShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, normals.size() * 3 ); // nbytes sgWriteUInt( fp, normals.size() * 3 ); // nbytes
char normal[3]; char normal[3];
for ( i = 0; i < (int)normals.size(); ++i ) { for ( i = 0; i < (int)normals.size(); ++i ) {
@@ -761,8 +775,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump texture coordinates // dump texture coordinates
sgWriteChar( fp, (char)SG_TEXCOORD_LIST ); // type sgWriteChar( fp, (char)SG_TEXCOORD_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties sgWriteUShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
for ( i = 0; i < (int)texcoords.size(); ++i ) { for ( i = 0; i < (int)texcoords.size(); ++i ) {
sgWriteVec2( fp, texcoords[i].data() ); sgWriteVec2( fp, texcoords[i].data() );
@@ -786,8 +800,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers // write group headers
sgWriteChar( fp, (char)SG_POINTS ); // type sgWriteChar( fp, (char)SG_POINTS ); // type
sgWriteShort( fp, 2 ); // nproperties sgWriteUShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements sgWriteUShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes sgWriteUInt( fp, material.length() ); // nbytes
@@ -806,19 +820,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write strips // write strips
for ( i = start; i < end; ++i ) { for ( i = start; i < end; ++i ) {
// nbytes // nbytes
sgWriteUInt( fp, pts_v[i].size() * idx_size * sizeof(short) ); sgWriteUInt( fp, pts_v[i].size() * idx_size
* sizeof(unsigned short) );
for ( j = 0; j < (int)pts_v[i].size(); ++j ) { for ( j = 0; j < (int)pts_v[i].size(); ++j ) {
if ( pts_v.size() ) { if ( pts_v.size() ) {
sgWriteShort( fp, (short)pts_v[i][j] ); sgWriteUShort( fp, (unsigned short)pts_v[i][j] );
} }
if ( pts_n.size() ) { if ( pts_n.size() ) {
sgWriteShort( fp, (short)pts_n[i][j] ); sgWriteUShort( fp, (unsigned short)pts_n[i][j] );
} }
if ( pts_c.size() ) { if ( pts_c.size() ) {
sgWriteShort( fp, (short)pts_c[i][j] ); sgWriteUShort( fp, (unsigned short)pts_c[i][j] );
} }
if ( pts_tc.size() ) { if ( pts_tc.size() ) {
sgWriteShort( fp, (short)pts_tc[i][j] ); sgWriteUShort( fp, (unsigned short)pts_tc[i][j] );
} }
} }
} }
@@ -847,8 +862,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers // write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_FACES ); // type sgWriteChar( fp, (char)SG_TRIANGLE_FACES ); // type
sgWriteShort( fp, 2 ); // nproperties sgWriteUShort( fp, 2 ); // nproperties
sgWriteShort( fp, 1 ); // nelements sgWriteUShort( fp, 1 ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes sgWriteUInt( fp, material.length() ); // nbytes
@@ -865,22 +880,23 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteChar( fp, idx_mask ); sgWriteChar( fp, idx_mask );
// nbytes // nbytes
sgWriteUInt( fp, (end - start) * 3 * idx_size * sizeof(short) ); sgWriteUInt( fp, (end - start) * 3 * idx_size
* sizeof(unsigned short) );
// write group // write group
for ( i = start; i < end; ++i ) { for ( i = start; i < end; ++i ) {
for ( j = 0; j < 3; ++j ) { for ( j = 0; j < 3; ++j ) {
if ( tris_v.size() ) { if ( tris_v.size() ) {
sgWriteShort( fp, (short)tris_v[i][j] ); sgWriteUShort( fp, (unsigned short)tris_v[i][j] );
} }
if ( tris_n.size() ) { if ( tris_n.size() ) {
sgWriteShort( fp, (short)tris_n[i][j] ); sgWriteUShort( fp, (unsigned short)tris_n[i][j] );
} }
if ( tris_c.size() ) { if ( tris_c.size() ) {
sgWriteShort( fp, (short)tris_c[i][j] ); sgWriteUShort( fp, (unsigned short)tris_c[i][j] );
} }
if ( tris_tc.size() ) { if ( tris_tc.size() ) {
sgWriteShort( fp, (short)tris_tc[i][j] ); sgWriteUShort( fp, (unsigned short)tris_tc[i][j] );
} }
} }
} }
@@ -908,8 +924,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers // write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_STRIPS ); // type sgWriteChar( fp, (char)SG_TRIANGLE_STRIPS ); // type
sgWriteShort( fp, 2 ); // nproperties sgWriteUShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements sgWriteUShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes sgWriteUInt( fp, material.length() ); // nbytes
@@ -928,19 +944,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write strips // write strips
for ( i = start; i < end; ++i ) { for ( i = start; i < end; ++i ) {
// nbytes // nbytes
sgWriteUInt( fp, strips_v[i].size() * idx_size * sizeof(short)); sgWriteUInt( fp, strips_v[i].size() * idx_size
* sizeof(unsigned short));
for ( j = 0; j < (int)strips_v[i].size(); ++j ) { for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
if ( strips_v.size() ) { if ( strips_v.size() ) {
sgWriteShort( fp, (short)strips_v[i][j] ); sgWriteUShort( fp, (unsigned short)strips_v[i][j] );
} }
if ( strips_n.size() ) { if ( strips_n.size() ) {
sgWriteShort( fp, (short)strips_n[i][j] ); sgWriteUShort( fp, (unsigned short)strips_n[i][j] );
} }
if ( strips_c.size() ) { if ( strips_c.size() ) {
sgWriteShort( fp, (short)strips_c[i][j] ); sgWriteUShort( fp, (unsigned short)strips_c[i][j] );
} }
if ( strips_tc.size() ) { if ( strips_tc.size() ) {
sgWriteShort( fp, (short)strips_tc[i][j] ); sgWriteUShort( fp, (unsigned short)strips_tc[i][j] );
} }
} }
} }
@@ -968,8 +985,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers // write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_FANS ); // type sgWriteChar( fp, (char)SG_TRIANGLE_FANS ); // type
sgWriteShort( fp, 2 ); // nproperties sgWriteUShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements sgWriteUShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes sgWriteUInt( fp, material.length() ); // nbytes
@@ -988,19 +1005,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write fans // write fans
for ( i = start; i < end; ++i ) { for ( i = start; i < end; ++i ) {
// nbytes // nbytes
sgWriteUInt( fp, fans_v[i].size() * idx_size * sizeof(short) ); sgWriteUInt( fp, fans_v[i].size() * idx_size
* sizeof(unsigned short) );
for ( j = 0; j < (int)fans_v[i].size(); ++j ) { for ( j = 0; j < (int)fans_v[i].size(); ++j ) {
if ( fans_v.size() ) { if ( fans_v.size() ) {
sgWriteShort( fp, (short)fans_v[i][j] ); sgWriteUShort( fp, (unsigned short)fans_v[i][j] );
} }
if ( fans_n.size() ) { if ( fans_n.size() ) {
sgWriteShort( fp, (short)fans_n[i][j] ); sgWriteUShort( fp, (unsigned short)fans_n[i][j] );
} }
if ( fans_c.size() ) { if ( fans_c.size() ) {
sgWriteShort( fp, (short)fans_c[i][j] ); sgWriteUShort( fp, (unsigned short)fans_c[i][j] );
} }
if ( fans_tc.size() ) { if ( fans_tc.size() ) {
sgWriteShort( fp, (short)fans_tc[i][j] ); sgWriteUShort( fp, (unsigned short)fans_tc[i][j] );
} }
} }
} }
+2 -2
View File
@@ -74,9 +74,9 @@ typedef group_list::const_iterator const_group_list_iterator;
* *
* - prop_typecode: material_name | ??? * - prop_typecode: material_name | ???
* *
* - nelements: SHORT (Gives us 65536 which ought to be enough, right?) * - nelements: USHORT (Gives us 65536 which ought to be enough, right?)
* *
* - nproperties: SHORT * - nproperties: USHORT
* *
* - *_typecode: CHAR * - *_typecode: CHAR
* *