X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2FChunk.hpp;h=97765677e021be36cc0f863af7ca882b973c6820;hb=bc35c2b12391c30c86ab8b713f456c7d8a5d701d;hp=6e87a0907d15059cea8b15e5255022b333b4c12b;hpb=4727825186798902f68df5b99a6a32f0ef618454;p=blank.git diff --git a/src/world/Chunk.hpp b/src/world/Chunk.hpp index 6e87a09..9776567 100644 --- a/src/world/Chunk.hpp +++ b/src/world/Chunk.hpp @@ -5,15 +5,17 @@ #include "BlockTypeRegistry.hpp" #include "../geometry/Location.hpp" #include "../geometry/primitive.hpp" +#include "../graphics/glm.hpp" +#include #include -#include #include namespace blank { class BlockType; +class Entity; class WorldCollision; /// cube of size 16 (256 tiles, 4096 blocks) @@ -30,6 +32,16 @@ public: static constexpr int size = side * side * side; static AABB Bounds() noexcept { return AABB{ { 0.0f, 0.0f, 0.0f }, ExactLocation::FExtent() }; } + 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 @@ -43,6 +55,9 @@ public: pos.y >= 0 && pos.y < side && pos.z >= 0 && pos.z < side; } + static int ToIndex(const ExactLocation::Fine &pos) noexcept { + return ToIndex(RoughLocation::Fine(pos)); + } static constexpr int ToIndex(const RoughLocation::Fine &pos) noexcept { return pos.x + pos.y * side + pos.z * side * side; } @@ -66,7 +81,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; @@ -125,29 +144,44 @@ 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, const glm::mat4 &Mchunk, std::vector &) noexcept; + bool Intersection( + const Entity &entity, + const glm::mat4 &Mentity, + const glm::mat4 &Mchunk, + std::vector &) noexcept; + 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()); + return glm::translate(ExactLocation::Fine((position - offset) * ExactLocation::Extent())); } void *BlockData() noexcept { return &blocks[0]; } @@ -159,6 +193,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; } @@ -176,6 +214,8 @@ private: const BlockTypeRegistry *types; Chunk *neighbor[Block::FACE_COUNT]; + std::set gravity; + Block blocks[size]; unsigned char light[size]; bool generated;