]> git.localhorst.tv Git - blank.git/blob - tst/world/ChunkTest.cpp
more chunk tests
[blank.git] / tst / world / ChunkTest.cpp
1 #include "ChunkTest.hpp"
2
3 #include "world/BlockType.hpp"
4 #include "world/Chunk.hpp"
5
6 #include <memory>
7
8 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::ChunkTest);
9
10 using std::unique_ptr;
11
12
13 namespace blank {
14 namespace test {
15
16 void ChunkTest::setUp() {
17         types = BlockTypeRegistry();
18
19         BlockType obstacle;
20         obstacle.visible = true;
21         obstacle.block_light = true;
22         types.Add(obstacle);
23
24         BlockType source;
25         source.visible = true;
26         source.luminosity = 5;
27         source.block_light = true;
28         types.Add(source);
29 }
30
31 void ChunkTest::tearDown() {
32 }
33
34
35 void ChunkTest::testBounds() {
36         CPPUNIT_ASSERT_MESSAGE(
37                 "valid position out of bounds",
38                 Chunk::InBounds(Chunk::Pos(0, 0, 0))
39         );
40         CPPUNIT_ASSERT_MESSAGE(
41                 "valid position out of bounds",
42                 Chunk::InBounds(Chunk::Pos(15, 0, 0))
43         );
44         CPPUNIT_ASSERT_MESSAGE(
45                 "valid position out of bounds",
46                 Chunk::InBounds(Chunk::Pos(0, 15, 0))
47         );
48         CPPUNIT_ASSERT_MESSAGE(
49                 "valid position out of bounds",
50                 Chunk::InBounds(Chunk::Pos(0, 0, 15))
51         );
52         CPPUNIT_ASSERT_MESSAGE(
53                 "valid position out of bounds",
54                 Chunk::InBounds(Chunk::Pos(15, 15, 15))
55         );
56         CPPUNIT_ASSERT_MESSAGE(
57                 "invalid position in bounds",
58                 !Chunk::InBounds(Chunk::Pos(-1, -1, -1))
59         );
60         CPPUNIT_ASSERT_MESSAGE(
61                 "invalid position in bounds",
62                 !Chunk::InBounds(Chunk::Pos(-1, 1, 0))
63         );
64         CPPUNIT_ASSERT_MESSAGE(
65                 "invalid position in bounds",
66                 !Chunk::InBounds(Chunk::Pos(16, -16, 0))
67         );
68         CPPUNIT_ASSERT_MESSAGE(
69                 "invalid position in bounds",
70                 !Chunk::InBounds(Chunk::Pos(16, 16, 16))
71         );
72 }
73
74 void ChunkTest::testBorder() {
75         CPPUNIT_ASSERT_MESSAGE(
76                 "position not border",
77                 Chunk::IsBorder(Chunk::Pos(0, 0, 0))
78         );
79         CPPUNIT_ASSERT_MESSAGE(
80                 "position not border",
81                 Chunk::IsBorder(Chunk::Pos(0, 0, 8))
82         );
83         CPPUNIT_ASSERT_MESSAGE(
84                 "position not border",
85                 Chunk::IsBorder(Chunk::Pos(0, 0, 15))
86         );
87         CPPUNIT_ASSERT_MESSAGE(
88                 "position not border",
89                 Chunk::IsBorder(Chunk::Pos(0, 8, 0))
90         );
91         CPPUNIT_ASSERT_MESSAGE(
92                 "position not border",
93                 Chunk::IsBorder(Chunk::Pos(0, 8, 8))
94         );
95         CPPUNIT_ASSERT_MESSAGE(
96                 "position not border",
97                 Chunk::IsBorder(Chunk::Pos(0, 8, 15))
98         );
99         CPPUNIT_ASSERT_MESSAGE(
100                 "position not border",
101                 Chunk::IsBorder(Chunk::Pos(0, 15, 0))
102         );
103         CPPUNIT_ASSERT_MESSAGE(
104                 "position not border",
105                 Chunk::IsBorder(Chunk::Pos(0, 15, 8))
106         );
107         CPPUNIT_ASSERT_MESSAGE(
108                 "position not border",
109                 Chunk::IsBorder(Chunk::Pos(0, 15, 15))
110         );
111         CPPUNIT_ASSERT_MESSAGE(
112                 "position not border",
113                 Chunk::IsBorder(Chunk::Pos(8, 0, 0))
114         );
115         CPPUNIT_ASSERT_MESSAGE(
116                 "position not border",
117                 Chunk::IsBorder(Chunk::Pos(8, 0, 8))
118         );
119         CPPUNIT_ASSERT_MESSAGE(
120                 "position not border",
121                 Chunk::IsBorder(Chunk::Pos(8, 0, 15))
122         );
123         CPPUNIT_ASSERT_MESSAGE(
124                 "position not border",
125                 Chunk::IsBorder(Chunk::Pos(8, 8, 0))
126         );
127         CPPUNIT_ASSERT_MESSAGE(
128                 "position is border",
129                 !Chunk::IsBorder(Chunk::Pos(8, 8, 8))
130         );
131         CPPUNIT_ASSERT_MESSAGE(
132                 "position not border",
133                 Chunk::IsBorder(Chunk::Pos(8, 8, 15))
134         );
135         CPPUNIT_ASSERT_MESSAGE(
136                 "position not border",
137                 Chunk::IsBorder(Chunk::Pos(8, 15, 0))
138         );
139         CPPUNIT_ASSERT_MESSAGE(
140                 "position not border",
141                 Chunk::IsBorder(Chunk::Pos(8, 15, 8))
142         );
143         CPPUNIT_ASSERT_MESSAGE(
144                 "position not border",
145                 Chunk::IsBorder(Chunk::Pos(8, 15, 15))
146         );
147         CPPUNIT_ASSERT_MESSAGE(
148                 "position not border",
149                 Chunk::IsBorder(Chunk::Pos(15, 0, 0))
150         );
151         CPPUNIT_ASSERT_MESSAGE(
152                 "position not border",
153                 Chunk::IsBorder(Chunk::Pos(15, 0, 8))
154         );
155         CPPUNIT_ASSERT_MESSAGE(
156                 "position not border",
157                 Chunk::IsBorder(Chunk::Pos(15, 0, 15))
158         );
159         CPPUNIT_ASSERT_MESSAGE(
160                 "position not border",
161                 Chunk::IsBorder(Chunk::Pos(15, 8, 0))
162         );
163         CPPUNIT_ASSERT_MESSAGE(
164                 "position not border",
165                 Chunk::IsBorder(Chunk::Pos(15, 8, 8))
166         );
167         CPPUNIT_ASSERT_MESSAGE(
168                 "position not border",
169                 Chunk::IsBorder(Chunk::Pos(15, 8, 15))
170         );
171         CPPUNIT_ASSERT_MESSAGE(
172                 "position not border",
173                 Chunk::IsBorder(Chunk::Pos(15, 15, 0))
174         );
175         CPPUNIT_ASSERT_MESSAGE(
176                 "position not border",
177                 Chunk::IsBorder(Chunk::Pos(15, 15, 8))
178         );
179         CPPUNIT_ASSERT_MESSAGE(
180                 "position not border",
181                 Chunk::IsBorder(Chunk::Pos(15, 15, 15))
182         );
183
184         CPPUNIT_ASSERT_MESSAGE(
185                 "position not border",
186                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 0)))
187         );
188         CPPUNIT_ASSERT_MESSAGE(
189                 "position not border",
190                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 8)))
191         );
192         CPPUNIT_ASSERT_MESSAGE(
193                 "position not border",
194                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 15)))
195         );
196         CPPUNIT_ASSERT_MESSAGE(
197                 "position not border",
198                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 0)))
199         );
200         CPPUNIT_ASSERT_MESSAGE(
201                 "position not border",
202                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 8)))
203         );
204         CPPUNIT_ASSERT_MESSAGE(
205                 "position not border",
206                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 15)))
207         );
208         CPPUNIT_ASSERT_MESSAGE(
209                 "position not border",
210                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 0)))
211         );
212         CPPUNIT_ASSERT_MESSAGE(
213                 "position not border",
214                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 8)))
215         );
216         CPPUNIT_ASSERT_MESSAGE(
217                 "position not border",
218                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 15)))
219         );
220         CPPUNIT_ASSERT_MESSAGE(
221                 "position not border",
222                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 0)))
223         );
224         CPPUNIT_ASSERT_MESSAGE(
225                 "position not border",
226                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 8)))
227         );
228         CPPUNIT_ASSERT_MESSAGE(
229                 "position not border",
230                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 15)))
231         );
232         CPPUNIT_ASSERT_MESSAGE(
233                 "position not border",
234                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 0)))
235         );
236         CPPUNIT_ASSERT_MESSAGE(
237                 "position is border",
238                 !Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 8)))
239         );
240         CPPUNIT_ASSERT_MESSAGE(
241                 "position not border",
242                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 15)))
243         );
244         CPPUNIT_ASSERT_MESSAGE(
245                 "position not border",
246                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 0)))
247         );
248         CPPUNIT_ASSERT_MESSAGE(
249                 "position not border",
250                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 8)))
251         );
252         CPPUNIT_ASSERT_MESSAGE(
253                 "position not border",
254                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 15)))
255         );
256         CPPUNIT_ASSERT_MESSAGE(
257                 "position not border",
258                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 0)))
259         );
260         CPPUNIT_ASSERT_MESSAGE(
261                 "position not border",
262                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 8)))
263         );
264         CPPUNIT_ASSERT_MESSAGE(
265                 "position not border",
266                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 15)))
267         );
268         CPPUNIT_ASSERT_MESSAGE(
269                 "position not border",
270                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 0)))
271         );
272         CPPUNIT_ASSERT_MESSAGE(
273                 "position not border",
274                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 8)))
275         );
276         CPPUNIT_ASSERT_MESSAGE(
277                 "position not border",
278                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 15)))
279         );
280         CPPUNIT_ASSERT_MESSAGE(
281                 "position not border",
282                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 0)))
283         );
284         CPPUNIT_ASSERT_MESSAGE(
285                 "position not border",
286                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 8)))
287         );
288         CPPUNIT_ASSERT_MESSAGE(
289                 "position not border",
290                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 15)))
291         );
292 }
293
294 void ChunkTest::testNeighbor() {
295         unique_ptr<Chunk> chunk(new Chunk(types));
296         chunk->Position({0, 0, 0});
297         for (int i = 0; i < Block::FACE_COUNT; ++i) {
298                 CPPUNIT_ASSERT_MESSAGE(
299                         "sole chunk has neighbor",
300                         !chunk->HasNeighbor(Block::Face(i))
301                 );
302         }
303
304         unique_ptr<Chunk> neighbor(new Chunk(types));
305         for (int i = 0; i < Block::FACE_COUNT; ++i) {
306                 Block::Face face = Block::Face(i);
307                 neighbor->Position(Block::FaceNormal(face));
308                 chunk->SetNeighbor(*neighbor);
309                 CPPUNIT_ASSERT_MESSAGE(
310                         "chunk did not link right neighbor",
311                         chunk->HasNeighbor(face)
312                 );
313                 CPPUNIT_ASSERT_MESSAGE(
314                         "chunk did not link right neighbor",
315                         neighbor->HasNeighbor(Block::Opposite(face))
316                 );
317                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
318                         "chunk did not link correct neighbor",
319                         &*neighbor, &chunk->GetNeighbor(face)
320                 );
321                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
322                         "chunk did not link correct neighbor",
323                         &*chunk, &neighbor->GetNeighbor(Block::Opposite(face))
324                 );
325                 chunk->Unlink();
326                 chunk->ClearNeighbors();
327         }
328
329         neighbor->Position({1, 1, 1});
330         chunk->SetNeighbor(*neighbor);
331         for (int i = 0; i < Block::FACE_COUNT; ++i) {
332                 CPPUNIT_ASSERT_MESSAGE(
333                         "chunk linked with non-neighbor",
334                         !chunk->HasNeighbor(Block::Face(i))
335                 );
336         }
337 }
338
339
340 void ChunkTest::testBlock() {
341         unique_ptr<Chunk> chunk(new Chunk(types));
342
343         for (int index = 0; index < Chunk::size; ++index) {
344                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
345                         "default chunk has non-default block",
346                         Block(), chunk->BlockAt(index)
347                 );
348         }
349
350         Block block(1, Block::FACE_LEFT, Block::TURN_RIGHT);
351         chunk->SetBlock(0, block);
352         CPPUNIT_ASSERT_EQUAL_MESSAGE(
353                 "wrong type on set block",
354                 block.type, chunk->BlockAt(0).type
355         );
356         CPPUNIT_ASSERT_EQUAL_MESSAGE(
357                 "wrong orientation on set block",
358                 block.orient, chunk->BlockAt(0).orient
359         );
360         for (int index = 1; index < Chunk::size; ++index) {
361                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
362                         "changing block at index 0 affected some other block",
363                         Block(), chunk->BlockAt(index)
364                 );
365         }
366 }
367
368 void ChunkTest::testLight() {
369         unique_ptr<Chunk> chunk(new Chunk(types));
370
371         for (int index = 0; index < Chunk::size; ++index) {
372                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
373                         "default chunk has non-zero light level",
374                         0, chunk->GetLight(index)
375                 );
376         }
377
378         chunk->SetLight(0, 15);
379         CPPUNIT_ASSERT_EQUAL_MESSAGE(
380                 "wrong light level on set index",
381                 15, chunk->GetLight(0)
382         );
383         for (int index = 1; index < Chunk::size; ++index) {
384                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
385                         "changing light at index 0 affected some other index",
386                         0, chunk->GetLight(index)
387                 );
388         }
389 }
390
391 void ChunkTest::testLightPropagation() {
392         unique_ptr<Chunk> chunk(new Chunk(types));
393
394         // 0 air, 1 solid, 2 solid and emits light level of 5
395         chunk->SetBlock(Chunk::Pos(7, 7, 7), Block(2));
396         CPPUNIT_ASSERT_EQUAL_MESSAGE(
397                 "adding luminant block did not set correct light level",
398                 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
399         );
400
401         CPPUNIT_ASSERT_EQUAL_MESSAGE(
402                 "light did not propagate correctly in +X",
403                 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
404         );
405         CPPUNIT_ASSERT_EQUAL_MESSAGE(
406                 "light did not propagate correctly in -X",
407                 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
408         );
409         CPPUNIT_ASSERT_EQUAL_MESSAGE(
410                 "light did not propagate correctly in +Y",
411                 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
412         );
413         CPPUNIT_ASSERT_EQUAL_MESSAGE(
414                 "light did not propagate correctly in -Y",
415                 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
416         );
417         CPPUNIT_ASSERT_EQUAL_MESSAGE(
418                 "light did not propagate correctly in +Z",
419                 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
420         );
421         CPPUNIT_ASSERT_EQUAL_MESSAGE(
422                 "light did not propagate correctly in -Z",
423                 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
424         );
425
426         CPPUNIT_ASSERT_EQUAL_MESSAGE(
427                 "light did not propagate correctly in 2D diagonal",
428                 3, chunk->GetLight(Chunk::Pos(8, 8, 7))
429         );
430         CPPUNIT_ASSERT_EQUAL_MESSAGE(
431                 "light did not propagate correctly in 2D diagonal",
432                 3, chunk->GetLight(Chunk::Pos(7, 6, 8))
433         );
434         CPPUNIT_ASSERT_EQUAL_MESSAGE(
435                 "light did not propagate correctly in 2D diagonal",
436                 3, chunk->GetLight(Chunk::Pos(6, 7, 8))
437         );
438
439         CPPUNIT_ASSERT_EQUAL_MESSAGE(
440                 "light did not propagate correctly in 3D diagonal",
441                 2, chunk->GetLight(Chunk::Pos(8, 6, 6))
442         );
443         CPPUNIT_ASSERT_EQUAL_MESSAGE(
444                 "light did not propagate correctly in 3D diagonal",
445                 2, chunk->GetLight(Chunk::Pos(6, 6, 8))
446         );
447         CPPUNIT_ASSERT_EQUAL_MESSAGE(
448                 "light did not propagate correctly in 3D diagonal",
449                 2, chunk->GetLight(Chunk::Pos(6, 8, 8))
450         );
451
452         // now block the light to the left
453         chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(1));
454 }
455
456 }
457 }