From: Daniel Karbach Date: Mon, 15 Jun 2015 08:13:25 +0000 (+0200) Subject: fixed light propagation after obstacle removal X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=f2f254f8d576b48fde9305c3d2927552d1d4c20d;p=blank.git fixed light propagation after obstacle removal regression from 4485397d careful with the yoda conditions! --- diff --git a/TODO b/TODO index 6234fd0..8ee6ef2 100644 --- a/TODO +++ b/TODO @@ -43,8 +43,6 @@ entity ai this could be solved by using a pre-interpolated light texture and mapping light levels to coordinates on that - there seems to be a bug with adding/removing obstacles...again - also: how could block light affect entity lighting? maybe get the interpolated light level at the entity's center and use that as the light power for the directional lighting shader and use a diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index fe4f802..569bb11 100644 --- a/src/world/chunk.cpp +++ b/src/world/chunk.cpp @@ -169,15 +169,16 @@ void Chunk::SetBlock(int index, const Block &block) noexcept { } else if (!new_type.block_light && old_type.block_light) { // obstacle removed int level = 0; + Pos pos(ToPos(index)); for (int face = 0; face < Block::FACE_COUNT; ++face) { - BlockLookup next_block(this, ToPos(index), Block::Face(face)); + BlockLookup next_block(this, pos, Block::Face(face)); if (next_block) { - level = std::min(level, next_block.GetLight()); + level = std::max(level, next_block.GetLight()); } } if (level > 1) { SetLight(index, level - 1); - light_queue.emplace(this, ToPos(index)); + light_queue.emplace(this, pos); work_light(); } } @@ -449,7 +450,6 @@ bool Chunk::Intersection( float &dist, glm::vec3 &normal ) const noexcept { - // TODO: should be possible to heavily optimize this int idx = 0; blkid = -1; dist = std::numeric_limits::infinity(); diff --git a/tst/world/ChunkTest.cpp b/tst/world/ChunkTest.cpp index 3ecf0f6..408fec3 100644 --- a/tst/world/ChunkTest.cpp +++ b/tst/world/ChunkTest.cpp @@ -451,6 +451,85 @@ void ChunkTest::testLightPropagation() { // now block the light to the left chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(1)); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "non-zero light level in solid block", + 0, chunk->GetLight(Chunk::Pos(6, 7, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 5, chunk->GetLight(Chunk::Pos(7, 7, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 4, chunk->GetLight(Chunk::Pos(8, 7, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 4, chunk->GetLight(Chunk::Pos(7, 8, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 4, chunk->GetLight(Chunk::Pos(7, 6, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 4, chunk->GetLight(Chunk::Pos(7, 7, 8)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 4, chunk->GetLight(Chunk::Pos(7, 7, 6)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 3, chunk->GetLight(Chunk::Pos(6, 6, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 3, chunk->GetLight(Chunk::Pos(6, 8, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 3, chunk->GetLight(Chunk::Pos(6, 7, 6)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 3, chunk->GetLight(Chunk::Pos(6, 7, 6)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 2, chunk->GetLight(Chunk::Pos(5, 6, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 2, chunk->GetLight(Chunk::Pos(5, 8, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 2, chunk->GetLight(Chunk::Pos(5, 7, 6)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle affected unrelated index", + 2, chunk->GetLight(Chunk::Pos(5, 7, 6)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "adding obstacle resulted in unexpected light level behind it", + 1, chunk->GetLight(Chunk::Pos(5, 7, 7)) + ); + + // and remove it again + chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(0)); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "removing obstacle did not refill light correctly", + 4, chunk->GetLight(Chunk::Pos(6, 7, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "removing obstacle did not refill light correctly", + 3, chunk->GetLight(Chunk::Pos(5, 7, 7)) + ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "removing obstacle did not refill light correctly", + 2, chunk->GetLight(Chunk::Pos(4, 7, 7)) + ); } }