summary refs log tree commit diff
path: root/src/World/Generation/ChunkMeshing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/World/Generation/ChunkMeshing.cpp')
-rw-r--r--src/World/Generation/ChunkMeshing.cpp35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/World/Generation/ChunkMeshing.cpp b/src/World/Generation/ChunkMeshing.cpp
index 8944c53..130bbad 100644
--- a/src/World/Generation/ChunkMeshing.cpp
+++ b/src/World/Generation/ChunkMeshing.cpp
@@ -118,44 +118,55 @@ std::array<Vector<3, F32>, 4> face_normals(BlockSide side) {
     return {normal, normal, normal, normal};
 }
 
-Bool is_face_visible(Chunk& chunk, const ChunkMeshing::ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side) {
 std::array<F32, 4> face_ao_values(Chunk& chunk, const ChunkNeighbors& neighbors, U32 x, U32 y, U32 z, BlockSide side) {
-    std::array<Vector<3, I32>, 4> offsets{};
+    std::array<Vector<3, I32>, 8> offsets{};
+    // Given a block position, these offsets can be added to it to get the 8 blocks necessary to calculate AO.
+    // There are 4 corners and 4 sides, corners are visually distinguished by the lack of spaces and
+    // but you can recognize them by the fact that they have no 0 offsets.
+    // Note: Is there a way to compute these? I tried but I couldn't... If the vertex windings ever change again I don't want to hardcode these...
+    auto nowhere = Vector<3, I32>::max();
     switch (side) {
     case BlockSide::Front:
-        offsets = {{{0, 1, 1}, {-1, 0, 1}, {0, -1, 1}, {1, 0, 1}}}; // works!
+        offsets = {{{0, 1, 1}, {-1,1,1}, {-1, 0, 1}, {-1,-1,1}, {0, -1, 1}, {1,-1,1}, {1, 0, 1}, {1,1,1}}};
         break;
     case BlockSide::Back:
-        offsets = {{{-1, 0, -1}, {0, 1, -1}, {1, 0, -1}, {0, -1, -1}}}; // works!
+        offsets = {{{-1, 0, -1}, {-1,1,-1}, {0, 1, -1}, {1,1,-1}, {1, 0, -1}, {1,-1,-1}, {0, -1, -1}, {-1,-1,-1}}};
         break;
     case BlockSide::Top:
-        offsets = {{{-1, 1, 0}, {0, 1, 1}, {1, 1, 0}, {0, 1, -1}}};
+        offsets = {{{-1, 1, 0}, {-1,1,1}, {0, 1, 1}, {1,1,1}, {1, 1, 0}, {1,1,-1}, {0, 1, -1}, {-1,1,-1}}};
         break;
     case BlockSide::Bottom:
-        offsets = {{{0, -1, 1}, {-1, -1, 0}, {0, -1, -1},  {1, -1, 0}}};
+        offsets = {{{0, -1, 1}, {-1,-1,1}, {-1, -1, 0}, {-1,-1,-1}, {0, -1, -1}, {1,-1,-1},  {1, -1, 0}, {1,-1,1}}};
         break;
     case BlockSide::Right:
-        offsets = {{{1, 0, -1}, {1, 1, 0}, {1, 0, 1},  {1, -1, 0}}};
+        offsets = {{{1, 0, -1}, {1,1,-1}, {1, 1, 0}, {1,1,1}, {1, 0, 1}, {1,-1,1},  {1, -1, 0}, {1,-1,-1}}};
         break;
     case BlockSide::Left:
-        offsets = {{{-1, 1, 0}, {-1, 0, -1}, {-1, -1, 0},  {-1, 0, 1}}};
+        offsets = {{{-1, 1, 0}, {-1,1,-1}, {-1, 0, -1}, {-1,-1,-1}, {-1, -1, 0}, {-1,-1,1},  {-1, 0, 1}, {-1,1,1}}};
         break;
     }
 
-
     std::array<F32, 4> vertex_ao{};
 
+    UInt offset_index = 0;
     for (UInt vertex = 0; vertex < 4; vertex++) {
-        auto a = offsets[vertex];
-        auto b = offsets[(vertex + 1) % 4];
+        auto a = offsets[offset_index];
+        auto b = offsets[++offset_index]; // corner
+        auto c = offsets[++offset_index % 8];
 
         auto block_a = get_block_wrapping(chunk, neighbors, {x + a.x(), y + a.y(), z + a.z()});
         auto block_b = get_block_wrapping(chunk, neighbors, {x + b.x(), y + b.y(), z + b.z()});
+        auto block_c = get_block_wrapping(chunk, neighbors, {x + c.x(), y + c.y(), z + c.z()});
 
         F32 occlusion_a = block_a.empty() ? 0 : 1;
         F32 occlusion_b = block_b.empty() ? 0 : 1;
+        F32 occlusion_c = block_c.empty() ? 0 : 1;
 
-        vertex_ao[vertex] = (occlusion_a + occlusion_b) / 2;
+        if (occlusion_a + occlusion_c == 2.0f) {
+            vertex_ao[vertex] = 1.0f;
+        } else {
+            vertex_ao[vertex] = (occlusion_a + occlusion_b + occlusion_c) / 3;
+        }
     }
 
     return vertex_ao;