2021-04-03 12:39:37 -07:00
|
|
|
#ifndef VOXEL_DATA_BLOCK_H
|
|
|
|
#define VOXEL_DATA_BLOCK_H
|
|
|
|
|
2021-09-25 20:14:50 -07:00
|
|
|
#include "../storage/voxel_buffer_internal.h"
|
2022-04-09 07:00:34 -07:00
|
|
|
#include "../util/log.h"
|
2022-01-31 13:29:08 -08:00
|
|
|
#include "../util/ref_count.h"
|
2021-12-13 13:38:10 -08:00
|
|
|
#include <memory>
|
2021-04-03 12:39:37 -07:00
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
namespace zylann::voxel {
|
|
|
|
|
2021-04-03 12:39:37 -07:00
|
|
|
// Stores loaded voxel data for a chunk of the volume. Mesh and colliders are stored separately.
|
|
|
|
class VoxelDataBlock {
|
|
|
|
public:
|
|
|
|
const Vector3i position;
|
|
|
|
const unsigned int lod_index = 0;
|
2022-01-31 13:29:08 -08:00
|
|
|
RefCount viewers;
|
2021-04-03 12:39:37 -07:00
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
static VoxelDataBlock *create(
|
|
|
|
Vector3i bpos, std::shared_ptr<VoxelBufferInternal> &buffer, unsigned int size, unsigned int p_lod_index) {
|
2021-09-25 20:14:50 -07:00
|
|
|
ERR_FAIL_COND_V(buffer == nullptr, nullptr);
|
2022-02-12 15:37:02 -08:00
|
|
|
ERR_FAIL_COND_V(buffer->get_size() != Vector3i(size, size, size), nullptr);
|
2021-04-03 12:39:37 -07:00
|
|
|
return memnew(VoxelDataBlock(bpos, buffer, p_lod_index));
|
|
|
|
}
|
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
VoxelBufferInternal &get_voxels() {
|
2021-08-15 09:27:55 -07:00
|
|
|
#ifdef DEBUG_ENABLED
|
2021-09-25 20:14:50 -07:00
|
|
|
CRASH_COND(_voxels == nullptr);
|
|
|
|
#endif
|
|
|
|
return *_voxels;
|
|
|
|
}
|
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
const VoxelBufferInternal &get_voxels_const() const {
|
2021-09-25 20:14:50 -07:00
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
|
CRASH_COND(_voxels == nullptr);
|
|
|
|
#endif
|
|
|
|
return *_voxels;
|
|
|
|
}
|
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
std::shared_ptr<VoxelBufferInternal> get_voxels_shared() const {
|
2021-09-25 20:14:50 -07:00
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
|
CRASH_COND(_voxels == nullptr);
|
2021-08-15 09:27:55 -07:00
|
|
|
#endif
|
|
|
|
return _voxels;
|
|
|
|
}
|
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
void set_voxels(std::shared_ptr<VoxelBufferInternal> &buffer) {
|
2021-09-25 20:14:50 -07:00
|
|
|
ERR_FAIL_COND(buffer == nullptr);
|
2021-08-15 09:27:55 -07:00
|
|
|
_voxels = buffer;
|
|
|
|
}
|
|
|
|
|
2022-04-10 18:10:44 -07:00
|
|
|
void set_modified(bool modified);
|
2021-04-03 12:39:37 -07:00
|
|
|
|
2021-09-16 12:46:55 -07:00
|
|
|
inline bool is_modified() const {
|
|
|
|
return _modified;
|
|
|
|
}
|
2021-04-03 12:39:37 -07:00
|
|
|
|
|
|
|
void set_needs_lodding(bool need_lodding) {
|
|
|
|
_needs_lodding = need_lodding;
|
|
|
|
}
|
|
|
|
|
2021-09-16 12:46:55 -07:00
|
|
|
inline bool get_needs_lodding() const {
|
|
|
|
return _needs_lodding;
|
|
|
|
}
|
|
|
|
|
2022-01-31 13:23:39 -08:00
|
|
|
inline void set_edited(bool edited) {
|
|
|
|
_edited = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool is_edited() const {
|
|
|
|
return _edited;
|
|
|
|
}
|
|
|
|
|
2021-04-03 12:39:37 -07:00
|
|
|
private:
|
2022-01-08 15:04:49 -08:00
|
|
|
VoxelDataBlock(Vector3i bpos, std::shared_ptr<VoxelBufferInternal> &buffer, unsigned int p_lod_index) :
|
2021-09-05 15:55:57 -07:00
|
|
|
position(bpos), lod_index(p_lod_index), _voxels(buffer) {}
|
2021-08-15 09:27:55 -07:00
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
std::shared_ptr<VoxelBufferInternal> _voxels;
|
2021-04-03 12:39:37 -07:00
|
|
|
|
|
|
|
// The block was edited, which requires its LOD counterparts to be recomputed
|
|
|
|
bool _needs_lodding = false;
|
|
|
|
|
|
|
|
// Indicates if this block is different from the time it was loaded (should be saved)
|
|
|
|
bool _modified = false;
|
2021-09-16 12:33:45 -07:00
|
|
|
|
2022-01-31 13:23:39 -08:00
|
|
|
// Tells if the block has ever been edited.
|
|
|
|
// If `false`, the same data can be obtained by running the generator.
|
|
|
|
// Once it becomes `true`, it usually never comes back to `false` unless reverted.
|
|
|
|
bool _edited = false;
|
|
|
|
|
2022-02-12 15:37:02 -08:00
|
|
|
// TODO Optimization: design a proper way to implement client-side caching for multiplayer
|
|
|
|
//
|
|
|
|
// Represents how many times the block was edited.
|
|
|
|
// This allows to implement client-side caching in multiplayer.
|
|
|
|
//
|
|
|
|
// Note: when doing client-side caching, if the server decides to revert a block to generator output,
|
|
|
|
// resetting version to 0 might not be a good idea, because if a client had version 1, it could mismatch with
|
|
|
|
// the "new version 1" after the next edit. All clients having ever joined the server would have to be aware
|
|
|
|
// of the revert before they start getting blocks with the server,
|
|
|
|
// or need to be told which version is the "generated" one.
|
|
|
|
//uint32_t _version;
|
|
|
|
|
2021-09-16 12:33:45 -07:00
|
|
|
// Tells if it's worth requesting a more precise version of the data.
|
|
|
|
// Will be `true` if it's not worth it.
|
2022-01-04 12:09:08 -08:00
|
|
|
//bool _max_lod_hint = false;
|
2021-04-03 12:39:37 -07:00
|
|
|
};
|
|
|
|
|
2022-01-08 15:04:49 -08:00
|
|
|
} // namespace zylann::voxel
|
|
|
|
|
2021-04-03 12:39:37 -07:00
|
|
|
#endif // VOXEL_DATA_BLOCK_H
|