X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fchunk.hpp;h=7e720bd84c5b49945f7dc7a45e6b2f0f1af9d699;hb=3072e2cd49ad1614100d1a1c73afe6a4888fb875;hp=3c301803495038beeb99f59db847db5ffa6d1498;hpb=eca1fdcc8e34a4918418b2de122c6200aeb7ceaf;p=blank.git diff --git a/src/chunk.hpp b/src/chunk.hpp index 3c30180..7e720bd 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -5,6 +5,7 @@ #include "geometry.hpp" #include "model.hpp" +#include #include #include @@ -18,7 +19,7 @@ public: using Pos = glm::tvec3; public: - Chunk(); + explicit Chunk(const BlockTypeRegistry &); Chunk(Chunk &&); Chunk &operator =(Chunk &&); @@ -31,14 +32,20 @@ public: static AABB Bounds() { return AABB{ { 0, 0, 0 }, Extent() }; } - static constexpr bool InBounds(const glm::vec3 &pos) { + static constexpr bool InBounds(const Block::Pos &pos) { return pos.x >= 0 && pos.x < Width() && pos.y >= 0 && pos.y < Height() && pos.z >= 0 && pos.z < Depth(); } - static constexpr int ToIndex(const glm::vec3 &pos) { - return int(pos.x) + int(pos.y) * Width() + int(pos.z) * Width() * Height(); + static constexpr bool InBounds(const Pos &pos) { + return + pos.x >= 0 && pos.x < Width() && + pos.y >= 0 && pos.y < Height() && + pos.z >= 0 && pos.z < Depth(); + } + static constexpr int ToIndex(const Pos &pos) { + return pos.x + pos.y * Width() + pos.z * Width() * Height(); } static constexpr bool InBounds(int idx) { return idx >= 0 && idx < Size(); @@ -50,40 +57,137 @@ public: 0.5f + (idx / (Width() * Height())) ); } + static Pos ToPos(int idx) { + return Pos( + (idx % Width()), + ((idx / Width()) % Height()), + (idx / (Width() * Height())) + ); + } + glm::mat4 ToTransform(int idx) const; + + static constexpr bool IsBorder(int idx) { + return + idx < Width() * Height() || // low Z plane + idx % Width() == 0 || // low X plane + (idx / (Width() * Height())) == Depth() - 1 || // high Z plane + idx % Width() == Width() - 1 || // high X plane + (idx / Width()) % Height() == 0 || // low Y plane + (idx / Width()) % Height() == Height() - 1; // high Y plane + } + + void SetNeighbor(Chunk &); + bool HasNeighbor(Block::Face f) const { return neighbor[f]; } + Chunk &GetNeighbor(Block::Face f) { return *neighbor[f]; } + const Chunk &GetNeighbor(Block::Face f) const { return *neighbor[f]; } + void ClearNeighbors(); + void Unlink(); + void Relink(); + + // check if block at given index is completely enclosed (and therefore invisible) + bool Obstructed(int idx) const; void Allocate(); void Invalidate() { dirty = true; } - Block &BlockAt(int index) { return blocks[index]; } + void SetBlock(int index, const Block &); + void SetBlock(const Block::Pos &pos, const Block &block) { SetBlock(ToIndex(pos), block); } + void SetBlock(const Pos &pos, const Block &block) { SetBlock(ToIndex(pos), block); } + const Block &BlockAt(int index) const { return blocks[index]; } - Block &BlockAt(const Block::Pos &pos) { return BlockAt(ToIndex(pos)); } const Block &BlockAt(const Block::Pos &pos) const { return BlockAt(ToIndex(pos)); } + const Block &BlockAt(const Pos &pos) const { return BlockAt(ToIndex(pos)); } + + const Block *FindNext(const Pos &pos, Block::Face face) const; + const Block *FindNext(const Block::Pos &pos, Block::Face face) const { return FindNext(Pos(pos), face); } + const Block *FindNext(int index, Block::Face face) const { return FindNext(ToPos(index), face); } + + const BlockType &Type(const Block &b) const { return *types->Get(b.type); } + + void SetLight(int index, int level); + void SetLight(const Pos &pos, int level) { SetLight(ToIndex(pos), level); } + void SetLight(const Block::Pos &pos, int level) { SetLight(ToIndex(pos), level); } + + int GetLight(int index) const; + int GetLight(const Pos &pos) const { return GetLight(ToIndex(pos)); } + int GetLight(const Block::Pos &pos) const { return GetLight(ToIndex(pos)); } + + bool Intersection( + const Ray &ray, + const glm::mat4 &M, + float &dist + ) const { + return blank::Intersection(ray, Bounds(), M, &dist); + } bool Intersection( const Ray &, const glm::mat4 &M, - int *blkid = nullptr, - float *dist = nullptr, - glm::vec3 *normal = nullptr) const; + int &blkid, + float &dist, + glm::vec3 &normal) const; void Position(const Pos &); const Pos &Position() const { return position; } glm::mat4 Transform(const Pos &offset) const; + void CheckUpdate(); void Draw(); private: - int VertexCount() const; void Update(); private: + const BlockTypeRegistry *types; + Chunk *neighbor[Block::FACE_COUNT]; std::vector blocks; + std::vector light; Model model; Pos position; bool dirty; }; + +class Generator; + +class ChunkLoader { + +public: + ChunkLoader(const BlockTypeRegistry &, const Generator &); + + void Generate(const Chunk::Pos &from, const Chunk::Pos &to); + + std::list &Loaded() { return loaded; } + + Chunk *Loaded(const Chunk::Pos &); + bool Queued(const Chunk::Pos &); + bool Known(const Chunk::Pos &); + Chunk &ForceLoad(const Chunk::Pos &); + + void Rebase(const Chunk::Pos &); + void Update(); + +private: + Chunk &Generate(const Chunk::Pos &pos); + void Insert(Chunk &); + void Remove(Chunk &); + +private: + Chunk::Pos base; + + const BlockTypeRegistry ® + const Generator &gen; + + std::list loaded; + std::list to_generate; + std::list to_free; + + int load_dist; + int unload_dist; + +}; + } #endif