1 #include "ChunkTest.hpp"
3 #include "world/BlockType.hpp"
4 #include "world/Chunk.hpp"
8 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::ChunkTest);
10 using std::unique_ptr;
16 void ChunkTest::setUp() {
17 types = BlockTypeRegistry();
20 obstacle.visible = true;
21 obstacle.block_light = true;
25 source.visible = true;
26 source.luminosity = 5;
27 source.block_light = true;
31 void ChunkTest::tearDown() {
35 void ChunkTest::testBounds() {
36 CPPUNIT_ASSERT_MESSAGE(
37 "valid position out of bounds",
38 Chunk::InBounds(Chunk::Pos(0, 0, 0))
40 CPPUNIT_ASSERT_MESSAGE(
41 "valid position out of bounds",
42 Chunk::InBounds(Chunk::Pos(15, 0, 0))
44 CPPUNIT_ASSERT_MESSAGE(
45 "valid position out of bounds",
46 Chunk::InBounds(Chunk::Pos(0, 15, 0))
48 CPPUNIT_ASSERT_MESSAGE(
49 "valid position out of bounds",
50 Chunk::InBounds(Chunk::Pos(0, 0, 15))
52 CPPUNIT_ASSERT_MESSAGE(
53 "valid position out of bounds",
54 Chunk::InBounds(Chunk::Pos(15, 15, 15))
56 CPPUNIT_ASSERT_MESSAGE(
57 "invalid position in bounds",
58 !Chunk::InBounds(Chunk::Pos(-1, -1, -1))
60 CPPUNIT_ASSERT_MESSAGE(
61 "invalid position in bounds",
62 !Chunk::InBounds(Chunk::Pos(-1, 1, 0))
64 CPPUNIT_ASSERT_MESSAGE(
65 "invalid position in bounds",
66 !Chunk::InBounds(Chunk::Pos(16, -16, 0))
68 CPPUNIT_ASSERT_MESSAGE(
69 "invalid position in bounds",
70 !Chunk::InBounds(Chunk::Pos(16, 16, 16))
74 void ChunkTest::testBorder() {
75 CPPUNIT_ASSERT_MESSAGE(
76 "position not border",
77 Chunk::IsBorder(Chunk::Pos(0, 0, 0))
79 CPPUNIT_ASSERT_MESSAGE(
80 "position not border",
81 Chunk::IsBorder(Chunk::Pos(0, 0, 8))
83 CPPUNIT_ASSERT_MESSAGE(
84 "position not border",
85 Chunk::IsBorder(Chunk::Pos(0, 0, 15))
87 CPPUNIT_ASSERT_MESSAGE(
88 "position not border",
89 Chunk::IsBorder(Chunk::Pos(0, 8, 0))
91 CPPUNIT_ASSERT_MESSAGE(
92 "position not border",
93 Chunk::IsBorder(Chunk::Pos(0, 8, 8))
95 CPPUNIT_ASSERT_MESSAGE(
96 "position not border",
97 Chunk::IsBorder(Chunk::Pos(0, 8, 15))
99 CPPUNIT_ASSERT_MESSAGE(
100 "position not border",
101 Chunk::IsBorder(Chunk::Pos(0, 15, 0))
103 CPPUNIT_ASSERT_MESSAGE(
104 "position not border",
105 Chunk::IsBorder(Chunk::Pos(0, 15, 8))
107 CPPUNIT_ASSERT_MESSAGE(
108 "position not border",
109 Chunk::IsBorder(Chunk::Pos(0, 15, 15))
111 CPPUNIT_ASSERT_MESSAGE(
112 "position not border",
113 Chunk::IsBorder(Chunk::Pos(8, 0, 0))
115 CPPUNIT_ASSERT_MESSAGE(
116 "position not border",
117 Chunk::IsBorder(Chunk::Pos(8, 0, 8))
119 CPPUNIT_ASSERT_MESSAGE(
120 "position not border",
121 Chunk::IsBorder(Chunk::Pos(8, 0, 15))
123 CPPUNIT_ASSERT_MESSAGE(
124 "position not border",
125 Chunk::IsBorder(Chunk::Pos(8, 8, 0))
127 CPPUNIT_ASSERT_MESSAGE(
128 "position is border",
129 !Chunk::IsBorder(Chunk::Pos(8, 8, 8))
131 CPPUNIT_ASSERT_MESSAGE(
132 "position not border",
133 Chunk::IsBorder(Chunk::Pos(8, 8, 15))
135 CPPUNIT_ASSERT_MESSAGE(
136 "position not border",
137 Chunk::IsBorder(Chunk::Pos(8, 15, 0))
139 CPPUNIT_ASSERT_MESSAGE(
140 "position not border",
141 Chunk::IsBorder(Chunk::Pos(8, 15, 8))
143 CPPUNIT_ASSERT_MESSAGE(
144 "position not border",
145 Chunk::IsBorder(Chunk::Pos(8, 15, 15))
147 CPPUNIT_ASSERT_MESSAGE(
148 "position not border",
149 Chunk::IsBorder(Chunk::Pos(15, 0, 0))
151 CPPUNIT_ASSERT_MESSAGE(
152 "position not border",
153 Chunk::IsBorder(Chunk::Pos(15, 0, 8))
155 CPPUNIT_ASSERT_MESSAGE(
156 "position not border",
157 Chunk::IsBorder(Chunk::Pos(15, 0, 15))
159 CPPUNIT_ASSERT_MESSAGE(
160 "position not border",
161 Chunk::IsBorder(Chunk::Pos(15, 8, 0))
163 CPPUNIT_ASSERT_MESSAGE(
164 "position not border",
165 Chunk::IsBorder(Chunk::Pos(15, 8, 8))
167 CPPUNIT_ASSERT_MESSAGE(
168 "position not border",
169 Chunk::IsBorder(Chunk::Pos(15, 8, 15))
171 CPPUNIT_ASSERT_MESSAGE(
172 "position not border",
173 Chunk::IsBorder(Chunk::Pos(15, 15, 0))
175 CPPUNIT_ASSERT_MESSAGE(
176 "position not border",
177 Chunk::IsBorder(Chunk::Pos(15, 15, 8))
179 CPPUNIT_ASSERT_MESSAGE(
180 "position not border",
181 Chunk::IsBorder(Chunk::Pos(15, 15, 15))
184 CPPUNIT_ASSERT_MESSAGE(
185 "position not border",
186 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 0)))
188 CPPUNIT_ASSERT_MESSAGE(
189 "position not border",
190 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 8)))
192 CPPUNIT_ASSERT_MESSAGE(
193 "position not border",
194 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 15)))
196 CPPUNIT_ASSERT_MESSAGE(
197 "position not border",
198 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 0)))
200 CPPUNIT_ASSERT_MESSAGE(
201 "position not border",
202 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 8)))
204 CPPUNIT_ASSERT_MESSAGE(
205 "position not border",
206 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 15)))
208 CPPUNIT_ASSERT_MESSAGE(
209 "position not border",
210 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 0)))
212 CPPUNIT_ASSERT_MESSAGE(
213 "position not border",
214 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 8)))
216 CPPUNIT_ASSERT_MESSAGE(
217 "position not border",
218 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 15)))
220 CPPUNIT_ASSERT_MESSAGE(
221 "position not border",
222 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 0)))
224 CPPUNIT_ASSERT_MESSAGE(
225 "position not border",
226 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 8)))
228 CPPUNIT_ASSERT_MESSAGE(
229 "position not border",
230 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 15)))
232 CPPUNIT_ASSERT_MESSAGE(
233 "position not border",
234 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 0)))
236 CPPUNIT_ASSERT_MESSAGE(
237 "position is border",
238 !Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 8)))
240 CPPUNIT_ASSERT_MESSAGE(
241 "position not border",
242 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 15)))
244 CPPUNIT_ASSERT_MESSAGE(
245 "position not border",
246 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 0)))
248 CPPUNIT_ASSERT_MESSAGE(
249 "position not border",
250 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 8)))
252 CPPUNIT_ASSERT_MESSAGE(
253 "position not border",
254 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 15)))
256 CPPUNIT_ASSERT_MESSAGE(
257 "position not border",
258 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 0)))
260 CPPUNIT_ASSERT_MESSAGE(
261 "position not border",
262 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 8)))
264 CPPUNIT_ASSERT_MESSAGE(
265 "position not border",
266 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 15)))
268 CPPUNIT_ASSERT_MESSAGE(
269 "position not border",
270 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 0)))
272 CPPUNIT_ASSERT_MESSAGE(
273 "position not border",
274 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 8)))
276 CPPUNIT_ASSERT_MESSAGE(
277 "position not border",
278 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 15)))
280 CPPUNIT_ASSERT_MESSAGE(
281 "position not border",
282 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 0)))
284 CPPUNIT_ASSERT_MESSAGE(
285 "position not border",
286 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 8)))
288 CPPUNIT_ASSERT_MESSAGE(
289 "position not border",
290 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 15)))
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))
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(face, *neighbor);
309 CPPUNIT_ASSERT_MESSAGE(
310 "chunk did not link right neighbor",
311 chunk->HasNeighbor(face)
313 CPPUNIT_ASSERT_MESSAGE(
314 "chunk did not link right neighbor",
315 neighbor->HasNeighbor(Block::Opposite(face))
317 CPPUNIT_ASSERT_EQUAL_MESSAGE(
318 "chunk did not link correct neighbor",
319 &*neighbor, &chunk->GetNeighbor(face)
321 CPPUNIT_ASSERT_EQUAL_MESSAGE(
322 "chunk did not link correct neighbor",
323 &*chunk, &neighbor->GetNeighbor(Block::Opposite(face))
330 void ChunkTest::testBlock() {
331 unique_ptr<Chunk> chunk(new Chunk(types));
333 for (int index = 0; index < Chunk::size; ++index) {
334 CPPUNIT_ASSERT_EQUAL_MESSAGE(
335 "default chunk has non-default block",
336 Block(), chunk->BlockAt(index)
340 Block block(1, Block::FACE_LEFT, Block::TURN_RIGHT);
341 chunk->SetBlock(0, block);
342 CPPUNIT_ASSERT_EQUAL_MESSAGE(
343 "wrong type on set block",
344 block.type, chunk->BlockAt(0).type
346 CPPUNIT_ASSERT_EQUAL_MESSAGE(
347 "wrong orientation on set block",
348 block.orient, chunk->BlockAt(0).orient
350 for (int index = 1; index < Chunk::size; ++index) {
351 CPPUNIT_ASSERT_EQUAL_MESSAGE(
352 "changing block at index 0 affected some other block",
353 Block(), chunk->BlockAt(index)
358 void ChunkTest::testLight() {
359 unique_ptr<Chunk> chunk(new Chunk(types));
361 for (int index = 0; index < Chunk::size; ++index) {
362 CPPUNIT_ASSERT_EQUAL_MESSAGE(
363 "default chunk has non-zero light level",
364 0, chunk->GetLight(index)
368 chunk->SetLight(0, 15);
369 CPPUNIT_ASSERT_EQUAL_MESSAGE(
370 "wrong light level on set index",
371 15, chunk->GetLight(0)
373 for (int index = 1; index < Chunk::size; ++index) {
374 CPPUNIT_ASSERT_EQUAL_MESSAGE(
375 "changing light at index 0 affected some other index",
376 0, chunk->GetLight(index)
381 void ChunkTest::testLightPropagation() {
382 unique_ptr<Chunk> chunk(new Chunk(types));
384 // 0 air, 1 solid, 2 solid and emits light level of 5
385 chunk->SetBlock(Chunk::Pos(7, 7, 7), Block(2));
386 CPPUNIT_ASSERT_EQUAL_MESSAGE(
387 "adding luminant block did not set correct light level",
388 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
391 CPPUNIT_ASSERT_EQUAL_MESSAGE(
392 "light did not propagate correctly in +X",
393 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
395 CPPUNIT_ASSERT_EQUAL_MESSAGE(
396 "light did not propagate correctly in -X",
397 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
399 CPPUNIT_ASSERT_EQUAL_MESSAGE(
400 "light did not propagate correctly in +Y",
401 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
403 CPPUNIT_ASSERT_EQUAL_MESSAGE(
404 "light did not propagate correctly in -Y",
405 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
407 CPPUNIT_ASSERT_EQUAL_MESSAGE(
408 "light did not propagate correctly in +Z",
409 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
411 CPPUNIT_ASSERT_EQUAL_MESSAGE(
412 "light did not propagate correctly in -Z",
413 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
416 CPPUNIT_ASSERT_EQUAL_MESSAGE(
417 "light did not propagate correctly in 2D diagonal",
418 3, chunk->GetLight(Chunk::Pos(8, 8, 7))
420 CPPUNIT_ASSERT_EQUAL_MESSAGE(
421 "light did not propagate correctly in 2D diagonal",
422 3, chunk->GetLight(Chunk::Pos(7, 6, 8))
424 CPPUNIT_ASSERT_EQUAL_MESSAGE(
425 "light did not propagate correctly in 2D diagonal",
426 3, chunk->GetLight(Chunk::Pos(6, 7, 8))
429 CPPUNIT_ASSERT_EQUAL_MESSAGE(
430 "light did not propagate correctly in 3D diagonal",
431 2, chunk->GetLight(Chunk::Pos(8, 6, 6))
433 CPPUNIT_ASSERT_EQUAL_MESSAGE(
434 "light did not propagate correctly in 3D diagonal",
435 2, chunk->GetLight(Chunk::Pos(6, 6, 8))
437 CPPUNIT_ASSERT_EQUAL_MESSAGE(
438 "light did not propagate correctly in 3D diagonal",
439 2, chunk->GetLight(Chunk::Pos(6, 8, 8))
442 // now block the light to the left
443 chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(1));
444 CPPUNIT_ASSERT_EQUAL_MESSAGE(
445 "adding obstacle affected unrelated index",
446 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
448 CPPUNIT_ASSERT_EQUAL_MESSAGE(
449 "adding obstacle affected unrelated index",
450 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
452 CPPUNIT_ASSERT_EQUAL_MESSAGE(
453 "adding obstacle affected unrelated index",
454 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
456 CPPUNIT_ASSERT_EQUAL_MESSAGE(
457 "adding obstacle affected unrelated index",
458 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
460 CPPUNIT_ASSERT_EQUAL_MESSAGE(
461 "adding obstacle affected unrelated index",
462 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
464 CPPUNIT_ASSERT_EQUAL_MESSAGE(
465 "adding obstacle affected unrelated index",
466 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
468 CPPUNIT_ASSERT_EQUAL_MESSAGE(
469 "adding obstacle affected unrelated index",
470 3, chunk->GetLight(Chunk::Pos(6, 6, 7))
472 CPPUNIT_ASSERT_EQUAL_MESSAGE(
473 "adding obstacle affected unrelated index",
474 3, chunk->GetLight(Chunk::Pos(6, 8, 7))
476 CPPUNIT_ASSERT_EQUAL_MESSAGE(
477 "adding obstacle affected unrelated index",
478 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
480 CPPUNIT_ASSERT_EQUAL_MESSAGE(
481 "adding obstacle affected unrelated index",
482 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
484 CPPUNIT_ASSERT_EQUAL_MESSAGE(
485 "adding obstacle affected unrelated index",
486 2, chunk->GetLight(Chunk::Pos(5, 6, 7))
488 CPPUNIT_ASSERT_EQUAL_MESSAGE(
489 "adding obstacle affected unrelated index",
490 2, chunk->GetLight(Chunk::Pos(5, 8, 7))
492 CPPUNIT_ASSERT_EQUAL_MESSAGE(
493 "adding obstacle affected unrelated index",
494 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
496 CPPUNIT_ASSERT_EQUAL_MESSAGE(
497 "adding obstacle affected unrelated index",
498 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
500 CPPUNIT_ASSERT_EQUAL_MESSAGE(
501 "adding obstacle resulted in unexpected light level behind it",
502 1, chunk->GetLight(Chunk::Pos(5, 7, 7))
505 // and remove it again
506 chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(0));
507 CPPUNIT_ASSERT_EQUAL_MESSAGE(
508 "removing obstacle did not refill light correctly",
509 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
511 CPPUNIT_ASSERT_EQUAL_MESSAGE(
512 "removing obstacle did not refill light correctly",
513 3, chunk->GetLight(Chunk::Pos(5, 7, 7))
515 CPPUNIT_ASSERT_EQUAL_MESSAGE(
516 "removing obstacle did not refill light correctly",
517 2, chunk->GetLight(Chunk::Pos(4, 7, 7))