76 lines
2.3 KiB
C++
76 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include "Generator.hpp"
|
|
#include "Voxel.hpp"
|
|
#include "../data/geometry/Faces.hpp"
|
|
#include "../data/math.hpp"
|
|
|
|
/// Chunk length
|
|
namespace world {
|
|
const auto CHUNK_LENGTH2 = CHUNK_LENGTH * CHUNK_LENGTH;
|
|
const auto CHUNK_SIZE = CHUNK_LENGTH2 * CHUNK_LENGTH;
|
|
|
|
constexpr auto RLE = true; //NOTE: only 2.7% gain after zstd
|
|
using namespace geometry;
|
|
/// World part as linear 3d voxel array
|
|
class Chunk {
|
|
public:
|
|
Chunk() {}
|
|
Chunk(const chunk_pos& pos, Generator& rnd);
|
|
Chunk(std::istream& str, bool rle = RLE);
|
|
~Chunk();
|
|
|
|
/// Update voxels
|
|
/// @return if modified neighbors to update
|
|
std::optional<Faces> update();
|
|
|
|
// Notify for render
|
|
inline void invalidate(Faces faces) {
|
|
upToDate = false;
|
|
toUpdate = toUpdate | faces;
|
|
modified = true;
|
|
}
|
|
// Get voxel from index
|
|
inline const Voxel& get(chunk_voxel_idx idx) const {
|
|
return voxels[idx];
|
|
}
|
|
// Get voxel from position
|
|
inline const Voxel& getAt(const chunk_voxel_pos& pos) const {
|
|
return get(glm::toIdx(pos));
|
|
}
|
|
// Set voxel from index
|
|
void set(chunk_voxel_idx idx, const Voxel& val);
|
|
// Set voxel from position
|
|
void setAt(const chunk_voxel_pos& pos, const Voxel& val) {
|
|
set(glm::toIdx(pos), val);
|
|
}
|
|
// Break voxel
|
|
std::optional<Item> replace(chunk_voxel_idx idx, const Voxel& val) {
|
|
const auto res = voxels[idx];
|
|
set(idx, val);
|
|
return {Item{res.density(), res.material()}}; //TODO: materials break table
|
|
}
|
|
// Is player modified
|
|
inline bool isModified() const { return modified; }
|
|
// Write to file.
|
|
void write(std::ostream& str, bool rle = RLE) const;
|
|
|
|
static std::optional<chunk_voxel_idx> getNeighborIdx(chunk_voxel_idx idx, Face dir);
|
|
|
|
private:
|
|
/// Chunk data
|
|
std::array<Voxel, CHUNK_SIZE> voxels;
|
|
/// Require update
|
|
bool upToDate = true;
|
|
/// Neighbors to update
|
|
Faces toUpdate = Faces::None;
|
|
/// Modified by player
|
|
bool modified = false;
|
|
};
|
|
|
|
/// Chunk full of air
|
|
static const std::shared_ptr<const Chunk> EMPTY_CHUNK = std::make_shared<Chunk>();
|
|
}
|