]> git.localhorst.tv Git - blank.git/blobdiff - src/world.cpp
place and remove blocks via mouse
[blank.git] / src / world.cpp
index 2dd7b307a6ffa292fd24027414af746a5123504b..e3c10b166d7af213a407ea076658155bfb1b5ce9 100644 (file)
@@ -1,5 +1,7 @@
 #include "world.hpp"
 
+#include <limits>
+
 
 namespace blank {
 
@@ -48,12 +50,7 @@ void BlockType::FillVBO(
        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, glm::vec3(1.0f, 1.0f, 1.0f)); // front
-       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // back
-       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // top
-       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // bottom
-       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // left
-       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // right
+       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
@@ -64,6 +61,18 @@ void BlockType::FillVBO(
 }
 
 
+BlockTypeRegistry::BlockTypeRegistry() {
+       Add(BlockType::DEFAULT);
+}
+
+int BlockTypeRegistry::Add(const BlockType &t) {
+       int id = types.size();
+       types.push_back(t);
+       types.back().id = id;
+       return id;
+}
+
+
 Chunk::Chunk()
 : blocks(Size())
 , model()
@@ -80,6 +89,65 @@ void Chunk::Draw() {
 }
 
 
+bool Chunk::Intersection(
+       const Ray &ray,
+       const glm::mat4 &M,
+       int *blkid,
+       float *dist,
+       glm::vec3 *normal) const {
+       { // rough check
+               const AABB bb{{0, 0, 0}, {Width(), Height(), Depth()}};
+               if (!blank::Intersection(ray, bb, M)) {
+                       return false;
+               }
+       }
+
+       if (!blkid && !dist && !normal) {
+               return true;
+       }
+
+       // TODO: should be possible to heavily optimize this
+       int id = 0;
+       int closest_id = -1;
+       float closest_dist = std::numeric_limits<float>::infinity();
+       glm::vec3 closest_normal(0, 1, 0);
+       for (int z = 0; z < Depth(); ++z) {
+               for (int y = 0; y < Height(); ++y) {
+                       for (int x = 0; x < Width(); ++x, ++id) {
+                               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 (cur_dist < closest_dist) {
+                                               closest_id = id;
+                                               closest_dist = cur_dist;
+                                               closest_normal = cur_norm;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (closest_id < 0) {
+               return false;
+       }
+
+       if (blkid) {
+               *blkid = closest_id;
+       }
+       if (dist) {
+               *dist = closest_dist;
+       }
+       if (normal) {
+               *normal = closest_normal;
+       }
+       return true;
+}
+
+
 int Chunk::VertexCount() const {
        // TODO: query blocks as soon as type shapes are implemented
        return Size() * 6 * 6;