#include "Chunk.hpp" #include #include "core/geometry/math.hpp" #include #include using namespace world::server; Chunk::Chunk(owner edits): world::EdittableChunk(edits, Voxel(0)) { } Chunk::Chunk(owner edits, const chunk_pos &pos, const std::unique_ptr &rnd): world::EdittableChunk(edits) { rnd->generate5(glm::multiply(pos), voxels); } Chunk::Chunk(owner edits, std::istream& str): world::EdittableChunk(edits, str) { } Chunk::~Chunk() { } world::Voxel Chunk::write(std::ostream& str) const { Voxel::material_t majMat = UINT16_MAX; uint16_t majCounter = 1; size_t visibleDensity = 0; const auto doMaj = [&](const Voxel& current) { if (current.material() == majMat) { majCounter++; } else { majCounter--; } if (majCounter == 0) { majMat = current.material(); majCounter = 1; } visibleDensity += current.density() * current.is_visible(); }; if constexpr(RLE) { auto it = voxels.begin(); uint16_t counter = 1; Voxel current = *it; while(true) { ++it; doMaj(current); const auto end = (it == voxels.end()); if(end || current.value != it->value) { str.write(reinterpret_cast(&counter), sizeof(counter)); str.write(reinterpret_cast(¤t), sizeof(current)); if(end) break; current = *it; counter = 1; } else { counter++; } } } else { for(auto current: voxels) { doMaj(current); str.write(reinterpret_cast(¤t), sizeof(current)); } } if (majCounter-1 == INT16_MAX) { // Perfect majority return Voxel(voxels.front().material(), voxels.front().density(), true); } return Voxel(majMat, visibleDensity / CHUNK_SIZE); } void Chunk::set(uint16_t idx, const world::Voxel& val) { const auto same = get(idx).value == val.value; if (!isHeavy()) { if (same) return; flatten(); } modified = modified || !same; voxels[idx] = val; } void Chunk::setAt(const chunk_voxel_pos& pos, const world::Voxel& val) { set(glm::toIdx(pos), val); } std::optional Chunk::replace(chunk_voxel_idx idx, const world::Voxel& val, float) { const auto res = get(idx); set(idx, val); return {world::Item{res.density(), res.material()}}; }