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);
|
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)
|
bool SGBinObject::write_bin_file(const SGPath& file)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -753,9 +773,16 @@ bool SGBinObject::write_bin_file(const SGPath& file)
|
|||||||
cout << "tex coords = " << texcoords.size() << endl;
|
cout << "tex coords = " << texcoords.size() << endl;
|
||||||
|
|
||||||
version = 10;
|
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) &&
|
if ((wgs84_nodes.size() < 0xffff) &&
|
||||||
(normals.size() < 0xffff) &&
|
(normals.size() < 0xffff) &&
|
||||||
(texcoords.size() < 0xffff)) {
|
(texcoords.size() < 0xffff) &&
|
||||||
|
shortMaterialsRanges) {
|
||||||
version = 7; // use smaller indices if possible
|
version = 7; // use smaller indices if possible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,12 +250,88 @@ void test_big()
|
|||||||
compareTris(basic, rd);
|
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[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
test_empty();
|
test_empty();
|
||||||
test_basic();
|
test_basic();
|
||||||
test_many_tcs();
|
test_many_tcs();
|
||||||
test_big();
|
test_big();
|
||||||
|
test_some_objects();
|
||||||
|
test_many_objects();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user