--- /dev/null
+#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<glm::vec3> &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<glm::vec3> &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<glm::vec3> &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);
+}
+
+}
namespace blank {
const BlockType BlockType::DEFAULT;
+const CuboidShape BlockType::DEFAULT_SHAPE({{ 0, 0, 0 }, { 1, 1, 1 }});
void BlockType::FillVBO(
const glm::vec3 &pos,
std::vector<glm::vec3> &colors,
std::vector<glm::vec3> &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<glm::vec3> &vertices,
std::vector<glm::vec3> &colors
) const {
- vertices = std::vector<glm::vec3>({
- { 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);
}
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;
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() {
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
}
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;
}