Areas onload and index
This commit is contained in:
parent
a05378c274
commit
8d0c9194b0
4
TODO.md
4
TODO.md
|
@ -16,8 +16,8 @@
|
|||
- [x] Unload unused
|
||||
- [x] Edition
|
||||
- [ ] Entity
|
||||
- [ ] Area
|
||||
- [ ] Offset
|
||||
- [x] Area
|
||||
- [x] Offset
|
||||
- [ ] Rotation
|
||||
- [ ] Planet
|
||||
- [ ] CubicSphere
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
#include "math.hpp"
|
||||
|
||||
using namespace glm;
|
||||
ifvec3::ifvec3(const llvec3 &pos, int density) : raw(divide(pos, uvec3(IDX_LENGTH2 * density))), offset(0) {}
|
||||
ifvec3::ifvec3(const llvec3 &pos, uint density) {
|
||||
const auto d = IDX_LENGTH2 * density;
|
||||
raw = divide(pos, glm::uvec3(d));
|
||||
offset = glm::vec3(rem(pos.x, d), rem(pos.y, d), rem(pos.z, d));
|
||||
if(density > 1) center();
|
||||
}
|
||||
llvec3 ifvec3::raw_as_long() const {
|
||||
return llvec3(raw) * llvec3(IDX_LENGTH2);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace glm {
|
|||
ifvec3(const raw_t &raw, const offset_t &offset, bool recenter = true) : raw(raw), offset(offset) {
|
||||
if(recenter) center();
|
||||
}
|
||||
ifvec3(const glm::llvec3 &pos, int density = 1);
|
||||
ifvec3(const glm::llvec3 &pos, uint density = 1);
|
||||
|
||||
raw_t raw;
|
||||
offset_t offset;
|
||||
|
|
|
@ -31,8 +31,14 @@ namespace world {
|
|||
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 area_pos& center, int radius, int seed = 42): center(center), chunks(radius), generator(seed) { }
|
||||
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 {
|
||||
|
@ -55,6 +61,8 @@ namespace world {
|
|||
|
||||
inline Generator &getGenerator() { return generator; }
|
||||
|
||||
inline params getParams() const { return params{center.as_voxel(), chunks.getRadius(), generator.getSeed()}; }
|
||||
|
||||
private:
|
||||
area_pos center;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace world {
|
|||
#else
|
||||
using noise = FastNoiseSIMD *;
|
||||
#endif
|
||||
Generator(int seed = 42) {
|
||||
Generator(int seed = 42): seed(seed) {
|
||||
#if HASTY
|
||||
printf("double!!!\n");
|
||||
const size_t fastestSimd = HastyNoise::GetFastestSIMD();
|
||||
|
@ -65,7 +65,10 @@ namespace world {
|
|||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
inline int getSeed() const { return seed; }
|
||||
|
||||
private:
|
||||
int seed;
|
||||
noise densityNoise;
|
||||
noise materialNoise;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
using namespace world;
|
||||
|
||||
const auto MAIN_AREA = 1;
|
||||
const auto AREAS_FILE = "/areas.idx";
|
||||
|
||||
Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"), contouring(std::make_shared<contouring::Dummy>()) {
|
||||
setOptions(options);
|
||||
|
@ -21,8 +21,34 @@ Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"
|
|||
running = true;
|
||||
|
||||
std::filesystem::create_directories(folderPath);
|
||||
//areas.emplace(MAIN_AREA, std::make_shared<Area>(area_pos(glm::multiply(chunk_pos(1 << 8, 0, 0))), 1 << 20));
|
||||
areas.emplace(2, std::make_shared<Area>(area_pos(voxel_pos(0)), 1 << 20));
|
||||
{
|
||||
std::ifstream index(folderPath + AREAS_FILE);
|
||||
if(index.good()) {
|
||||
size_t size = 0;
|
||||
index.read(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
while(!index.eof()) {
|
||||
area_id id = 0;
|
||||
index.read(reinterpret_cast<char *>(&id), sizeof(area_id));
|
||||
Area::params params{voxel_pos(0), 0};
|
||||
index.read(reinterpret_cast<char *>(¶ms.center.x), sizeof(voxel_pos::value_type));
|
||||
index.read(reinterpret_cast<char *>(¶ms.center.y), sizeof(voxel_pos::value_type));
|
||||
index.read(reinterpret_cast<char *>(¶ms.center.z), sizeof(voxel_pos::value_type));
|
||||
index.read(reinterpret_cast<char *>(¶ms.radius), sizeof(int));
|
||||
index.read(reinterpret_cast<char *>(¶ms.seed), sizeof(int));
|
||||
auto ok = far_areas.emplace(id, params).second;
|
||||
assert(ok && "Duplicated area");
|
||||
index.peek();
|
||||
}
|
||||
assert(far_areas.size() == size && "Corrupted areas index");
|
||||
LOG_D(far_areas.size() << " areas loaded");
|
||||
} else {
|
||||
LOG_E("No index file!!! Probably a new world...");
|
||||
//TODO: generate universe
|
||||
far_areas.emplace(1, Area::params{voxel_pos(0), 1 << 20});
|
||||
far_areas.emplace(2, Area::params{voxel_pos(0), 1, 43});
|
||||
}
|
||||
index.close();
|
||||
}
|
||||
|
||||
// Load workers
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
|
@ -90,6 +116,7 @@ Universe::~Universe() {
|
|||
} while (size > 0);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
saveAreas();
|
||||
|
||||
running = false;
|
||||
loadQueue.notify();
|
||||
|
@ -106,12 +133,61 @@ Universe::~Universe() {
|
|||
LOG_D("Universe disappeared");
|
||||
}
|
||||
|
||||
// Write areas index (warn: file io)
|
||||
void Universe::saveAreas() const {
|
||||
std::ofstream index(folderPath + AREAS_FILE, std::ios::out | std::ios::binary);
|
||||
if(!index.good()) {
|
||||
LOG_E("Areas index write error");
|
||||
return;
|
||||
}
|
||||
{
|
||||
size_t size = areas.size() + far_areas.size();
|
||||
index.write(reinterpret_cast<char *>(&size), sizeof(size));
|
||||
}
|
||||
for(const auto& area: areas) {
|
||||
auto id = area.first;
|
||||
auto params = area.second->getParams();
|
||||
index.write(reinterpret_cast<char *>(&id), sizeof(area_id));
|
||||
index.write(reinterpret_cast<char *>(¶ms.center.x), sizeof(voxel_pos::value_type));
|
||||
index.write(reinterpret_cast<char *>(¶ms.center.y), sizeof(voxel_pos::value_type));
|
||||
index.write(reinterpret_cast<char *>(¶ms.center.z), sizeof(voxel_pos::value_type));
|
||||
index.write(reinterpret_cast<char *>(¶ms.radius), sizeof(int));
|
||||
index.write(reinterpret_cast<char *>(¶ms.seed), sizeof(int));
|
||||
}
|
||||
for(auto far: far_areas) {
|
||||
index.write(reinterpret_cast<char *>(&far.first), sizeof(area_id));
|
||||
index.write(reinterpret_cast<char *>(&far.second.center.x), sizeof(voxel_pos::value_type));
|
||||
index.write(reinterpret_cast<char *>(&far.second.center.y), sizeof(voxel_pos::value_type));
|
||||
index.write(reinterpret_cast<char *>(&far.second.center.z), sizeof(voxel_pos::value_type));
|
||||
index.write(reinterpret_cast<char *>(&far.second.radius), sizeof(int));
|
||||
index.write(reinterpret_cast<char *>(&far.second.seed), sizeof(int));
|
||||
}
|
||||
if(!index.good())
|
||||
LOG_E("Areas index write error");
|
||||
|
||||
index.close();
|
||||
}
|
||||
|
||||
void Universe::update(const voxel_pos& pos, float deltaTime, Universe::report& rep) {
|
||||
rmt_ScopedCPUSample(Universe, 0);
|
||||
const chunk_pos newPos = glm::divide(pos);
|
||||
const auto chunkChange = last_pos != newPos;
|
||||
last_pos = newPos;
|
||||
|
||||
if(chunkChange) {
|
||||
rmt_ScopedCPUSample(Far, 0);
|
||||
auto it = far_areas.begin();
|
||||
while(it != far_areas.end()) {
|
||||
const chunk_pos diff = glm::divide(pos - it->second.center);
|
||||
if (glm::length2(diff) > glm::pow2(loadDistance + it->second.radius)) {
|
||||
it++;
|
||||
} else {
|
||||
LOG_I("Load area " << it->first);
|
||||
areas.emplace(it->first, std::make_shared<Area>(it->second));
|
||||
it = far_areas.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // Update alive areas
|
||||
rmt_ScopedCPUSample(Update, 0);
|
||||
size_t chunk_count = 0;
|
||||
|
@ -130,7 +206,10 @@ void Universe::update(const voxel_pos& pos, float deltaTime, Universe::report& r
|
|||
saveQueue.emplace(*it, *it_c);
|
||||
it_c = chunks.erase(it_c);
|
||||
}
|
||||
LOG_I("Remove area " << it->first);
|
||||
far_areas.emplace(it->first, it->second->getParams());
|
||||
it = areas.erase(it);
|
||||
saveAreas();
|
||||
} else {
|
||||
bool lazyArea = queuesEmpty;
|
||||
{ // Update alive chunks
|
||||
|
|
|
@ -79,8 +79,9 @@ namespace world {
|
|||
/// Alive areas containing chunks
|
||||
area_map areas;
|
||||
using area_it_t = robin_hood::pair<area_id, std::shared_ptr<Area>>;
|
||||
|
||||
//TODO: far_areas: <pos, {id, size, seed}>
|
||||
/// Dead areas
|
||||
robin_hood::unordered_flat_map<area_id, Area::params> far_areas;
|
||||
void saveAreas() const;
|
||||
|
||||
bool running = true;
|
||||
std::vector<std::thread> loadWorkers;
|
||||
|
|
Loading…
Reference in New Issue