X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2Fchunk.cpp;h=75f9c4f424c28d8babc77ef9322921a7db96a899;hb=55dbd6b35a39888f245e247d2e140f141f918178;hp=c114526ba46cdace3204acb226189cb0af671d27;hpb=4db5e3765bc93606e340f704ae27ca840eae7045;p=blank.git diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index c114526..75f9c4f 100644 --- a/src/world/chunk.cpp +++ b/src/world/chunk.cpp @@ -3,8 +3,10 @@ #include "ChunkLoader.hpp" #include "Generator.hpp" +#include "WorldCollision.hpp" #include +#include #include #include @@ -184,6 +186,26 @@ void Chunk::SetBlock(int index, const Block &block) noexcept { } } +namespace { + +// propagate light from a's edge to b +void edge_light( + Chunk &a, const Chunk::Pos &a_pos, + Chunk &b, const Chunk::Pos &b_pos +) noexcept { + if (a.GetLight(a_pos) > 1) { + const BlockType &b_type = b.Type(Chunk::ToIndex(b_pos)); + if (!b_type.block_light) { + light_queue.emplace(&a, a_pos); + } + if (b_type.visible) { + b.Invalidate(); + } + } +} + +} + void Chunk::SetNeighbor(Chunk &other) noexcept { if (other.position == position + Pos(-1, 0, 0)) { if (neighbor[Block::FACE_LEFT] != &other) { @@ -193,12 +215,8 @@ void Chunk::SetNeighbor(Chunk &other) noexcept { for (int y = 0; y < height; ++y) { Pos my_pos(0, y, z); Pos other_pos(width - 1, y, z); - if (GetLight(my_pos) > 0) { - light_queue.emplace(this, my_pos); - } - if (other.GetLight(other_pos) > 0) { - light_queue.emplace(&other, other_pos); - } + edge_light(*this, my_pos, other, other_pos); + edge_light(other, other_pos, *this, my_pos); } } work_light(); @@ -211,12 +229,8 @@ void Chunk::SetNeighbor(Chunk &other) noexcept { for (int y = 0; y < height; ++y) { Pos my_pos(width - 1, y, z); Pos other_pos(0, y, z); - if (GetLight(my_pos) > 0) { - light_queue.emplace(this, my_pos); - } - if (other.GetLight(other_pos) > 0) { - light_queue.emplace(&other, other_pos); - } + edge_light(*this, my_pos, other, other_pos); + edge_light(other, other_pos, *this, my_pos); } } work_light(); @@ -229,12 +243,8 @@ void Chunk::SetNeighbor(Chunk &other) noexcept { for (int x = 0; x < width; ++x) { Pos my_pos(x, 0, z); Pos other_pos(x, height - 1, z); - if (GetLight(my_pos) > 0) { - light_queue.emplace(this, my_pos); - } - if (other.GetLight(other_pos) > 0) { - light_queue.emplace(&other, other_pos); - } + edge_light(*this, my_pos, other, other_pos); + edge_light(other, other_pos, *this, my_pos); } } work_light(); @@ -247,12 +257,8 @@ void Chunk::SetNeighbor(Chunk &other) noexcept { for (int x = 0; x < width; ++x) { Pos my_pos(x, height - 1, z); Pos other_pos(x, 0, z); - if (GetLight(my_pos) > 0) { - light_queue.emplace(this, my_pos); - } - if (other.GetLight(other_pos) > 0) { - light_queue.emplace(&other, other_pos); - } + edge_light(*this, my_pos, other, other_pos); + edge_light(other, other_pos, *this, my_pos); } } work_light(); @@ -265,12 +271,8 @@ void Chunk::SetNeighbor(Chunk &other) noexcept { for (int x = 0; x < width; ++x) { Pos my_pos(x, y, 0); Pos other_pos(x, y, depth - 1); - if (GetLight(my_pos) > 0) { - light_queue.emplace(this, my_pos); - } - if (other.GetLight(other_pos) > 0) { - light_queue.emplace(&other, other_pos); - } + edge_light(*this, my_pos, other, other_pos); + edge_light(other, other_pos, *this, my_pos); } } work_light(); @@ -283,12 +285,8 @@ void Chunk::SetNeighbor(Chunk &other) noexcept { for (int x = 0; x < width; ++x) { Pos my_pos(x, y, depth - 1); Pos other_pos(x, y, 0); - if (GetLight(my_pos) > 0) { - light_queue.emplace(this, my_pos); - } - if (other.GetLight(other_pos) > 0) { - light_queue.emplace(&other, other_pos); - } + edge_light(*this, my_pos, other, other_pos); + edge_light(other, other_pos, *this, my_pos); } } work_light(); @@ -481,6 +479,36 @@ bool Chunk::Intersection( } } +bool Chunk::Intersection( + const AABB &box, + const glm::mat4 &Mbox, + const glm::mat4 &Mchunk, + std::vector &col +) const noexcept { + bool any = false; + float penetration; + glm::vec3 normal; + + if (!blank::Intersection(box, Mbox, Bounds(), Mchunk, penetration, normal)) { + return false; + } + for (int idx = 0, z = 0; z < depth; ++z) { + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x, ++idx) { + const BlockType &type = Type(idx); + if (!type.collision) { + continue; + } + if (type.shape->Intersects(Mchunk * ToTransform(Pos(x, y, z), idx), box, Mbox, penetration, normal)) { + col.emplace_back(this, idx, penetration, normal); + any = true; + } + } + } + } + return any; +} + namespace {