From: Daniel Karbach Date: Fri, 6 Mar 2015 16:14:56 +0000 (+0100) Subject: abstract block shape X-Git-Url: http://git.localhorst.tv/?a=commitdiff_plain;h=b79bc060068daf80c707f7ca08cb40a716367784;p=blank.git abstract block shape --- diff --git a/src/app.cpp b/src/app.cpp index 5463f7f..4f7cbdc 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -159,6 +159,7 @@ void Application::Update(int dt) { if (world.Intersection(aim, glm::mat4(1.0f), &chunk, &blkid, &dist, &normal)) { glm::vec3 pos = Chunk::ToCoords(blkid); outline_visible = true; + outline.Clear(); chunk->BlockAt(blkid).type->FillOutlineModel(outline); outline_transform = glm::translate(chunk->Transform(), pos); } else { diff --git a/src/shape.cpp b/src/shape.cpp new file mode 100644 index 0000000..e974d06 --- /dev/null +++ b/src/shape.cpp @@ -0,0 +1,104 @@ +#include "shape.hpp" + + +namespace blank { + +CuboidShape::CuboidShape(const AABB &b) +: Shape() +, bb(b) { + bb.Adjust(); +} + + +size_t CuboidShape::VertexCount() const { + return 36; +} + +void CuboidShape::Vertices(std::vector &out, const glm::vec3 &pos) const { + out.reserve(36); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); // front + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // back + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); // top + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // bottom + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); // left + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); // right + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); +} + +void CuboidShape::Normals(std::vector &out) const { + out.reserve(36); + out.insert(out.end(), 6, glm::vec3( 0.0f, 0.0f, 1.0f)); // front + out.insert(out.end(), 6, glm::vec3( 0.0f, 0.0f, -1.0f)); // back + out.insert(out.end(), 6, glm::vec3( 0.0f, 1.0f, 0.0f)); // top + out.insert(out.end(), 6, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom + out.insert(out.end(), 6, glm::vec3(-1.0f, 0.0f, 0.0f)); // left + out.insert(out.end(), 6, glm::vec3( 1.0f, 0.0f, 0.0f)); // right +} + + +size_t CuboidShape::OutlineCount() const { + return 24; +} + +void CuboidShape::Outline(std::vector &out, const glm::vec3 &pos) const { + out.reserve(24); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.min.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.min.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.max.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.max.y, pos.z + bb.max.z); + out.emplace_back(pos.x + bb.min.x, pos.y + bb.min.y, pos.z + bb.max.z); +} + +bool CuboidShape::Intersects(const Ray &ray, const glm::mat4 &M, float &dist, glm::vec3 &normal) const { + return Intersection(ray, bb, M, &dist, &normal); +} + +} diff --git a/src/shape.hpp b/src/shape.hpp new file mode 100644 index 0000000..438fa10 --- /dev/null +++ b/src/shape.hpp @@ -0,0 +1,48 @@ +#ifndef BLANK_SHAPE_HPP_ +#define BLANK_SHAPE_HPP_ + +#include "geometry.hpp" + +#include +#include + + +namespace blank { + +struct Shape { + + virtual size_t VertexCount() const = 0; + virtual void Vertices(std::vector &, const glm::vec3 &pos = { 0.0f, 0.0f, 0.0f }) const = 0; + virtual void Normals(std::vector &) const = 0; + + virtual size_t OutlineCount() const = 0; + virtual void Outline(std::vector &, const glm::vec3 &pos = { 0.0f, 0.0f, 0.0f }) const = 0; + + virtual bool Intersects(const Ray &, const glm::mat4 &, float &dist, glm::vec3 &normal) const = 0; + +}; + + +class CuboidShape +: public Shape { + +public: + CuboidShape(const AABB &bounds); + + size_t VertexCount() const override; + void Vertices(std::vector &, const glm::vec3 &) const override; + void Normals(std::vector &) const override; + + size_t OutlineCount() const override; + void Outline(std::vector &, const glm::vec3 &) const override; + + bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; + +private: + AABB bb; + +}; + +} + +#endif diff --git a/src/world.cpp b/src/world.cpp index 2ac65ab..c1d1f5a 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -7,6 +7,7 @@ namespace blank { const BlockType BlockType::DEFAULT; +const CuboidShape BlockType::DEFAULT_SHAPE({{ 0, 0, 0 }, { 1, 1, 1 }}); void BlockType::FillVBO( const glm::vec3 &pos, @@ -14,72 +15,17 @@ void BlockType::FillVBO( std::vector &colors, std::vector &normals ) const { - vertices.emplace_back(pos.x , pos.y , pos.z + 1); // front - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z ); // back - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); // top - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z ); // bottom - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y , pos.z ); // left - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y + 1, pos.z ); - vertices.emplace_back(pos.x , pos.y , pos.z + 1); - vertices.emplace_back(pos.x , pos.y + 1, pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z ); // right - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y , pos.z + 1); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z ); - vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1); - - colors.insert(colors.end(), 6 * 6, color); - - normals.insert(normals.end(), 6, glm::vec3( 0.0f, 0.0f, 1.0f)); // front - normals.insert(normals.end(), 6, glm::vec3( 0.0f, 0.0f, -1.0f)); // back - normals.insert(normals.end(), 6, glm::vec3( 0.0f, 1.0f, 0.0f)); // top - normals.insert(normals.end(), 6, glm::vec3( 0.0f, -1.0f, 0.0f)); // bottom - normals.insert(normals.end(), 6, glm::vec3(-1.0f, 0.0f, 0.0f)); // left - normals.insert(normals.end(), 6, glm::vec3( 1.0f, 0.0f, 0.0f)); // right + shape->Vertices(vertices, pos); + colors.insert(colors.end(), shape->VertexCount(), color); + shape->Normals(normals); } void BlockType::FillOutlineVBO( std::vector &vertices, std::vector &colors ) const { - vertices = std::vector({ - { 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, - { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 1.0f }, - { 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f }, - { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, - { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, - { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, - { 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, - }); - colors.resize(24, outline_color); + shape->Outline(vertices); + colors.insert(colors.end(), shape->OutlineCount(), outline_color); } @@ -156,10 +102,9 @@ bool Chunk::Intersection( if (!blocks[id].type->visible) { continue; } - const AABB bb{{x, y, z}, {x+1, y+1, z+1}}; float cur_dist; glm::vec3 cur_norm; - if (blank::Intersection(ray, bb, M, &cur_dist, &cur_norm)) { + if (blocks[id].type->shape->Intersects(ray, glm::translate(M, glm::vec3(x, y, z)), cur_dist, cur_norm)) { if (cur_dist < closest_dist) { closest_id = id; closest_dist = cur_dist; @@ -194,7 +139,11 @@ void Chunk::Position(const glm::vec3 &pos) { int Chunk::VertexCount() const { // TODO: query blocks as soon as type shapes are implemented - return Size() * 6 * 6; + int count = 0; + for (const auto &block : blocks) { + count += block.type->shape->VertexCount(); + } + return count; } void Chunk::Update() { @@ -214,11 +163,17 @@ void Chunk::Update() { World::World() : blockType() +, blockShape({{ 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f }}) +, slabShape({{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.5f, 1.0f }}) , 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))); + blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &blockShape }); // white block + blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &slabShape }); // white slab + blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &blockShape }); // red block + blockType.Add(BlockType{ true, { 1.0f, 0.0f, 0.0f }, &slabShape }); // red slab + blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &blockShape }); // green block + blockType.Add(BlockType{ true, { 0.0f, 1.0f, 0.0f }, &slabShape }); // green slab + blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &blockShape }); // blue block + blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &slabShape }); // blue slab } @@ -236,22 +191,29 @@ 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]); + for (int i = 1; i < 9; ++i) { + chunk.BlockAt(i) = Block(blockType[i]); + chunk.BlockAt(i + 257) = Block(blockType[i]); + chunk.BlockAt(i + 514) = Block(blockType[i]); + } + if (false) { + 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[5]); + 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[5]); + 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[5]); + chunk.BlockAt(glm::vec3(1, 1, 0)) = Block(blockType[5]); + 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; } diff --git a/src/world.hpp b/src/world.hpp index 9fb0779..83fd3e8 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -1,8 +1,9 @@ #ifndef BLANK_WORLD_HPP_ #define BLANK_WORLD_HPP_ -#include "model.hpp" #include "geometry.hpp" +#include "model.hpp" +#include "shape.hpp" #include #include @@ -18,16 +19,20 @@ struct BlockType { int id; bool visible; + + const Shape *shape; glm::vec3 color; glm::vec3 outline_color; - constexpr explicit BlockType( + explicit BlockType( bool v = false, const glm::vec3 &color = { 1, 1, 1 }, + const Shape *shape = &DEFAULT_SHAPE, const glm::vec3 &outline_color = { -1, -1, -1 }) - : id(-1), visible(v), color(color), outline_color(outline_color) { } + : id(-1), visible(v), shape(shape), color(color), outline_color(outline_color) { } static const BlockType DEFAULT; + static const CuboidShape DEFAULT_SHAPE; void FillVBO( @@ -178,6 +183,9 @@ private: private: BlockTypeRegistry blockType; + CuboidShape blockShape; + CuboidShape slabShape; + std::list chunks; };