X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2Fchunk.cpp;h=75f9c4f424c28d8babc77ef9322921a7db96a899;hb=55dbd6b35a39888f245e247d2e140f141f918178;hp=2216617ec52aac4dc59b317329d2103da84d872a;hpb=c04ea5a6f67d446ea29aa2e88dc4c666956d7732;p=blank.git diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index 2216617..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(); @@ -484,25 +482,31 @@ bool Chunk::Intersection( bool Chunk::Intersection( const AABB &box, const glm::mat4 &Mbox, - const glm::mat4 &Mchunk + const glm::mat4 &Mchunk, + std::vector &col ) const noexcept { - if (!blank::Intersection(box, Mbox, Bounds(), Mchunk)) { + 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.visible) { + if (!type.collision) { continue; } - if (type.shape->Intersects(Mchunk * ToTransform(Pos(x, y, z), idx), box, Mbox)) { - return true; + 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 false; + return any; }