Test for, and fix, materials handling in BTG code.
It's possible (and happens!) to have less than 2^16 vertices or tex-coords, but more than 2^15 objects (tris) with the same materials. This was breaking our version 7 vs version 10 detection logic. Pete found the issue, I'm simply committing a version of his fix.
This commit is contained in:
parent
183d3749f0
commit
851a307c23
@ -722,6 +722,26 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
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;
|
||||
@ -753,9 +773,16 @@ bool SGBinObject::write_bin_file(const SGPath& file)
|
||||
cout << "tex coords = " << texcoords.size() << endl;
|
||||
|
||||
version = 10;
|
||||
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)) {
|
||||
(texcoords.size() < 0xffff) &&
|
||||
shortMaterialsRanges) {
|
||||
version = 7; // use smaller indices if possible
|
||||
}
|
||||
|
||||
|
@ -250,12 +250,88 @@ void test_big()
|
||||
compareTris(basic, rd);
|
||||
}
|
||||
|
||||
void test_some_objects()
|
||||
{
|
||||
SGBinObject basic;
|
||||
SGPath path(simgear::Dir::current().file("some_objects.btg.gz"));
|
||||
|
||||
SGVec3d center(1, 2, 3);
|
||||
basic.set_gbs_center(center);
|
||||
basic.set_gbs_radius(12345);
|
||||
|
||||
std::vector<SGVec3d> points;
|
||||
generate_points(10000, points);
|
||||
std::vector<SGVec3f> normals;
|
||||
generate_normals(1024, normals);
|
||||
std::vector<SGVec2f> texCoords;
|
||||
generate_tcs(20000, texCoords);
|
||||
|
||||
basic.set_wgs84_nodes(points);
|
||||
basic.set_normals(normals);
|
||||
basic.set_texcoords(texCoords);
|
||||
|
||||
generate_tris(basic, 30000); // a number smaller than 2^15!
|
||||
|
||||
bool ok = basic.write_bin_file(path);
|
||||
VERIFY( ok );
|
||||
|
||||
SGBinObject rd;
|
||||
ok = rd.read_bin(path.str()) ;
|
||||
VERIFY( ok);
|
||||
COMPARE(rd.get_version(), 7); // since we have less than 2^15 tris
|
||||
COMPARE(rd.get_wgs84_nodes().size(), points.size());
|
||||
COMPARE(rd.get_texcoords().size(), texCoords.size());
|
||||
|
||||
comparePoints(rd, points);
|
||||
compareTexCoords(rd, texCoords);
|
||||
compareTris(basic, rd);
|
||||
}
|
||||
|
||||
void test_many_objects()
|
||||
{
|
||||
SGBinObject basic;
|
||||
SGPath path(simgear::Dir::current().file("many_objects.btg.gz"));
|
||||
|
||||
SGVec3d center(1, 2, 3);
|
||||
basic.set_gbs_center(center);
|
||||
basic.set_gbs_radius(12345);
|
||||
|
||||
std::vector<SGVec3d> points;
|
||||
generate_points(10000, points);
|
||||
std::vector<SGVec3f> normals;
|
||||
generate_normals(1024, normals);
|
||||
std::vector<SGVec2f> texCoords;
|
||||
generate_tcs(20000, texCoords);
|
||||
|
||||
basic.set_wgs84_nodes(points);
|
||||
basic.set_normals(normals);
|
||||
basic.set_texcoords(texCoords);
|
||||
|
||||
generate_tris(basic, 200000);
|
||||
|
||||
bool ok = basic.write_bin_file(path);
|
||||
VERIFY( ok );
|
||||
|
||||
SGBinObject rd;
|
||||
ok = rd.read_bin(path.str()) ;
|
||||
VERIFY( ok);
|
||||
COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
|
||||
COMPARE(rd.get_wgs84_nodes().size(), points.size());
|
||||
COMPARE(rd.get_texcoords().size(), texCoords.size());
|
||||
|
||||
comparePoints(rd, points);
|
||||
compareTexCoords(rd, texCoords);
|
||||
compareTris(basic, rd);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
test_empty();
|
||||
test_basic();
|
||||
test_many_tcs();
|
||||
test_big();
|
||||
test_some_objects();
|
||||
test_many_objects();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user