X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fchunk.hpp;h=06dc98bab34075ba0234103a572f1f17b55609b9;hb=35c09fc00094a3d390732fd533b2bd03413d90c7;hp=ae773657ad3a6925f20556c7b922bf5428bde770;hpb=1b022dd17364c9e3344afd86572f2ead14973cde;p=blank.git diff --git a/src/chunk.hpp b/src/chunk.hpp index ae77365..06dc98b 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -32,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(); @@ -51,6 +57,13 @@ 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) { @@ -63,19 +76,43 @@ public: (idx / Width()) % Height() == Height() - 1; // high Y plane } - // check if block at given index is completely enclosed (and therefore invisible) - bool Obstructed(int idx) const; + bool IsSurface(int index) const { return IsSurface(ToPos(index)); } + bool IsSurface(const Block::Pos &pos) const { return IsSurface(Pos(pos)); } + bool IsSurface(const Pos &pos) const; + + 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 which faces of a block at given index are obstructed (and therefore invisible) + Block::FaceSet 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 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)); } + + float GetVertexLight(int index, const BlockModel::Position &, const Model::Normal &) const; + bool Intersection( const Ray &ray, const glm::mat4 &M, @@ -103,22 +140,56 @@ private: private: const BlockTypeRegistry *types; - std::vector blocks; - Model model; + Chunk *neighbor[Block::FACE_COUNT]; + Block blocks[16 * 16 * 16]; + unsigned char light[16 * 16 * 16]; + BlockModel model; Pos position; bool dirty; }; +class BlockLookup { + +public: + // resolve chunk/position from oob coordinates + BlockLookup(Chunk *c, const Chunk::Pos &p); + + // resolve chunk/position from ib coordinates and direction + BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir); + + // check if lookup was successful + operator bool() const { return chunk; } + + // only valid if lookup was successful + Chunk &GetChunk() const { return *chunk; } + const Chunk::Pos &GetBlockPos() const { return pos; } + const Block &GetBlock() const { return GetChunk().BlockAt(GetBlockPos()); } + const BlockType &GetType() const { return GetChunk().Type(GetBlock()); } + int GetLight() const { return GetChunk().GetLight(GetBlockPos()); } + +private: + Chunk *chunk; + Chunk::Pos pos; + +}; + + class Generator; class ChunkLoader { public: - ChunkLoader(const BlockTypeRegistry &, const Generator &); + struct Config { + int load_dist = 6; + int unload_dist = 8; + }; + + ChunkLoader(const Config &, const BlockTypeRegistry &, const Generator &); void Generate(const Chunk::Pos &from, const Chunk::Pos &to); + void GenerateSurrounding(const Chunk::Pos &); std::list &Loaded() { return loaded; } @@ -130,6 +201,11 @@ public: void Rebase(const Chunk::Pos &); void Update(); +private: + Chunk &Generate(const Chunk::Pos &pos); + void Insert(Chunk &); + void Remove(Chunk &); + private: Chunk::Pos base;