1
0
Fork 0
Univerxel/src/core/world/EdittableChunk.hpp

82 lines
2.5 KiB
C++

#pragma once
#include "Chunk.hpp"
#include "../geometry/Faces.hpp"
using namespace geometry;
namespace world {
class EdittableChunk;
class ChunkEdits {
public:
ChunkEdits(EdittableChunk* ptr, bool upToDate = false):
parent(ptr), upToDate(upToDate), toUpdate(upToDate ? Faces::None : Faces::All) { }
virtual ~ChunkEdits() { }
/// Update voxels
/// @return if modified neighbors to update
virtual std::optional<Faces> update(float deltaTime, bool animate);
/// Notify for render
inline void invalidate(Faces faces) {
upToDate = false;
toUpdate = toUpdate | faces;
}
void invalidate(chunk_voxel_idx idx);
struct EditBody {
Voxel value;
float delay;
};
struct Edit: EditBody {
chunk_voxel_idx idx;
};
/// Save edits without chunk change
void add(const Edit &edit);
/// Change chunk and save edit
void apply(const Edit &edit);
static std::optional<chunk_voxel_idx> getNeighborIdx(chunk_voxel_idx idx, Face dir);
using edits_t = robin_hood::unordered_map<chunk_voxel_idx, EditBody>;
/// Get visible changes
const edits_t &getEdits() const { return edits; }
protected:
/// Animated changes
edits_t edits;
/// Data ptr
EdittableChunk *const parent;
/// Require update
bool upToDate;
/// Neighbors to update
Faces toUpdate;
};
class EdittableChunk: public world::Chunk {
public:
virtual ~EdittableChunk();
ChunkEdits* setEdits() { assert(edits); return edits.get(); }
const ChunkEdits& getEdits() const { assert(edits); return *edits.get(); }
/// Direct set without update of voxel at index
void set(chunk_voxel_idx idx, const Voxel &voxel);
/// Direct set without update of voxel at position
void setAt(const chunk_voxel_pos &pos, const Voxel& voxel);
/// Convert light to heavy
/// Faster to edit
void flatten();
/// Convert heavy to light
/// Uses less memory
void shrink();
protected:
EdittableChunk(owner<ChunkEdits*>, std::istream& str);
EdittableChunk(owner<ChunkEdits*>, Voxel);
/// NOTE: voxels must be allocated by child constructor
EdittableChunk(owner<ChunkEdits*>);
const std::unique_ptr<ChunkEdits> edits;
};
}