]> git.localhorst.tv Git - blank.git/commitdiff
don't add obstructed blocks to meshes
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 11 Mar 2015 20:43:52 +0000 (21:43 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 11 Mar 2015 20:43:52 +0000 (21:43 +0100)
src/block.cpp
src/block.hpp
src/chunk.cpp
src/chunk.hpp
src/world.cpp

index cdfc452868ee4013298fed5d69e0fd4abef953ea..236a61ff62bcb0b2d122f78fc33691f35db2d3d1 100644 (file)
@@ -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,
index 1663c16aa0d4450f0cdc06d9e503d408c0350049..967cc1fccc69cf192950d0247fc0f9429e8ab88e 100644 (file)
@@ -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;
 
index bed947e3d5fdfff7182056313a30667ad9996edb..16ff4e5023bb65f4f68495294b7b940007b67239 100644 (file)
@@ -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 &reg, const Generator &gen)
 : base(0, 0, 0)
index e442e4e289107ee735417c9677ffa6157b42396d..e27cf5ed09d5b3e6a9b018e5bd1b4ca927450a47 100644 (file)
@@ -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; }
 
index 248685cc4add2b8c7840b5ecf3211d2d1bcac1a2..46abf711facdfc85ea497bd8ee8f555f44dc767e 100644 (file)
@@ -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 });