#pragma once #include "forward.h" #include using namespace libguarded; #include "region/index.hpp" #include "Generator.hpp" #include "../data/geometry/IBox.hpp" namespace world { /// Chunk map with restricted access struct ChunkContainer: robin_hood::unordered_map> { private: int radius; public: /// Area radius in chunks constexpr inline int getRadius() const { return radius; } ChunkContainer(int radius): radius(radius) { assert(radius > 0 && radius < (1 << 22) / CHUNK_LENGTH); } inline bool inRange(const chunk_pos& pos) const { return glm::abs(pos.x) < radius && glm::abs(pos.y) < radius && glm::abs(pos.z) < radius; } std::optional> findInRange(const chunk_pos &pos) const; std::optional> findOrEmpty(const chunk_pos &pos) const; }; /// Area (aka big group of chunks) struct Area { public: using regions_t = robin_hood::unordered_map>; struct params { voxel_pos center; int radius; int seed = 42; }; /// radius: size in chunk (length = radius * 2 + 1) Area(const params& p): center(p.center), chunks(p.radius), generator(p.seed) { } inline const area_pos &getOffset() const { return center; } inline geometry::IBox getBounding() const { const auto c = center.as_voxel(); return geometry::IBox(c - voxel_pos(CHUNK_LENGTH * (chunks.getRadius() - 1)), c + voxel_pos(CHUNK_LENGTH * chunks.getRadius())); } /// Move offset return if chunk_change bool inline move(const area_pos::offset_t &offset) { const auto prev = glm::divide(center.as_voxel()); center = center + offset; return prev != glm::divide(center.as_voxel()); } inline const ChunkContainer &getChunks() const { return chunks; } inline ChunkContainer &setChunks() { return chunks; } std::shared_ptr getRegion(const std::string& folderPath, const area_ &); shared_guarded::handle getRegions() { return regions.lock(); } inline Generator &getGenerator() { return generator; } inline params getParams() const { return params{center.as_voxel(), chunks.getRadius(), generator.getSeed()}; } private: area_pos center; //TODO: rotation ChunkContainer chunks; shared_guarded regions; Generator generator; }; }