]> git.localhorst.tv Git - blank.git/blobdiff - src/world/Chunk.hpp
improved ray/world collision a little
[blank.git] / src / world / Chunk.hpp
index 4938c1b1a7a92f3f34c861e30287ca23491c6686..67794145290ea8adcbaef3dc00618f0122cb93d6 100644 (file)
@@ -6,6 +6,7 @@
 #include "../geometry/Location.hpp"
 #include "../geometry/primitive.hpp"
 
+#include <set>
 #include <vector>
 #include <glm/glm.hpp>
 #include <glm/gtx/transform.hpp>
@@ -34,6 +35,14 @@ public:
        static glm::vec3 Center() noexcept { return glm::vec3(8.0f); }
        static float Radius() noexcept { return 27.71281292110203669632f; /* 16 * √3 */ }
 
+       /// get bounding box relative to given reference chunk
+       AABB RelativeBounds(const ExactLocation::Coarse &ref) const noexcept {
+               AABB bounds;
+               bounds.min = (position - ref) * ExactLocation::Extent();
+               bounds.max = bounds.min + ExactLocation::FExtent();
+               return bounds;
+       }
+
        static constexpr bool InBounds(const ExactLocation::Fine &pos) noexcept {
                return
                        pos.x >= 0.0f && pos.x < fside &&
@@ -69,7 +78,11 @@ public:
                        (idx / (side * side))
                );
        }
-       glm::mat4 ToTransform(const RoughLocation::Fine &pos, int idx) const noexcept;
+       /// get a chunk-local transform for block at given position and index
+       /// (position and index are redundant)
+       glm::mat4 ToTransform(const RoughLocation::Fine &position, int index) const noexcept;
+       /// same as above, but also apply offset to given reference
+       glm::mat4 ToTransform(const ExactLocation::Coarse &ref, const RoughLocation::Fine &pos, int idx) const noexcept;
 
        ExactLocation::Fine ToSceneCoords(const ExactLocation::Coarse &base, const ExactLocation::Fine &pos) const noexcept {
                return ExactLocation::Fine((position - base) * ExactLocation::Extent()) + pos;
@@ -128,19 +141,27 @@ public:
 
        float GetVertexLight(const RoughLocation::Fine &, const BlockMesh::Position &, const EntityMesh::Normal &) const noexcept;
 
+       /// get gravity for one unit mass at given point
+       glm::vec3 GravityAt(const ExactLocation &) const noexcept;
+
+       /// check if given ray passes this chunk at all
+       /// given reference indicates the chunk offset of the ray in world space
        bool Intersection(
                const Ray &ray,
-               const glm::mat4 &M,
+               const ExactLocation::Coarse &reference,
                float &dist
        ) const noexcept {
-               return blank::Intersection(ray, Bounds(), M, &dist);
+               return blank::Intersection(ray, RelativeBounds(reference), dist);
        }
 
+       /// check if given ray intersects any block of this chunk
+       /// given reference indicates the chunk offset of the ray in world space
        bool Intersection(
                const Ray &,
-               const glm::mat4 &M,
+               const ExactLocation::Coarse &reference,
                WorldCollision &) noexcept;
 
+       /// get all blocks intersecting given box
        bool Intersection(
                const AABB &box,
                const glm::mat4 &Mbox,
@@ -155,6 +176,7 @@ public:
 
        void Position(const ExactLocation::Coarse &pos) noexcept { position = pos; }
        const ExactLocation::Coarse &Position() const noexcept { return position; }
+
        glm::mat4 Transform(const ExactLocation::Coarse &offset) const noexcept {
                return glm::translate((position - offset) * ExactLocation::Extent());
        }
@@ -168,6 +190,10 @@ public:
        bool Lighted() const noexcept { return lighted; }
        void ScanLights();
 
+       /// check for active blocks, should be called after
+       /// block data was modified by means other than SetBlock()
+       void ScanActive();
+
        void Ref() noexcept { ++ref_count; }
        void UnRef() noexcept { --ref_count; }
        bool Referenced() const noexcept { return ref_count > 0; }
@@ -185,6 +211,8 @@ private:
        const BlockTypeRegistry *types;
        Chunk *neighbor[Block::FACE_COUNT];
 
+       std::set<int> gravity;
+
        Block blocks[size];
        unsigned char light[size];
        bool generated;