#include "BlockTypeRegistry.hpp"
#include "../geometry/Location.hpp"
#include "../geometry/primitive.hpp"
+#include "../graphics/glm.hpp"
+#include <set>
#include <vector>
-#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
namespace blank {
class BlockType;
+class Entity;
class WorldCollision;
/// cube of size 16 (256 tiles, 4096 blocks)
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 &&
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;
}
(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;
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<WorldCollision> &) noexcept;
+ bool Intersection(
+ const Entity &entity,
+ const glm::mat4 &Mentity,
+ const glm::mat4 &Mchunk,
+ std::vector<WorldCollision> &) 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]; }
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; }
const BlockTypeRegistry *types;
Chunk *neighbor[Block::FACE_COUNT];
+ std::set<int> gravity;
+
Block blocks[size];
unsigned char light[size];
bool generated;