]> git.mxchange.org Git - simgear.git/blob - simgear/io/test_binobj.cxx
Unit test for SGBinObj, and fix a bug in large-indice handling the test revealed.
[simgear.git] / simgear / io / test_binobj.cxx
1
2 #ifdef HAVE_CONFIG_H
3 #  include <simgear_config.h>
4 #endif
5
6 #include <simgear/compiler.h>
7
8 #include <iostream>
9 #include <cstdlib>
10 #include <cstdio>
11
12 #include <simgear/misc/sg_dir.hxx>
13
14 #include "sg_binobj.hxx"
15
16 using std::cout;
17 using std::cerr;
18 using std::endl;
19 using std::string;
20
21 #define COMPARE(a, b) \
22     if ((a) != (b))  { \
23         cerr << "failed:" << #a << " != " << #b << endl; \
24         cerr << "\tgot:" << a << endl; \
25         exit(1); \
26     }
27
28 #define VERIFY(a) \
29     if (!(a))  { \
30         cerr << "failed:" << #a << endl; \
31         exit(1); \
32     }
33     
34 void generate_points(int count, std::vector<SGVec3d>& vec)
35 {
36     for (int i=0; i<count; ++i) {
37         vec.push_back(SGVec3d(i * 0.5, i * i, i * 4));
38     }
39 }
40
41 void generate_normals(int count, std::vector<SGVec3f>& vec)
42 {
43     for (int i=0; i<count; ++i) {
44         vec.push_back(normalize(SGVec3f(i, i * 2, i * -4)));
45     }
46 }
47
48 void generate_tcs(int count, std::vector<SGVec2f>& vec)
49 {
50     for (int i=0; i<count; ++i) {
51         vec.push_back(SGVec2f(1.0 / i, 16.0 / i));
52     }
53 }
54     
55 void test_empty()
56 {
57     SGBinObject empty;
58     SGPath path(simgear::Dir::current().file("empty.btg.gz"));
59     bool ok = empty.write_bin_file(path);
60     VERIFY( ok );
61     SGBinObject rd;
62    ok = rd.read_bin(path.str()) ;
63    VERIFY( ok);
64
65    COMPARE(rd.get_wgs84_nodes().size(), 0);
66    VERIFY(rd.get_pt_materials().empty());
67 }   
68  
69 void comparePoints(const SGBinObject& rd, const std::vector<SGVec3d>& b)
70 {
71     for (unsigned int i=1; i<b.size(); i += 10) {
72         SGVec3d pos = rd.get_wgs84_nodes()[i];
73         pos += rd.get_gbs_center();
74      
75        if (!equivalent(pos, b[i], 0.1)) {
76             cout << "i=" << i << endl;
77             cout << b[i] << endl;
78             cout << pos << endl;
79         }
80         
81         VERIFY(equivalent(pos, b[i], 0.1));        
82     }
83 }
84
85 void compareTexCoords(const SGBinObject& rd, const std::vector<SGVec2f>& b)
86 {
87     for (unsigned int i=1; i<b.size(); i += 10) {
88         SGVec2f pos = rd.get_texcoords()[i];
89         VERIFY(equivalent(pos, b[i], 0.001f));        
90     }
91 }
92  
93 int_list make_tri(int maxIndex)
94 {
95     int_list r;
96     r.push_back(random() % maxIndex);
97     r.push_back(random() % maxIndex);
98     r.push_back(random() % maxIndex);
99     return r;
100 }
101
102 void compareTris(const SGBinObject& a, const SGBinObject& b)
103 {
104     unsigned int count = a.get_tri_materials().size();
105     for (unsigned int i=0; i<count; i += 39) {
106         const int_list& vA(a.get_tris_v()[i]);
107         const int_list& vB(b.get_tris_v()[i]);
108         VERIFY(vA == vB);
109
110         COMPARE(a.get_tri_materials()[i], b.get_tri_materials()[i]);
111         
112         const int_list& tA(a.get_tris_tc()[i]);
113         const int_list& tB(b.get_tris_tc()[i]);
114         VERIFY(tA == tB);
115     }
116 }
117
118 void generate_tris(SGBinObject& b, int count)
119 {
120     group_list v, n, tc;
121     string_list materials;
122
123     int maxVertices = b.get_wgs84_nodes().size();
124     int maxNormals = b.get_normals().size();
125     int maxTCs = b.get_texcoords().size();
126     
127     for (int t=0; t<count; ++t) {
128         v.push_back(make_tri(maxVertices));
129         n.push_back(make_tri(maxNormals));
130         tc.push_back(make_tri(maxTCs));
131         materials.push_back("material1");
132     }
133     
134     b.set_tris_v(v);
135     b.set_tris_n(n);
136     b.set_tris_tc(tc);
137     b.set_tri_materials(materials);
138 }
139  
140 void test_basic()
141 {
142     SGBinObject basic;
143     SGPath path(simgear::Dir::current().file("basic.btg.gz"));
144     
145     SGVec3d center(1, 2, 3);
146     basic.set_gbs_center(center);
147     basic.set_gbs_radius(12345);
148     
149     std::vector<SGVec3d> points;
150     generate_points(1024, points);
151     std::vector<SGVec3f> normals;
152     generate_normals(1024, normals);
153     std::vector<SGVec2f> texCoords;
154     generate_tcs(10000, texCoords);
155     
156     basic.set_wgs84_nodes(points);
157     basic.set_normals(normals);
158     basic.set_texcoords(texCoords);
159     
160     bool ok = basic.write_bin_file(path);
161     VERIFY( ok );
162     
163     SGBinObject rd;
164    ok = rd.read_bin(path.str()) ;
165    VERIFY( ok);
166    COMPARE(rd.get_version(), 7); // should be version 7 since indices are < 2^16
167    COMPARE(rd.get_gbs_center(), center);
168    COMPARE(rd.get_gbs_radius(), 12345);
169    COMPARE(rd.get_wgs84_nodes().size(), points.size());
170    
171    comparePoints(rd, points);
172    compareTexCoords(rd, texCoords);
173 }
174         
175 void test_many_tcs()
176 {
177     SGBinObject basic;
178     SGPath path(simgear::Dir::current().file("many_tex.btg.gz"));
179     
180     SGVec3d center(1, 2, 3);
181     basic.set_gbs_center(center);
182     basic.set_gbs_radius(12345);
183     
184     std::vector<SGVec3d> points;
185     generate_points(10000, points);
186     std::vector<SGVec3f> normals;
187     generate_normals(1024, normals);
188     std::vector<SGVec2f> texCoords;
189     generate_tcs(100000, texCoords);
190     
191     basic.set_wgs84_nodes(points);
192     basic.set_normals(normals);
193     basic.set_texcoords(texCoords);
194     
195     generate_tris(basic, 20000);
196     
197     bool ok = basic.write_bin_file(path);
198     VERIFY( ok );
199     
200     SGBinObject rd;
201    ok = rd.read_bin(path.str()) ;
202    VERIFY( ok);
203    COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
204    COMPARE(rd.get_wgs84_nodes().size(), points.size());
205    COMPARE(rd.get_texcoords().size(), texCoords.size());
206    
207    comparePoints(rd, points);
208    compareTexCoords(rd, texCoords);
209    compareTris(basic, rd);
210 }
211
212 void test_big()
213 {
214     SGBinObject basic;
215     SGPath path(simgear::Dir::current().file("big.btg.gz"));
216     
217     SGVec3d center(1, 2, 3);
218     basic.set_gbs_center(center);
219     basic.set_gbs_radius(12345);
220     
221     std::vector<SGVec3d> points;
222     generate_points(200000, points);
223     std::vector<SGVec3f> normals;
224     generate_normals(1024, normals);
225     std::vector<SGVec2f> texCoords;
226     generate_tcs(300000, texCoords);
227     
228     basic.set_wgs84_nodes(points);
229     basic.set_normals(normals);
230     basic.set_texcoords(texCoords);
231     
232     generate_tris(basic, 200000);
233     
234     bool ok = basic.write_bin_file(path);
235     VERIFY( ok );
236     
237     SGBinObject rd;
238    ok = rd.read_bin(path.str()) ;
239    VERIFY( ok);
240    COMPARE(rd.get_version(), 10); // should be version 10 since indices are > 2^16
241    COMPARE(rd.get_wgs84_nodes().size(), points.size());
242    COMPARE(rd.get_texcoords().size(), texCoords.size());
243    
244    comparePoints(rd, points);
245    compareTexCoords(rd, texCoords);
246    compareTris(basic, rd);
247 }
248
249 int main(int argc, char* argv[])
250 {
251     test_empty();
252     test_basic();
253     test_many_tcs();
254     test_big();
255     
256     return 0;
257 }