]> git.localhorst.tv Git - blank.git/commitdiff
fixed light propagation after obstacle removal
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 15 Jun 2015 08:13:25 +0000 (10:13 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 15 Jun 2015 08:13:25 +0000 (10:13 +0200)
regression from 4485397d
careful with the yoda conditions!

TODO
src/world/chunk.cpp
tst/world/ChunkTest.cpp

diff --git a/TODO b/TODO
index 6234fd0464048c6a29ac103210758c7377f0c6de..8ee6ef25c4a9753a1927abd55b75d19e50a57f35 100644 (file)
--- 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
index fe4f80267ab00d1f4bf2c572c7f278168cf03915..569bb11c9f8e240ff25864cf7323ce8aed579504 100644 (file)
@@ -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<float>::infinity();
index 3ecf0f6912b7d42ae2f5853c5ad71e6effbad170..408fec32dffaa5f3f4b8de747490d11f832a907c 100644 (file)
@@ -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))
+       );
 }
 
 }