75 lines
2.6 KiB
C++
75 lines
2.6 KiB
C++
#pragma once
|
|
|
|
#include "forward.h"
|
|
#include <shared_mutex_guarded.h>
|
|
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<chunk_pos, std::shared_ptr<Chunk>> {
|
|
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<std::shared_ptr<Chunk>> findInRange(const chunk_pos &pos) const;
|
|
std::optional<std::shared_ptr<const Chunk>> findOrEmpty(const chunk_pos &pos) const;
|
|
};
|
|
|
|
/// Area (aka big group of chunks)
|
|
struct Area {
|
|
public:
|
|
using regions_t = robin_hood::unordered_map<region_pos, std::shared_ptr<Region>>;
|
|
|
|
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<Region> getRegion(const std::string& folderPath, const area_<region_pos> &);
|
|
shared_guarded<regions_t>::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_t> regions;
|
|
|
|
Generator generator;
|
|
};
|
|
} |