1
0
Fork 0
Univerxel/src/world/Area.hpp

66 lines
2.4 KiB
C++
Raw Normal View History

2020-08-02 20:15:53 +00:00
#pragma once
#include "forward.h"
#include <shared_mutex_guarded.h>
using namespace libguarded;
#include "region/index.hpp"
#include "Generator.hpp"
2020-08-03 16:15:02 +00:00
#include "../data/geometry/IBox.hpp"
2020-08-02 20:15:53 +00:00
namespace world {
/// Chunk map with restricted access
struct ChunkContainer: robin_hood::unordered_map<chunk_pos, std::shared_ptr<Chunk>> {
private:
int radius;
public:
2020-08-03 16:15:02 +00:00
/// Area radius in chunks
constexpr inline int getRadius() const { return radius; }
2020-08-02 20:15:53 +00:00
ChunkContainer(int radius): radius(radius) {
2020-08-03 16:15:02 +00:00
assert(radius > 0 && radius < (1 << 22) / CHUNK_LENGTH);
2020-08-02 20:15:53 +00:00
}
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>>;
/// radius: size in chunk (length = radius * 2 + 1)
2020-08-03 16:15:02 +00:00
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);
}
2020-08-02 20:15:53 +00:00
inline const ChunkContainer &getChunks() const { return chunks; }
inline ChunkContainer &setChunks() { return chunks; }
2020-08-03 16:15:02 +00:00
2020-08-02 20:15:53 +00:00
std::shared_ptr<Region> getRegion(const std::string& folderPath, const area_<region_pos> &);
shared_guarded<regions_t>::handle getRegions() { return regions.lock(); }
2020-08-03 16:15:02 +00:00
2020-08-02 20:15:53 +00:00
inline Generator &getGenerator() { return generator; }
private:
2020-08-03 16:15:02 +00:00
voxel_pos center;
//TODO: rotation
2020-08-02 20:15:53 +00:00
ChunkContainer chunks;
shared_guarded<regions_t> regions;
Generator generator;
};
}