X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld.cpp;h=c24450cdb154e93d460cb4405146f8d3d8d08096;hb=5700ea3c08ea5e4a5c743f0413b65dc8eebfd220;hp=e3c10b166d7af213a407ea076658155bfb1b5ce9;hpb=8881c507009521d08648560984c0f50166224542;p=blank.git diff --git a/src/world.cpp b/src/world.cpp index e3c10b1..c24450c 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,6 +1,7 @@ #include "world.hpp" #include +#include namespace blank { @@ -76,10 +77,27 @@ int BlockTypeRegistry::Add(const BlockType &t) { Chunk::Chunk() : blocks(Size()) , model() +, transform(1.0f) , dirty(false) { } +Chunk::Chunk(Chunk &&other) +: blocks(std::move(other.blocks)) +, model(std::move(other.model)) +, transform(other.transform) +, dirty(other.dirty) { + +} + +Chunk &Chunk::operator =(Chunk &&other) { + blocks = std::move(other.blocks); + model = std::move(other.model); + transform = other.transform; + dirty = other.dirty; + return *this; +} + void Chunk::Draw() { if (dirty) { @@ -147,6 +165,11 @@ bool Chunk::Intersection( return true; } +void Chunk::Position(const glm::vec3 &pos) { + position = pos; + transform = glm::translate(pos * Extent()); +} + int Chunk::VertexCount() const { // TODO: query blocks as soon as type shapes are implemented @@ -167,4 +190,101 @@ void Chunk::Update() { dirty = false; } + +World::World() +: blockType() +, chunks() { + blockType.Add(BlockType(true, glm::vec3(1, 1, 1))); + blockType.Add(BlockType(true, glm::vec3(1, 0, 0))); + blockType.Add(BlockType(true, glm::vec3(0, 1, 0))); + blockType.Add(BlockType(true, glm::vec3(0, 0, 1))); +} + + +void World::Generate() { + for (int z = -1; z < 2; ++z) { + for (int y = -1; y < 2; ++y) { + for (int x = -1; x < 2; ++x) { + Generate(glm::vec3(x, y, z)); + } + } + } +} + +Chunk &World::Generate(const glm::vec3 &pos) { + chunks.emplace_back(); + Chunk &chunk = chunks.back(); + chunk.Position(pos); + chunk.BlockAt(glm::vec3(0, 0, 0)) = Block(blockType[4]); + chunk.BlockAt(glm::vec3(0, 0, 1)) = Block(blockType[1]); + chunk.BlockAt(glm::vec3(1, 0, 0)) = Block(blockType[2]); + chunk.BlockAt(glm::vec3(1, 0, 1)) = Block(blockType[3]); + chunk.BlockAt(glm::vec3(2, 0, 0)) = Block(blockType[4]); + chunk.BlockAt(glm::vec3(2, 0, 1)) = Block(blockType[1]); + chunk.BlockAt(glm::vec3(3, 0, 0)) = Block(blockType[2]); + chunk.BlockAt(glm::vec3(3, 0, 1)) = Block(blockType[3]); + chunk.BlockAt(glm::vec3(2, 0, 2)) = Block(blockType[4]); + chunk.BlockAt(glm::vec3(2, 0, 3)) = Block(blockType[1]); + chunk.BlockAt(glm::vec3(3, 0, 2)) = Block(blockType[2]); + chunk.BlockAt(glm::vec3(3, 0, 3)) = Block(blockType[3]); + chunk.BlockAt(glm::vec3(1, 1, 0)) = Block(blockType[1]); + chunk.BlockAt(glm::vec3(1, 1, 1)) = Block(blockType[4]); + chunk.BlockAt(glm::vec3(2, 1, 1)) = Block(blockType[3]); + chunk.BlockAt(glm::vec3(2, 2, 1)) = Block(blockType[2]); + chunk.Invalidate(); + return chunk; +} + +bool World::Intersection( + const Ray &ray, + const glm::mat4 &M, + Chunk **chunk, + int *blkid, + float *dist, + glm::vec3 *normal) { + Chunk *closest_chunk = nullptr; + int closest_blkid = -1; + float closest_dist = std::numeric_limits::infinity(); + glm::vec3 closest_normal; + + for (Chunk &cur_chunk : chunks) { + int cur_blkid; + float cur_dist; + glm::vec3 cur_normal; + if (cur_chunk.Intersection(ray, M * cur_chunk.Transform(), &cur_blkid, &cur_dist, &cur_normal)) { + if (cur_dist < closest_dist) { + closest_chunk = &cur_chunk; + closest_blkid = cur_blkid; + closest_dist = cur_dist; + closest_normal = cur_normal; + } + } + } + + if (chunk) { + *chunk = closest_chunk; + } + if (blkid) { + *blkid = closest_blkid; + } + if (dist) { + *dist = closest_dist; + } + if (normal) { + *normal = closest_normal; + } + return closest_chunk; +} + + +Chunk &World::Next(const Chunk &to, const glm::vec3 &dir) { + const glm::vec3 tgt_pos = to.Position() + dir; + for (Chunk &chunk : chunks) { + if (chunk.Position() == tgt_pos) { + return chunk; + } + } + return Generate(tgt_pos); +} + }