]> git.mxchange.org Git - simgear.git/commitdiff
Unit test for SGBinObj, and fix a bug in large-indice handling the test revealed.
authorJames Turner <zakalawe@mac.com>
Fri, 14 Oct 2011 20:57:34 +0000 (21:57 +0100)
committerJames Turner <zakalawe@mac.com>
Fri, 14 Oct 2011 20:57:34 +0000 (21:57 +0100)
simgear/io/CMakeLists.txt
simgear/io/sg_binobj.cxx
simgear/io/test_binobj.cxx [new file with mode: 0644]

index 01560b39a01e431be9e8970feb8ca87cc1ad1bd2..84acd3f0abf948ba9203cd345dba34fa6f05e20a 100644 (file)
@@ -65,4 +65,14 @@ target_link_libraries(decode_binobj
     ${WINSOCK_LIBRARY}
     ${ZLIB_LIBRARY}
     ${RT_LIBRARY})
-        
\ No newline at end of file
+
+add_executable(test_binobj test_binobj.cxx)
+target_link_libraries(test_binobj
+    sgio sgbucket sgstructure sgthreads sgtiming sgmisc sgdebug
+    ${CMAKE_THREAD_LIBS_INIT}
+    ${WINSOCK_LIBRARY}
+    ${ZLIB_LIBRARY}
+    ${RT_LIBRARY}) 
+    
+add_test(binobj ${EXECUTABLE_OUTPUT_PATH}/test_binobj)
+       
\ No newline at end of file
index e01a52865f0f71188ab13dfde738e6eb7c858c0b..54f3b8debf5c3d7ec00f13b93f6e14b5b7f3874b 100644 (file)
@@ -752,7 +752,9 @@ bool SGBinObject::write_bin_file(const SGPath& file)
     cout << "tex coords = " << texcoords.size() << endl;
 
     version = 10;
-    if (wgs84_nodes.size() < 0xffff) {
+    if ((wgs84_nodes.size() < 0xffff) &&
+        (normals.size() < 0xffff) &&
+        (texcoords.size() < 0xffff)) {
         version = 7; // use smaller indices if possible
     }
 
diff --git a/simgear/io/test_binobj.cxx b/simgear/io/test_binobj.cxx
new file mode 100644 (file)
index 0000000..20c7ad3
--- /dev/null
@@ -0,0 +1,257 @@
+
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <iostream>
+#include <cstdlib>
+#include <cstdio>
+
+#include <simgear/misc/sg_dir.hxx>
+
+#include "sg_binobj.hxx"
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::string;
+
+#define COMPARE(a, b) \
+    if ((a) != (b))  { \
+        cerr << "failed:" << #a << " != " << #b << endl; \
+        cerr << "\tgot:" << a << endl; \
+        exit(1); \
+    }
+
+#define VERIFY(a) \
+    if (!(a))  { \
+        cerr << "failed:" << #a << endl; \
+        exit(1); \
+    }
+    
+void generate_points(int count, std::vector<SGVec3d>& vec)
+{
+    for (int i=0; i<count; ++i) {
+        vec.push_back(SGVec3d(i * 0.5, i * i, i * 4));
+    }
+}
+
+void generate_normals(int count, std::vector<SGVec3f>& vec)
+{
+    for (int i=0; i<count; ++i) {
+        vec.push_back(normalize(SGVec3f(i, i * 2, i * -4)));
+    }
+}
+
+void generate_tcs(int count, std::vector<SGVec2f>& vec)
+{
+    for (int i=0; i<count; ++i) {
+        vec.push_back(SGVec2f(1.0 / i, 16.0 / i));
+    }
+}
+    
+void test_empty()
+{
+    SGBinObject empty;
+    SGPath path(simgear::Dir::current().file("empty.btg.gz"));
+    bool ok = empty.write_bin_file(path);
+    VERIFY( ok );
+    SGBinObject rd;
+   ok = rd.read_bin(path.str()) ;
+   VERIFY( ok);
+
+   COMPARE(rd.get_wgs84_nodes().size(), 0);
+   VERIFY(rd.get_pt_materials().empty());
+}   
+void comparePoints(const SGBinObject& rd, const std::vector<SGVec3d>& b)
+{
+    for (unsigned int i=1; i<b.size(); i += 10) {
+        SGVec3d pos = rd.get_wgs84_nodes()[i];
+        pos += rd.get_gbs_center();
+     
+       if (!equivalent(pos, b[i], 0.1)) {
+            cout << "i=" << i << endl;
+            cout << b[i] << endl;
+            cout << pos << endl;
+        }
+        
+        VERIFY(equivalent(pos, b[i], 0.1));        
+    }
+}
+
+void compareTexCoords(const SGBinObject& rd, const std::vector<SGVec2f>& b)
+{
+    for (unsigned int i=1; i<b.size(); i += 10) {
+        SGVec2f pos = rd.get_texcoords()[i];
+        VERIFY(equivalent(pos, b[i], 0.001f));        
+    }
+}
+int_list make_tri(int maxIndex)
+{
+    int_list r;
+    r.push_back(random() % maxIndex);
+    r.push_back(random() % maxIndex);
+    r.push_back(random() % maxIndex);
+    return r;
+}
+
+void compareTris(const SGBinObject& a, const SGBinObject& b)
+{
+    unsigned int count = a.get_tri_materials().size();
+    for (unsigned int i=0; i<count; i += 39) {
+        const int_list& vA(a.get_tris_v()[i]);
+        const int_list& vB(b.get_tris_v()[i]);
+        VERIFY(vA == vB);
+
+        COMPARE(a.get_tri_materials()[i], b.get_tri_materials()[i]);
+        
+        const int_list& tA(a.get_tris_tc()[i]);
+        const int_list& tB(b.get_tris_tc()[i]);
+        VERIFY(tA == tB);
+    }
+}
+
+void generate_tris(SGBinObject& b, int count)
+{
+    group_list v, n, tc;
+    string_list materials;
+
+    int maxVertices = b.get_wgs84_nodes().size();
+    int maxNormals = b.get_normals().size();
+    int maxTCs = b.get_texcoords().size();
+    
+    for (int t=0; t<count; ++t) {
+        v.push_back(make_tri(maxVertices));
+        n.push_back(make_tri(maxNormals));
+        tc.push_back(make_tri(maxTCs));
+        materials.push_back("material1");
+    }
+    
+    b.set_tris_v(v);
+    b.set_tris_n(n);
+    b.set_tris_tc(tc);
+    b.set_tri_materials(materials);
+}
+void test_basic()
+{
+    SGBinObject basic;
+    SGPath path(simgear::Dir::current().file("basic.btg.gz"));
+    
+    SGVec3d center(1, 2, 3);
+    basic.set_gbs_center(center);
+    basic.set_gbs_radius(12345);
+    
+    std::vector<SGVec3d> points;
+    generate_points(1024, points);
+    std::vector<SGVec3f> normals;
+    generate_normals(1024, normals);
+    std::vector<SGVec2f> texCoords;
+    generate_tcs(10000, texCoords);
+    
+    basic.set_wgs84_nodes(points);
+    basic.set_normals(normals);
+    basic.set_texcoords(texCoords);
+    
+    bool ok = basic.write_bin_file(path);
+    VERIFY( ok );
+    
+    SGBinObject rd;
+   ok = rd.read_bin(path.str()) ;
+   VERIFY( ok);
+   COMPARE(rd.get_version(), 7); // should be version 7 since indices are < 2^16
+   COMPARE(rd.get_gbs_center(), center);
+   COMPARE(rd.get_gbs_radius(), 12345);
+   COMPARE(rd.get_wgs84_nodes().size(), points.size());
+   
+   comparePoints(rd, points);
+   compareTexCoords(rd, texCoords);
+}
+        
+void test_many_tcs()
+{
+    SGBinObject basic;
+    SGPath path(simgear::Dir::current().file("many_tex.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(100000, texCoords);
+    
+    basic.set_wgs84_nodes(points);
+    basic.set_normals(normals);
+    basic.set_texcoords(texCoords);
+    
+    generate_tris(basic, 20000);
+    
+    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);
+}
+
+void test_big()
+{
+    SGBinObject basic;
+    SGPath path(simgear::Dir::current().file("big.btg.gz"));
+    
+    SGVec3d center(1, 2, 3);
+    basic.set_gbs_center(center);
+    basic.set_gbs_radius(12345);
+    
+    std::vector<SGVec3d> points;
+    generate_points(200000, points);
+    std::vector<SGVec3f> normals;
+    generate_normals(1024, normals);
+    std::vector<SGVec2f> texCoords;
+    generate_tcs(300000, 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();
+    
+    return 0;
+}