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));
383 // this is required to make the chunk do lighting propagation at all
386 // 0 air, 1 solid, 2 solid and emits light level of 5
387 chunk->SetBlock(Chunk::Pos(7, 7, 7), Block(2));
388 CPPUNIT_ASSERT_EQUAL_MESSAGE(
389 "adding luminant block did not set correct light level",
390 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
393 CPPUNIT_ASSERT_EQUAL_MESSAGE(
394 "light did not propagate correctly in +X",
395 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
397 CPPUNIT_ASSERT_EQUAL_MESSAGE(
398 "light did not propagate correctly in -X",
399 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
401 CPPUNIT_ASSERT_EQUAL_MESSAGE(
402 "light did not propagate correctly in +Y",
403 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
405 CPPUNIT_ASSERT_EQUAL_MESSAGE(
406 "light did not propagate correctly in -Y",
407 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
409 CPPUNIT_ASSERT_EQUAL_MESSAGE(
410 "light did not propagate correctly in +Z",
411 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
413 CPPUNIT_ASSERT_EQUAL_MESSAGE(
414 "light did not propagate correctly in -Z",
415 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
418 CPPUNIT_ASSERT_EQUAL_MESSAGE(
419 "light did not propagate correctly in 2D diagonal",
420 3, chunk->GetLight(Chunk::Pos(8, 8, 7))
422 CPPUNIT_ASSERT_EQUAL_MESSAGE(
423 "light did not propagate correctly in 2D diagonal",
424 3, chunk->GetLight(Chunk::Pos(7, 6, 8))
426 CPPUNIT_ASSERT_EQUAL_MESSAGE(
427 "light did not propagate correctly in 2D diagonal",
428 3, chunk->GetLight(Chunk::Pos(6, 7, 8))
431 CPPUNIT_ASSERT_EQUAL_MESSAGE(
432 "light did not propagate correctly in 3D diagonal",
433 2, chunk->GetLight(Chunk::Pos(8, 6, 6))
435 CPPUNIT_ASSERT_EQUAL_MESSAGE(
436 "light did not propagate correctly in 3D diagonal",
437 2, chunk->GetLight(Chunk::Pos(6, 6, 8))
439 CPPUNIT_ASSERT_EQUAL_MESSAGE(
440 "light did not propagate correctly in 3D diagonal",
441 2, chunk->GetLight(Chunk::Pos(6, 8, 8))
444 // now block the light to the left
445 chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(1));
446 CPPUNIT_ASSERT_EQUAL_MESSAGE(
447 "adding obstacle affected unrelated index",
448 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
450 CPPUNIT_ASSERT_EQUAL_MESSAGE(
451 "adding obstacle affected unrelated index",
452 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
454 CPPUNIT_ASSERT_EQUAL_MESSAGE(
455 "adding obstacle affected unrelated index",
456 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
458 CPPUNIT_ASSERT_EQUAL_MESSAGE(
459 "adding obstacle affected unrelated index",
460 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
462 CPPUNIT_ASSERT_EQUAL_MESSAGE(
463 "adding obstacle affected unrelated index",
464 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
466 CPPUNIT_ASSERT_EQUAL_MESSAGE(
467 "adding obstacle affected unrelated index",
468 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
470 CPPUNIT_ASSERT_EQUAL_MESSAGE(
471 "adding obstacle affected unrelated index",
472 3, chunk->GetLight(Chunk::Pos(6, 6, 7))
474 CPPUNIT_ASSERT_EQUAL_MESSAGE(
475 "adding obstacle affected unrelated index",
476 3, chunk->GetLight(Chunk::Pos(6, 8, 7))
478 CPPUNIT_ASSERT_EQUAL_MESSAGE(
479 "adding obstacle affected unrelated index",
480 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
482 CPPUNIT_ASSERT_EQUAL_MESSAGE(
483 "adding obstacle affected unrelated index",
484 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
486 CPPUNIT_ASSERT_EQUAL_MESSAGE(
487 "adding obstacle affected unrelated index",
488 2, chunk->GetLight(Chunk::Pos(5, 6, 7))
490 CPPUNIT_ASSERT_EQUAL_MESSAGE(
491 "adding obstacle affected unrelated index",
492 2, chunk->GetLight(Chunk::Pos(5, 8, 7))
494 CPPUNIT_ASSERT_EQUAL_MESSAGE(
495 "adding obstacle affected unrelated index",
496 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
498 CPPUNIT_ASSERT_EQUAL_MESSAGE(
499 "adding obstacle affected unrelated index",
500 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
502 CPPUNIT_ASSERT_EQUAL_MESSAGE(
503 "adding obstacle resulted in unexpected light level behind it",
504 1, chunk->GetLight(Chunk::Pos(5, 7, 7))
507 // and remove it again
508 chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(0));
509 CPPUNIT_ASSERT_EQUAL_MESSAGE(
510 "removing obstacle did not refill light correctly",
511 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
513 CPPUNIT_ASSERT_EQUAL_MESSAGE(
514 "removing obstacle did not refill light correctly",
515 3, chunk->GetLight(Chunk::Pos(5, 7, 7))
517 CPPUNIT_ASSERT_EQUAL_MESSAGE(
518 "removing obstacle did not refill light correctly",
519 2, chunk->GetLight(Chunk::Pos(4, 7, 7))