#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>; /// radius: size in chunk (length = radius * 2 + 1) Area(const voxel_pos& center, int radius, int seed = 42): center(center), chunks(radius), generator(seed) { } inline const voxel_pos &getOffset() const { return center; } inline geometry::IBox getBounding() const { return geometry::IBox(center - voxel_pos(CHUNK_LENGTH * (chunks.getRadius() - 1)), center + voxel_pos(CHUNK_LENGTH * chunks.getRadius())); } /// Move offset return if chunk_change constexpr bool inline move(const voxel_pos &offset) { const auto prev = glm::divide(center); center += offset; return prev != glm::divide(center); } 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; } private: voxel_pos center; //TODO: rotation ChunkContainer chunks; shared_guarded regions; Generator generator; }; }