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(*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))
326 chunk->ClearNeighbors();
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))
340 void ChunkTest::testBlock() {
341 unique_ptr<Chunk> chunk(new Chunk(types));
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)
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
356 CPPUNIT_ASSERT_EQUAL_MESSAGE(
357 "wrong orientation on set block",
358 block.orient, chunk->BlockAt(0).orient
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)
368 void ChunkTest::testLight() {
369 unique_ptr<Chunk> chunk(new Chunk(types));
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)
378 chunk->SetLight(0, 15);
379 CPPUNIT_ASSERT_EQUAL_MESSAGE(
380 "wrong light level on set index",
381 15, chunk->GetLight(0)
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)
391 void ChunkTest::testLightPropagation() {
392 unique_ptr<Chunk> chunk(new Chunk(types));
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))
401 CPPUNIT_ASSERT_EQUAL_MESSAGE(
402 "light did not propagate correctly in +X",
403 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
405 CPPUNIT_ASSERT_EQUAL_MESSAGE(
406 "light did not propagate correctly in -X",
407 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
409 CPPUNIT_ASSERT_EQUAL_MESSAGE(
410 "light did not propagate correctly in +Y",
411 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
413 CPPUNIT_ASSERT_EQUAL_MESSAGE(
414 "light did not propagate correctly in -Y",
415 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
417 CPPUNIT_ASSERT_EQUAL_MESSAGE(
418 "light did not propagate correctly in +Z",
419 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
421 CPPUNIT_ASSERT_EQUAL_MESSAGE(
422 "light did not propagate correctly in -Z",
423 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
426 CPPUNIT_ASSERT_EQUAL_MESSAGE(
427 "light did not propagate correctly in 2D diagonal",
428 3, chunk->GetLight(Chunk::Pos(8, 8, 7))
430 CPPUNIT_ASSERT_EQUAL_MESSAGE(
431 "light did not propagate correctly in 2D diagonal",
432 3, chunk->GetLight(Chunk::Pos(7, 6, 8))
434 CPPUNIT_ASSERT_EQUAL_MESSAGE(
435 "light did not propagate correctly in 2D diagonal",
436 3, chunk->GetLight(Chunk::Pos(6, 7, 8))
439 CPPUNIT_ASSERT_EQUAL_MESSAGE(
440 "light did not propagate correctly in 3D diagonal",
441 2, chunk->GetLight(Chunk::Pos(8, 6, 6))
443 CPPUNIT_ASSERT_EQUAL_MESSAGE(
444 "light did not propagate correctly in 3D diagonal",
445 2, chunk->GetLight(Chunk::Pos(6, 6, 8))
447 CPPUNIT_ASSERT_EQUAL_MESSAGE(
448 "light did not propagate correctly in 3D diagonal",
449 2, chunk->GetLight(Chunk::Pos(6, 8, 8))
452 // now block the light to the left
453 chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(1));
454 CPPUNIT_ASSERT_EQUAL_MESSAGE(
455 "non-zero light level in solid block",
456 0, chunk->GetLight(Chunk::Pos(6, 7, 7))
458 CPPUNIT_ASSERT_EQUAL_MESSAGE(
459 "adding obstacle affected unrelated index",
460 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
462 CPPUNIT_ASSERT_EQUAL_MESSAGE(
463 "adding obstacle affected unrelated index",
464 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
466 CPPUNIT_ASSERT_EQUAL_MESSAGE(
467 "adding obstacle affected unrelated index",
468 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
470 CPPUNIT_ASSERT_EQUAL_MESSAGE(
471 "adding obstacle affected unrelated index",
472 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
474 CPPUNIT_ASSERT_EQUAL_MESSAGE(
475 "adding obstacle affected unrelated index",
476 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
478 CPPUNIT_ASSERT_EQUAL_MESSAGE(
479 "adding obstacle affected unrelated index",
480 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
482 CPPUNIT_ASSERT_EQUAL_MESSAGE(
483 "adding obstacle affected unrelated index",
484 3, chunk->GetLight(Chunk::Pos(6, 6, 7))
486 CPPUNIT_ASSERT_EQUAL_MESSAGE(
487 "adding obstacle affected unrelated index",
488 3, chunk->GetLight(Chunk::Pos(6, 8, 7))
490 CPPUNIT_ASSERT_EQUAL_MESSAGE(
491 "adding obstacle affected unrelated index",
492 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
494 CPPUNIT_ASSERT_EQUAL_MESSAGE(
495 "adding obstacle affected unrelated index",
496 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
498 CPPUNIT_ASSERT_EQUAL_MESSAGE(
499 "adding obstacle affected unrelated index",
500 2, chunk->GetLight(Chunk::Pos(5, 6, 7))
502 CPPUNIT_ASSERT_EQUAL_MESSAGE(
503 "adding obstacle affected unrelated index",
504 2, chunk->GetLight(Chunk::Pos(5, 8, 7))
506 CPPUNIT_ASSERT_EQUAL_MESSAGE(
507 "adding obstacle affected unrelated index",
508 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
510 CPPUNIT_ASSERT_EQUAL_MESSAGE(
511 "adding obstacle affected unrelated index",
512 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
514 CPPUNIT_ASSERT_EQUAL_MESSAGE(
515 "adding obstacle resulted in unexpected light level behind it",
516 1, chunk->GetLight(Chunk::Pos(5, 7, 7))
519 // and remove it again
520 chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(0));
521 CPPUNIT_ASSERT_EQUAL_MESSAGE(
522 "removing obstacle did not refill light correctly",
523 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
525 CPPUNIT_ASSERT_EQUAL_MESSAGE(
526 "removing obstacle did not refill light correctly",
527 3, chunk->GetLight(Chunk::Pos(5, 7, 7))
529 CPPUNIT_ASSERT_EQUAL_MESSAGE(
530 "removing obstacle did not refill light correctly",
531 2, chunk->GetLight(Chunk::Pos(4, 7, 7))