- // read object header
- char obj_type;
- short nproperties, nelements;
- sgReadChar( fp, &obj_type );
- sgReadShort( fp, &nproperties );
- sgReadShort( fp, &nelements );
-
- // cout << "object " << i << " = " << (int)obj_type << " props = "
- // << nproperties << " elements = " << nelements << endl;
-
- if ( obj_type == SG_BOUNDING_SPHERE ) {
- // read bounding sphere properties
- for ( j = 0; j < nproperties; ++j ) {
- char prop_type;
- sgReadChar( fp, &prop_type );
-
- sgReadUInt( fp, &nbytes );
- // cout << "property size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
-
- // read bounding sphere elements
- for ( j = 0; j < nelements; ++j ) {
- sgReadUInt( fp, &nbytes );
- // cout << "element size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
-
- double *dptr = (double *)ptr;
- if ( sgIsBigEndian() ) {
- sgEndianSwap( (uint64 *)&(dptr[0]) );
- sgEndianSwap( (uint64 *)&(dptr[1]) );
- sgEndianSwap( (uint64 *)&(dptr[2]) );
- }
- gbs_center = Point3D( dptr[0], dptr[1], dptr[2] );
- // cout << "Center = " << gbs_center << endl;
- ptr += sizeof(double) * 3;
-
- float *fptr = (float *)ptr;
- if ( sgIsBigEndian() ) {
- sgEndianSwap( (unsigned int *)fptr );
- }
- gbs_radius = fptr[0];
- // cout << "Bounding radius = " << gbs_radius << endl;
- }
- } else if ( obj_type == SG_VERTEX_LIST ) {
- // read vertex list properties
- for ( j = 0; j < nproperties; ++j ) {
- char prop_type;
- sgReadChar( fp, &prop_type );
-
- sgReadUInt( fp, &nbytes );
- // cout << "property size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
-
- // read vertex list elements
- for ( j = 0; j < nelements; ++j ) {
- sgReadUInt( fp, &nbytes );
- // cout << "element size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- int count = nbytes / (sizeof(float) * 3);
- float *fptr = (float *)ptr;
- for ( k = 0; k < count; ++k ) {
- if ( sgIsBigEndian() ) {
- sgEndianSwap( (unsigned int *)&(fptr[0]) );
- sgEndianSwap( (unsigned int *)&(fptr[1]) );
- sgEndianSwap( (unsigned int *)&(fptr[2]) );
- }
- p = Point3D( fptr[0], fptr[1], fptr[2] );
- // cout << "node = " << p << endl;
- wgs84_nodes.push_back( p );
- fptr += 3;
- }
- }
- } else if ( obj_type == SG_COLOR_LIST ) {
- // read color list properties
- for ( j = 0; j < nproperties; ++j ) {
- char prop_type;
- sgReadChar( fp, &prop_type );
-
- sgReadUInt( fp, &nbytes );
- // cout << "property size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
-
- // read color list elements
- for ( j = 0; j < nelements; ++j ) {
- sgReadUInt( fp, &nbytes );
- // cout << "element size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- int count = nbytes / (sizeof(float) * 4);
- float *fptr = (float *)ptr;
- for ( k = 0; k < count; ++k ) {
- if ( sgIsBigEndian() ) {
- sgEndianSwap( (unsigned int *)&(fptr[0]) );
- sgEndianSwap( (unsigned int *)&(fptr[1]) );
- sgEndianSwap( (unsigned int *)&(fptr[2]) );
- sgEndianSwap( (unsigned int *)&(fptr[3]) );
- }
- p = Point3D( fptr[0], fptr[1], fptr[2] );
- // cout << "node = " << p << endl;
- colors.push_back( p );
- fptr += 4;
- }
- }
- } else if ( obj_type == SG_NORMAL_LIST ) {
- // read normal list properties
- for ( j = 0; j < nproperties; ++j ) {
- char prop_type;
- sgReadChar( fp, &prop_type );
-
- sgReadUInt( fp, &nbytes );
- // cout << "property size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
-
- // read normal list elements
- for ( j = 0; j < nelements; ++j ) {
- sgReadUInt( fp, &nbytes );
- // cout << "element size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- unsigned char *ptr = (unsigned char *)(buf.get_ptr());
- sgReadBytes( fp, nbytes, ptr );
- int count = nbytes / 3;
- for ( k = 0; k < count; ++k ) {
- sgdVec3 normal;
- sgdSetVec3( normal,
- (ptr[0]) / 127.5 - 1.0,
- (ptr[1]) / 127.5 - 1.0,
- (ptr[2]) / 127.5 - 1.0 );
- sgdNormalizeVec3( normal );
-
- p = Point3D( normal[0], normal[1], normal[2] );
- // cout << "normal = " << p << endl;
- normals.push_back( p );
- ptr += 3;
- }
- }
- } else if ( obj_type == SG_TEXCOORD_LIST ) {
- // read texcoord list properties
- for ( j = 0; j < nproperties; ++j ) {
- char prop_type;
- sgReadChar( fp, &prop_type );
-
- sgReadUInt( fp, &nbytes );
- // cout << "property size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
-
- // read texcoord list elements
- for ( j = 0; j < nelements; ++j ) {
- sgReadUInt( fp, &nbytes );
- // cout << "element size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- int count = nbytes / (sizeof(float) * 2);
- float *fptr = (float *)ptr;
- for ( k = 0; k < count; ++k ) {
- if ( sgIsBigEndian() ) {
- sgEndianSwap( (unsigned int *)&(fptr[0]) );
- sgEndianSwap( (unsigned int *)&(fptr[1]) );
- }
- p = Point3D( fptr[0], fptr[1], 0 );
- // cout << "texcoord = " << p << endl;
- texcoords.push_back( p );
- fptr += 2;
- }
- }
- } 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 );
- } 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 );
- } 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 );
- } 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 );
- } else {
- // unknown object type, just skip
-
- // read properties
- for ( j = 0; j < nproperties; ++j ) {
- char prop_type;
- sgReadChar( fp, &prop_type );
-
- sgReadUInt( fp, &nbytes );
- // cout << "property size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
-
- // read elements
- for ( j = 0; j < nelements; ++j ) {
- sgReadUInt( fp, &nbytes );
- // cout << "element size = " << nbytes << endl;
- if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
- char *ptr = buf.get_ptr();
- sgReadBytes( fp, nbytes, ptr );
- }
- }
+ // read object header
+ char obj_type;
+ uint32_t nproperties, nelements;
+ sgReadChar( fp, &obj_type );
+ if ( version >= 10 ) {
+ sgReadUInt( fp, &nproperties );
+ sgReadUInt( fp, &nelements );
+ } else if ( version >= 7 ) {
+ uint16_t v;
+ sgReadUShort( fp, &v );
+ nproperties = v;
+ sgReadUShort( fp, &v );
+ nelements = v;
+ } else {
+ int16_t v;
+ sgReadShort( fp, &v );
+ nproperties = v;
+ sgReadShort( fp, &v );
+ nelements = v;
+ }
+
+ //cout << "object " << i << " = " << (int)obj_type << " props = "
+ // << nproperties << " elements = " << nelements << endl;
+
+ if ( obj_type == SG_BOUNDING_SPHERE ) {
+ // read bounding sphere properties
+ read_properties( fp, nproperties );
+
+ // read bounding sphere elements
+ for ( j = 0; j < nelements; ++j ) {
+ sgReadUInt( fp, &nbytes );
+ buf.resize( nbytes );
+ buf.reset();
+ char *ptr = buf.get_ptr();
+ sgReadBytes( fp, nbytes, ptr );
+ gbs_center = buf.readVec3d();
+ gbs_radius = buf.readFloat();
+ }
+ } else if ( obj_type == SG_VERTEX_LIST ) {
+ // read vertex list properties
+ read_properties( fp, nproperties );
+
+ // read vertex 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) * 3);
+ wgs84_nodes.reserve( count );
+ for ( k = 0; k < count; ++k ) {
+ SGVec3f v = buf.readVec3f();
+ // extend from float to double, hmmm
+ wgs84_nodes.push_back( SGVec3d(v[0], v[1], v[2]) );
+ }
+ }
+ } else if ( obj_type == SG_COLOR_LIST ) {
+ // read color list properties
+ read_properties( fp, nproperties );
+
+ // read color 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) * 4);
+ colors.reserve(count);
+ for ( k = 0; k < count; ++k ) {
+ colors.push_back( buf.readVec4f() );
+ }
+ }
+ } else if ( obj_type == SG_NORMAL_LIST ) {
+ // read normal list properties
+ read_properties( fp, nproperties );
+
+ // read normal list elements
+ for ( j = 0; j < nelements; ++j ) {
+ sgReadUInt( fp, &nbytes );
+ buf.resize( nbytes );
+ buf.reset();
+ unsigned char *ptr = (unsigned char *)(buf.get_ptr());
+ sgReadBytes( fp, nbytes, ptr );
+ int count = nbytes / 3;
+ normals.reserve( count );
+
+ for ( k = 0; k < count; ++k ) {
+ SGVec3f normal( (ptr[0]) / 127.5 - 1.0,
+ (ptr[1]) / 127.5 - 1.0,
+ (ptr[2]) / 127.5 - 1.0);
+ normals.push_back(normalize(normal));
+ ptr += 3;
+ }
+ }
+ } else if ( obj_type == SG_TEXCOORD_LIST ) {
+ // read texcoord list properties
+ read_properties( fp, nproperties );
+
+ // read texcoord 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) * 2);
+ texcoords.reserve(count);
+ for ( k = 0; k < count; ++k ) {
+ texcoords.push_back( buf.readVec2f() );
+ }
+ }
+ } 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 );
+ } 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 );
+ } 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 );
+ } 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 );
+ } else {
+ // unknown object type, just skip
+ read_properties( fp, nproperties );
+
+ // read elements
+ for ( j = 0; j < nelements; ++j ) {
+ sgReadUInt( fp, &nbytes );
+ // cout << "element size = " << nbytes << endl;
+ if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
+ char *ptr = buf.get_ptr();
+ sgReadBytes( fp, nbytes, ptr );
+ }
+ }
+
+ if ( sgReadError() ) {
+ cout << "We detected an error while reading object:" << i << endl;
+ return false;
+ }