From: Daniel Karbach Date: Wed, 11 Mar 2015 20:43:52 +0000 (+0100) Subject: don't add obstructed blocks to meshes X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=a58c4558e7d4934f4d0ee621520acfe1c8258c93;p=blank.git don't add obstructed blocks to meshes --- diff --git a/src/block.cpp b/src/block.cpp index cdfc452..236a61f 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -5,6 +5,16 @@ namespace blank { const NullShape BlockType::DEFAULT_SHAPE; +BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) +: shape(s) +, color(col) +, outline_color(-1, -1, -1) +, id(0) +, visible(v) +, fill({ false, false, false, false, false, false }) { + +} + void BlockType::FillModel( Model::Buffer &buf, const glm::vec3 &pos_offset, diff --git a/src/block.hpp b/src/block.hpp index 1663c16..967cc1f 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -28,20 +28,28 @@ struct Block { /// attributes of a type of block struct BlockType { + const Shape *shape; + glm::vec3 color; + glm::vec3 outline_color; + Block::Type id; bool visible; - const Shape *shape; - glm::vec3 color; - glm::vec3 outline_color; + struct Faces { + bool right; + bool left; + bool top; + bool bottom; + bool front; + bool back; + } fill; 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(0), visible(v), shape(shape), color(color), outline_color(outline_color) { } + const Shape *shape = &DEFAULT_SHAPE + ); static const NullShape DEFAULT_SHAPE; diff --git a/src/chunk.cpp b/src/chunk.cpp index bed947e..16ff4e5 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -137,6 +137,8 @@ void Chunk::Update() { Model::Index vtx_counter = 0; for (size_t i = 0; i < Size(); ++i) { + if (Obstructed(i)) continue; + const BlockType &type = Type(blocks[i]); type.FillModel(buf, ToCoords(i), vtx_counter); vtx_counter += type.shape->VertexCount(); @@ -146,6 +148,34 @@ void Chunk::Update() { dirty = false; } +bool Chunk::Obstructed(int idx) const { + if (IsBorder(idx)) return false; + + // not checking neighbor visibility here, so all + // invisible blocks must have their fill set to 6x false + // (the default, so should be okay) + + const BlockType &right = Type(blocks[idx + 1]); + if (!right.fill.left) return false; + + const BlockType &left = Type(blocks[idx - 1]); + if (!left.fill.right) return false; + + const BlockType &top = Type(blocks[idx + Width()]); + if (!top.fill.bottom) return false; + + const BlockType &bottom = Type(blocks[idx - Width()]); + if (!bottom.fill.top) return false; + + const BlockType &front = Type(blocks[idx + Width() * Height()]); + if (!front.fill.back) return false; + + const BlockType &back = Type(blocks[idx - Width() * Height()]); + if (!back.fill.front) return false; + + return true; +} + ChunkLoader::ChunkLoader(const BlockTypeRegistry ®, const Generator &gen) : base(0, 0, 0) diff --git a/src/chunk.hpp b/src/chunk.hpp index e442e4e..e27cf5e 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -52,6 +52,17 @@ public: ); } + static constexpr bool IsBorder(int idx) { + return + idx < Width() * Height() || + (idx / Width()) % Height() == 0 || + (idx / Width()) % Height() == Height() - 1 || + (idx / (Width() * Height())) == Depth() - 1; + } + + // check if block at given index is completely enclosed (and therefore invisible) + bool Obstructed(int idx) const; + void Allocate(); void Invalidate() { dirty = true; } diff --git a/src/world.cpp b/src/world.cpp index 248685c..46abf71 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -14,18 +14,73 @@ World::World() , generate(0) , chunks(blockType, generate) , player() { - blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &blockShape }); // white block - blockType.Add(BlockType{ true, { 1.0f, 1.0f, 1.0f }, &stairShape }); // white stair - 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 }, &stairShape }); // red stair - 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 }, &stairShape }); // green stair - 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 }, &stairShape }); // blue stair - blockType.Add(BlockType{ true, { 0.0f, 0.0f, 1.0f }, &slabShape }); // blue slab + BlockType::Faces block_fill = { true, true, true, true, true, true }; + BlockType::Faces slab_fill = { false, false, false, true, false, false }; + BlockType::Faces stair_fill = { true, false, false, true, false, false }; + + { // white block + BlockType type(true, { 1.0f, 1.0f, 1.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // white slab + BlockType type(true, { 1.0f, 1.0f, 1.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // white stair + BlockType type(true, { 1.0f, 1.0f, 1.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + + { // red block + BlockType type(true, { 1.0f, 0.0f, 0.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // red slab + BlockType type(true, { 1.0f, 0.0f, 0.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // red stair + BlockType type(true, { 1.0f, 0.0f, 0.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + + { // green block + BlockType type(true, { 0.0f, 1.0f, 0.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // green slab + BlockType type(true, { 0.0f, 1.0f, 0.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // green stair + BlockType type(true, { 0.0f, 1.0f, 0.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } + + { // blue block + BlockType type(true, { 0.0f, 0.0f, 1.0f }, &blockShape); + type.fill = block_fill; + blockType.Add(type); + } + { // blue slab + BlockType type(true, { 0.0f, 0.0f, 1.0f }, &slabShape); + type.fill = slab_fill; + blockType.Add(type); + } + { // blue stair + BlockType type(true, { 0.0f, 0.0f, 1.0f }, &stairShape); + type.fill = stair_fill; + blockType.Add(type); + } generate.Space(0); generate.Solids({ 1, 4, 7, 10 });