#include <simgear/bucket/newbucket.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/math/SGGeometry.hxx>
+#include <simgear/structure/exception.hxx>
#include "lowlevel.hxx"
#include "sg_binobj.hxx"
}
if ( sgReadError() ) {
- cout << "We detected an error reading object properties" << endl;
- return;
+ throw sg_exception("Error reading object properties");
+ }
+
+ size_t indexCount = std::bitset<32>(idx_mask).count();
+ if (indexCount == 0) {
+ throw sg_exception("object index mask has no bits set");
}
for ( j = 0; j < nelements; ++j ) {
sgReadUInt( fp, &nbytes );
if ( sgReadError() ) {
- cout << "We detected an error reading element size for :" << j << endl;
- return;
+ throw sg_exception("Error reading element size");
}
buf.resize( nbytes );
sgReadBytes( fp, nbytes, ptr );
if ( sgReadError() ) {
- cout << "We detected an error reading object element:" << j << "bytes="<< nbytes << endl;
- return;
+ throw sg_exception("Error reading element bytes");
}
int_list vs;
SG_LOG( SG_EVENT, SG_ALERT,
"ERROR: opening " << file << " or " << filegz << " for reading!");
- return false;
+ throw sg_io_exception("Error opening for reading (and .gz)", sg_location(file));
}
}
} else {
// close the file before we return
gzclose(fp);
-
- return false;
+ throw sg_io_exception("Bad BTG magic/version", sg_location(file));
}
-
+
// read creation time
unsigned int foo_calendar_time;
sgReadUInt( fp, &foo_calendar_time );
//cout << "Total objects to read = " << nobjects << endl;
if ( sgReadError() ) {
- cout << "We detected an error while reading the file header" << endl;
- return false;
+ throw sg_io_exception("Error reading BTG file header", sg_location(file));
}
// read in objects
}
if ( sgReadError() ) {
- cout << "We detected an error while reading object:" << i << endl;
- return false;
+ throw sg_io_exception("Error while reading object", sg_location(file, i));
}
}
// close the file
gzclose(fp);
- if ( sgReadError() ) {
- cout << "We detected an error while reading the file." << endl;
- return false;
- }
-
return true;
}
if (verts.empty()) {
return;
}
-
+
unsigned int start = 0, end = 1;
string m;
int_list emptyList;
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 (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 );
return write_bin_file(file);
}
+static unsigned int max_object_size( const string_list& materials )
+{
+ unsigned int max_size = 0;
+
+ for (unsigned int start=0; start < materials.size();) {
+ string m = materials[start];
+ unsigned int end = start + 1;
+ // find range of objects with identical material, calc its size
+ for (; (end < materials.size()) && (m == materials[end]); ++end) {}
+
+ unsigned int cur_size = end - start;
+ max_size = std::max(max_size, cur_size);
+ start = end;
+ }
+
+ return max_size;
+}
+
+const unsigned int VERSION_7_MATERIAL_LIMIT = 0x7fff;
+
bool SGBinObject::write_bin_file(const SGPath& file)
{
int i;
cout << "tex coords = " << texcoords.size() << endl;
version = 10;
- if (wgs84_nodes.size() < 0xffff) {
+ bool shortMaterialsRanges =
+ (max_object_size(pt_materials) < VERSION_7_MATERIAL_LIMIT) &&
+ (max_object_size(fan_materials) < VERSION_7_MATERIAL_LIMIT) &&
+ (max_object_size(strip_materials) < VERSION_7_MATERIAL_LIMIT) &&
+ (max_object_size(tri_materials) < VERSION_7_MATERIAL_LIMIT);
+
+ if ((wgs84_nodes.size() < 0xffff) &&
+ (normals.size() < 0xffff) &&
+ (texcoords.size() < 0xffff) &&
+ shortMaterialsRanges) {
version = 7; // use smaller indices if possible
}
gzclose(fp);
if ( sgWriteError() ) {
- cout << "We detected an error while writing the file." << endl;
+ cout << "Error while writing file " << file.str() << endl;
return false;
}
fprintf(fp, "\n");
// dump individual triangles if they exist
- if ( tris_v.size() > 0 ) {
+ if ( ! tris_v.empty() ) {
fprintf(fp, "# triangle groups\n");
int start = 0;
}
// dump triangle groups
- if ( strips_v.size() > 0 ) {
+ if ( ! strips_v.empty() ) {
fprintf(fp, "# triangle strips\n");
int start = 0;
fclose(fp);
string command = "gzip --force --best " + file.str();
- system(command.c_str());
+ int err = system(command.c_str());
+ if (err)
+ {
+ cout << "ERROR: gzip " << file.str() << " failed!" << endl;
+ }
- return true;
+ return (err == 0);
}
void SGBinObject::read_properties(gzFile fp, int nproperties)