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

90 lines
2.5 KiB
C++

#include "EdittableChunk.hpp"
#include <algorithm>
#include <Tracy.hpp>
#include "../../core/data/math.hpp"
using namespace world::client;
EdittableChunk::EdittableChunk(): world::Chunk() { }
EdittableChunk::EdittableChunk(std::istream &is): world::Chunk(is) { }
EdittableChunk::~EdittableChunk() { }
std::optional<Faces> EdittableChunk::update(float deltaTime, bool animate) {
ZoneScopedN("Chunk");
for(auto it = edits.begin(); it != edits.end();) {
it->delay -= deltaTime;
if(it->delay <= 0 && animate) {
invalidate(it->idx);
it = edits.erase(it);
} else {
it++;
}
}
if(upToDate) {
return {};
} else {
upToDate = true;
return {toUpdate};
}
}
void EdittableChunk::invalidate(uint16_t idx) {
invalidate(
((!getNeighborIdx(idx, Face::Up).has_value()) & Faces::Up) |
((!getNeighborIdx(idx, Face::Down).has_value()) & Faces::Down) |
((!getNeighborIdx(idx, Face::Left).has_value()) & Faces::Left) |
((!getNeighborIdx(idx, Face::Right).has_value()) & Faces::Right) |
((!getNeighborIdx(idx, Face::Forward).has_value()) & Faces::Forward) |
((!getNeighborIdx(idx, Face::Backward).has_value()) & Faces::Backward));
}
void EdittableChunk::apply(const Edit& edit) {
const auto prev = voxels[edit.idx];
if(prev.value != edit.value.value) {
voxels[edit.idx] = edit.value;
if(edit.delay > 0) {
edits.emplace_back<Edit>({edit.idx, prev, edit.delay});
} else {
invalidate(edit.idx);
}
}
}
std::optional<chunk_voxel_idx> EdittableChunk::getNeighborIdx(chunk_voxel_idx idx, Face dir) {
switch (dir) {
case Face::Forward:
if (idx % glm::IDX_LENGTH >= glm::IDX_LENGTH - 1)
return {};
return idx + 1;
case Face::Backward:
if (idx % glm::IDX_LENGTH <= 0)
return {};
return idx - 1;
case Face::Up:
if ((idx / glm::IDX_LENGTH) % glm::IDX_LENGTH >= glm::IDX_LENGTH - 1)
return {};
return idx + glm::IDX_LENGTH;
case Face::Down:
if ((idx / glm::IDX_LENGTH) % glm::IDX_LENGTH <= 0)
return {};
return idx - glm::IDX_LENGTH;
case Face::Right:
if (idx / glm::IDX_LENGTH2 >= glm::IDX_LENGTH - 1)
return {};
return idx + glm::IDX_LENGTH2;
case Face::Left:
if (idx / glm::IDX_LENGTH2 <= 0)
return {};
return idx - glm::IDX_LENGTH2;
default:
return {};
}
}