Namespaced VoxelBufferInternal
This commit is contained in:
parent
fad9537303
commit
38baeae2d9
@ -4,6 +4,7 @@
|
||||
#include "../util/profiling.h"
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
VoxelTool::VoxelTool() {
|
||||
_sdf_scale = VoxelBufferInternal::get_sdf_quantization_scale(VoxelBufferInternal::DEFAULT_SDF_CHANNEL_DEPTH);
|
||||
|
@ -199,7 +199,7 @@ private:
|
||||
|
||||
static void gather_indices_and_weights(Span<const WeightOutput> weight_outputs,
|
||||
const zylann::voxel::VoxelGraphRuntime::State &state, Vector3i rmin, Vector3i rmax, int ry,
|
||||
VoxelBufferInternal &out_voxel_buffer, FixedArray<uint8_t, 4> spare_indices);
|
||||
zylann::voxel::VoxelBufferInternal &out_voxel_buffer, FixedArray<uint8_t, 4> spare_indices);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -781,6 +781,7 @@ void VoxelGraphRuntime::generate_set(State &state, Span<float> in_x, Span<float>
|
||||
|
||||
Span<const uint8_t> params = read_params(operations, pc);
|
||||
|
||||
// TODO Buffers will stay bound if this error occurs!
|
||||
ERR_FAIL_COND(node_type.process_buffer_func == nullptr);
|
||||
ProcessBufferContext ctx(inputs, outputs, params, buffers, execution_map != nullptr);
|
||||
node_type.process_buffer_func(ctx);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "voxel_generator_flat.h"
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelGeneratorFlat::VoxelGeneratorFlat() {}
|
||||
|
||||
VoxelGeneratorFlat::~VoxelGeneratorFlat() {}
|
||||
|
@ -27,7 +27,7 @@ protected:
|
||||
|
||||
private:
|
||||
struct Parameters {
|
||||
VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_SDF;
|
||||
zylann::voxel::VoxelBufferInternal::ChannelId channel = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
|
||||
int voxel_type = 1;
|
||||
float height = 0;
|
||||
float iso_scale = 0.1;
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "../../util/fixed_array.h"
|
||||
#include "../../util/span.h"
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelGeneratorHeightmap::VoxelGeneratorHeightmap() {}
|
||||
|
||||
VoxelGeneratorHeightmap::~VoxelGeneratorHeightmap() {}
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
|
||||
protected:
|
||||
template <typename Height_F>
|
||||
Result generate(VoxelBufferInternal &out_buffer, Height_F height_func, Vector3i origin, int lod) {
|
||||
Result generate(zylann::voxel::VoxelBufferInternal &out_buffer, Height_F height_func, Vector3i origin, int lod) {
|
||||
Parameters params;
|
||||
{
|
||||
RWLockRead rlock(_parameters_lock);
|
||||
@ -35,7 +35,7 @@ protected:
|
||||
|
||||
const int channel = params.channel;
|
||||
const Vector3i bs = out_buffer.get_size();
|
||||
const bool use_sdf = channel == VoxelBufferInternal::CHANNEL_SDF;
|
||||
const bool use_sdf = channel == zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
|
||||
|
||||
if (origin.y > get_height_start() + get_height_range()) {
|
||||
// The bottom of the block is above the highest ground can go (default is air)
|
||||
@ -111,7 +111,7 @@ private:
|
||||
};
|
||||
|
||||
struct Parameters {
|
||||
VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_SDF;
|
||||
zylann::voxel::VoxelBufferInternal::ChannelId channel = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
|
||||
int matter_type = 1;
|
||||
Range range;
|
||||
float iso_scale = 0.1;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "../../util/span.h"
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <core/config/engine.h>
|
||||
#include <core/core_string_names.h>
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelGeneratorNoise::VoxelGeneratorNoise() {}
|
||||
|
||||
VoxelGeneratorNoise::~VoxelGeneratorNoise() {}
|
||||
|
@ -35,7 +35,7 @@ private:
|
||||
Ref<OpenSimplexNoise> _noise;
|
||||
|
||||
struct Parameters {
|
||||
VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_SDF;
|
||||
zylann::voxel::VoxelBufferInternal::ChannelId channel = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF;
|
||||
Ref<OpenSimplexNoise> noise;
|
||||
float height_start = 0;
|
||||
float height_range = 300;
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <core/config/engine.h>
|
||||
#include <core/core_string_names.h>
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelGeneratorNoise2D::VoxelGeneratorNoise2D() {}
|
||||
|
||||
VoxelGeneratorNoise2D::~VoxelGeneratorNoise2D() {}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <cmath>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
VoxelGeneratorWaves::VoxelGeneratorWaves() {
|
||||
_parameters.pattern_size = Vector2(30, 30);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "voxel_generator.h"
|
||||
#include "../constants/voxel_string_names.h"
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelGenerator::VoxelGenerator() {}
|
||||
|
||||
VoxelGenerator::Result VoxelGenerator::generate_block(VoxelBlockRequest &input) {
|
||||
|
@ -261,7 +261,8 @@ private:
|
||||
OctreeNodePool &_pool;
|
||||
};
|
||||
|
||||
template <typename Action_T> void foreach_node(OctreeNode *root, Action_T &a, int depth = 0) {
|
||||
template <typename Action_T>
|
||||
void foreach_node(OctreeNode *root, Action_T &a, int depth = 0) {
|
||||
a(root, depth);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (root->children[i]) {
|
||||
@ -1533,7 +1534,7 @@ Ref<Resource> VoxelMesherDMC::duplicate(bool p_subresources) const {
|
||||
}
|
||||
|
||||
int VoxelMesherDMC::get_used_channels_mask() const {
|
||||
return (1 << VoxelBufferInternal::CHANNEL_SDF);
|
||||
return (1 << zylann::voxel::VoxelBufferInternal::CHANNEL_SDF);
|
||||
}
|
||||
|
||||
Dictionary VoxelMesherDMC::get_statistics() const {
|
||||
|
@ -6,13 +6,16 @@
|
||||
#include <scene/resources/mesh.h>
|
||||
|
||||
class VoxelBuffer;
|
||||
|
||||
namespace zylann::voxel {
|
||||
class VoxelBufferInternal;
|
||||
}
|
||||
|
||||
class VoxelMesher : public Resource {
|
||||
GDCLASS(VoxelMesher, Resource)
|
||||
public:
|
||||
struct Input {
|
||||
const VoxelBufferInternal &voxels;
|
||||
const zylann::voxel::VoxelBufferInternal &voxels;
|
||||
int lod; // = 0; // Not initialized because it confused GCC
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
enum Type { TYPE_LOAD, TYPE_SAVE };
|
||||
|
||||
Type type;
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances;
|
||||
Vector3i position;
|
||||
uint8_t lod;
|
||||
@ -55,7 +55,8 @@ public:
|
||||
|
||||
struct BlockMeshInput {
|
||||
// Moore area ordered by forward XYZ iteration
|
||||
FixedArray<std::shared_ptr<VoxelBufferInternal>, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST> data_blocks;
|
||||
FixedArray<std::shared_ptr<zylann::voxel::VoxelBufferInternal>, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST>
|
||||
data_blocks;
|
||||
unsigned int data_blocks_count = 0;
|
||||
Vector3i render_block_position;
|
||||
uint8_t lod = 0;
|
||||
@ -115,8 +116,8 @@ public:
|
||||
void request_block_generate(
|
||||
uint32_t volume_id, Vector3i block_pos, int lod, std::shared_ptr<zylann::AsyncDependencyTracker> tracker);
|
||||
void request_all_stream_blocks(uint32_t volume_id);
|
||||
void request_voxel_block_save(
|
||||
uint32_t volume_id, std::shared_ptr<VoxelBufferInternal> voxels, Vector3i block_pos, int lod);
|
||||
void request_voxel_block_save(uint32_t volume_id, std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels,
|
||||
Vector3i block_pos, int lod);
|
||||
void request_instance_block_save(
|
||||
uint32_t volume_id, std::unique_ptr<VoxelInstanceBlockData> instances, Vector3i block_pos, int lod);
|
||||
void remove_volume(uint32_t volume_id);
|
||||
@ -287,7 +288,7 @@ private:
|
||||
bool is_cancelled() override;
|
||||
void apply_result() override;
|
||||
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances;
|
||||
Vector3i position; // In data blocks of the specified lod
|
||||
uint32_t volume_id;
|
||||
@ -329,7 +330,7 @@ private:
|
||||
bool is_cancelled() override;
|
||||
void apply_result() override;
|
||||
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
|
||||
Vector3i position;
|
||||
uint32_t volume_id;
|
||||
uint8_t lod;
|
||||
@ -353,7 +354,8 @@ private:
|
||||
bool is_cancelled() override;
|
||||
void apply_result() override;
|
||||
|
||||
FixedArray<std::shared_ptr<VoxelBufferInternal>, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST> blocks;
|
||||
FixedArray<std::shared_ptr<zylann::voxel::VoxelBufferInternal>, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST>
|
||||
blocks;
|
||||
// TODO Need to provide format
|
||||
//FixedArray<uint8_t, VoxelBufferInternal::MAX_CHANNELS> channel_depths;
|
||||
Vector3i position; // In mesh blocks of the specified lod
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <core/io/image.h>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
const char *VoxelBuffer::CHANNEL_ID_HINT_STRING = "Type,Sdf,Color,Indices,Weights,Data5,Data6,Data7";
|
||||
|
||||
|
@ -18,33 +18,33 @@ class VoxelBuffer : public RefCounted {
|
||||
|
||||
public:
|
||||
enum ChannelId {
|
||||
CHANNEL_TYPE = VoxelBufferInternal::CHANNEL_TYPE,
|
||||
CHANNEL_SDF = VoxelBufferInternal::CHANNEL_SDF,
|
||||
CHANNEL_COLOR = VoxelBufferInternal::CHANNEL_COLOR,
|
||||
CHANNEL_INDICES = VoxelBufferInternal::CHANNEL_INDICES,
|
||||
CHANNEL_WEIGHTS = VoxelBufferInternal::CHANNEL_WEIGHTS,
|
||||
CHANNEL_DATA5 = VoxelBufferInternal::CHANNEL_DATA5,
|
||||
CHANNEL_DATA6 = VoxelBufferInternal::CHANNEL_DATA6,
|
||||
CHANNEL_DATA7 = VoxelBufferInternal::CHANNEL_DATA7,
|
||||
MAX_CHANNELS = VoxelBufferInternal::MAX_CHANNELS,
|
||||
CHANNEL_TYPE = zylann::voxel::VoxelBufferInternal::CHANNEL_TYPE,
|
||||
CHANNEL_SDF = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF,
|
||||
CHANNEL_COLOR = zylann::voxel::VoxelBufferInternal::CHANNEL_COLOR,
|
||||
CHANNEL_INDICES = zylann::voxel::VoxelBufferInternal::CHANNEL_INDICES,
|
||||
CHANNEL_WEIGHTS = zylann::voxel::VoxelBufferInternal::CHANNEL_WEIGHTS,
|
||||
CHANNEL_DATA5 = zylann::voxel::VoxelBufferInternal::CHANNEL_DATA5,
|
||||
CHANNEL_DATA6 = zylann::voxel::VoxelBufferInternal::CHANNEL_DATA6,
|
||||
CHANNEL_DATA7 = zylann::voxel::VoxelBufferInternal::CHANNEL_DATA7,
|
||||
MAX_CHANNELS = zylann::voxel::VoxelBufferInternal::MAX_CHANNELS,
|
||||
};
|
||||
|
||||
// TODO use C++17 inline to initialize right here...
|
||||
static const char *CHANNEL_ID_HINT_STRING;
|
||||
|
||||
enum Compression {
|
||||
COMPRESSION_NONE = VoxelBufferInternal::COMPRESSION_NONE,
|
||||
COMPRESSION_UNIFORM = VoxelBufferInternal::COMPRESSION_UNIFORM,
|
||||
COMPRESSION_NONE = zylann::voxel::VoxelBufferInternal::COMPRESSION_NONE,
|
||||
COMPRESSION_UNIFORM = zylann::voxel::VoxelBufferInternal::COMPRESSION_UNIFORM,
|
||||
//COMPRESSION_RLE,
|
||||
COMPRESSION_COUNT = VoxelBufferInternal::COMPRESSION_COUNT
|
||||
COMPRESSION_COUNT = zylann::voxel::VoxelBufferInternal::COMPRESSION_COUNT
|
||||
};
|
||||
|
||||
enum Depth {
|
||||
DEPTH_8_BIT = VoxelBufferInternal::DEPTH_8_BIT,
|
||||
DEPTH_16_BIT = VoxelBufferInternal::DEPTH_16_BIT,
|
||||
DEPTH_32_BIT = VoxelBufferInternal::DEPTH_32_BIT,
|
||||
DEPTH_64_BIT = VoxelBufferInternal::DEPTH_64_BIT,
|
||||
DEPTH_COUNT = VoxelBufferInternal::DEPTH_COUNT
|
||||
DEPTH_8_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_8_BIT,
|
||||
DEPTH_16_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_16_BIT,
|
||||
DEPTH_32_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_32_BIT,
|
||||
DEPTH_64_BIT = zylann::voxel::VoxelBufferInternal::DEPTH_64_BIT,
|
||||
DEPTH_COUNT = zylann::voxel::VoxelBufferInternal::DEPTH_COUNT
|
||||
};
|
||||
|
||||
// Limit was made explicit for serialization reasons, and also because there must be a reasonable one
|
||||
@ -53,18 +53,18 @@ public:
|
||||
// Constructs a new buffer
|
||||
VoxelBuffer();
|
||||
// Reference an existing buffer
|
||||
VoxelBuffer(std::shared_ptr<VoxelBufferInternal> &other);
|
||||
VoxelBuffer(std::shared_ptr<zylann::voxel::VoxelBufferInternal> &other);
|
||||
|
||||
~VoxelBuffer();
|
||||
|
||||
inline const VoxelBufferInternal &get_buffer() const {
|
||||
inline const zylann::voxel::VoxelBufferInternal &get_buffer() const {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(_buffer == nullptr);
|
||||
#endif
|
||||
return *_buffer;
|
||||
}
|
||||
|
||||
inline VoxelBufferInternal &get_buffer() {
|
||||
inline zylann::voxel::VoxelBufferInternal &get_buffer() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(_buffer == nullptr);
|
||||
#endif
|
||||
@ -73,16 +73,28 @@ public:
|
||||
|
||||
//inline std::shared_ptr<VoxelBufferInternal> get_buffer_shared() { return _buffer; }
|
||||
|
||||
Vector3i get_size() const { return _buffer->get_size(); }
|
||||
Vector3i get_size() const {
|
||||
return _buffer->get_size();
|
||||
}
|
||||
// TODO Deprecate
|
||||
int get_size_x() const { return _buffer->get_size().x; }
|
||||
int get_size_y() const { return _buffer->get_size().x; }
|
||||
int get_size_z() const { return _buffer->get_size().x; }
|
||||
int get_size_x() const {
|
||||
return _buffer->get_size().x;
|
||||
}
|
||||
int get_size_y() const {
|
||||
return _buffer->get_size().x;
|
||||
}
|
||||
int get_size_z() const {
|
||||
return _buffer->get_size().x;
|
||||
}
|
||||
|
||||
void create(int x, int y, int z) { _buffer->create(x, y, z); }
|
||||
void create(int x, int y, int z) {
|
||||
_buffer->create(x, y, z);
|
||||
}
|
||||
void clear();
|
||||
|
||||
uint64_t get_voxel(int x, int y, int z, unsigned int channel) const { return _buffer->get_voxel(x, y, z, channel); }
|
||||
uint64_t get_voxel(int x, int y, int z, unsigned int channel) const {
|
||||
return _buffer->get_voxel(x, y, z, channel);
|
||||
}
|
||||
void set_voxel(uint64_t value, int x, int y, int z, unsigned int channel) {
|
||||
_buffer->set_voxel(value, x, y, z, channel);
|
||||
}
|
||||
@ -124,11 +136,17 @@ public:
|
||||
|
||||
// Metadata
|
||||
|
||||
Variant get_block_metadata() const { return _buffer->get_block_metadata(); }
|
||||
Variant get_block_metadata() const {
|
||||
return _buffer->get_block_metadata();
|
||||
}
|
||||
void set_block_metadata(Variant meta);
|
||||
|
||||
Variant get_voxel_metadata(Vector3i pos) const { return _buffer->get_voxel_metadata(pos); }
|
||||
void set_voxel_metadata(Vector3i pos, Variant meta) { _buffer->set_voxel_metadata(pos, meta); }
|
||||
Variant get_voxel_metadata(Vector3i pos) const {
|
||||
return _buffer->get_voxel_metadata(pos);
|
||||
}
|
||||
void set_voxel_metadata(Vector3i pos, Variant meta) {
|
||||
_buffer->set_voxel_metadata(pos, meta);
|
||||
}
|
||||
void for_each_voxel_metadata(const Callable &callback) const;
|
||||
void for_each_voxel_metadata_in_area(const Callable &callback, Vector3i min_pos, Vector3i max_pos);
|
||||
void copy_voxel_metadata_in_area(
|
||||
@ -145,7 +163,7 @@ private:
|
||||
static void _bind_methods();
|
||||
|
||||
// Not sure yet if we'll really need shared_ptr or just no pointer
|
||||
std::shared_ptr<VoxelBufferInternal> _buffer;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> _buffer;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelBuffer::ChannelId)
|
||||
|
@ -13,10 +13,7 @@
|
||||
#include <core/math/math_funcs.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
namespace {
|
||||
namespace zylann::voxel {
|
||||
|
||||
inline uint8_t *allocate_channel_data(size_t size) {
|
||||
#ifdef VOXEL_BUFFER_USE_MEMORY_POOL
|
||||
@ -41,11 +38,6 @@ uint64_t g_depth_max_values[] = {
|
||||
0xffffffffffffffff // 64
|
||||
};
|
||||
|
||||
inline uint32_t get_depth_bit_count(VoxelBufferInternal::Depth d) {
|
||||
CRASH_COND(d < 0 || d >= VoxelBufferInternal::DEPTH_COUNT);
|
||||
return VoxelBufferInternal::get_depth_byte_count(d) << 3;
|
||||
}
|
||||
|
||||
inline uint64_t get_max_value_for_depth(VoxelBufferInternal::Depth d) {
|
||||
CRASH_COND(d < 0 || d >= VoxelBufferInternal::DEPTH_COUNT);
|
||||
return g_depth_max_values[d];
|
||||
@ -113,21 +105,19 @@ inline real_t raw_voxel_to_real(uint64_t value, VoxelBufferInternal::Depth depth
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
VoxelBufferInternal::VoxelBufferInternal() {
|
||||
// Minecraft uses way more than 255 block types and there is room for eventual metadata such as rotation
|
||||
_channels[CHANNEL_TYPE].depth = VoxelBufferInternal::DEFAULT_TYPE_CHANNEL_DEPTH;
|
||||
_channels[CHANNEL_TYPE].depth = DEFAULT_TYPE_CHANNEL_DEPTH;
|
||||
_channels[CHANNEL_TYPE].defval = 0;
|
||||
|
||||
// 16-bit is better on average to handle large worlds
|
||||
_channels[CHANNEL_SDF].depth = VoxelBufferInternal::DEFAULT_SDF_CHANNEL_DEPTH;
|
||||
_channels[CHANNEL_SDF].depth = DEFAULT_SDF_CHANNEL_DEPTH;
|
||||
_channels[CHANNEL_SDF].defval = 0xffff;
|
||||
|
||||
_channels[CHANNEL_INDICES].depth = VoxelBufferInternal::DEPTH_16_BIT;
|
||||
_channels[CHANNEL_INDICES].depth = DEPTH_16_BIT;
|
||||
_channels[CHANNEL_INDICES].defval = encode_indices_to_packed_u16(0, 1, 2, 3);
|
||||
|
||||
_channels[CHANNEL_WEIGHTS].depth = VoxelBufferInternal::DEPTH_16_BIT;
|
||||
_channels[CHANNEL_WEIGHTS].depth = DEPTH_16_BIT;
|
||||
_channels[CHANNEL_WEIGHTS].defval = encode_weights_to_packed_u16(15, 0, 0, 0);
|
||||
}
|
||||
|
||||
@ -422,7 +412,8 @@ void VoxelBufferInternal::fill_f(real_t value, unsigned int channel) {
|
||||
fill(real_to_raw_voxel(value, _channels[channel].depth), channel);
|
||||
}
|
||||
|
||||
template <typename T> inline bool is_uniform_b(const uint8_t *data, size_t item_count) {
|
||||
template <typename T>
|
||||
inline bool is_uniform_b(const uint8_t *data, size_t item_count) {
|
||||
return is_uniform<T>(reinterpret_cast<const T *>(data), item_count);
|
||||
}
|
||||
|
||||
@ -441,13 +432,13 @@ bool VoxelBufferInternal::is_uniform(const Channel &channel) {
|
||||
// Channel isn't optimized, so must look at each voxel
|
||||
switch (channel.depth) {
|
||||
case DEPTH_8_BIT:
|
||||
return ::is_uniform_b<uint8_t>(channel.data, channel.size_in_bytes);
|
||||
return is_uniform_b<uint8_t>(channel.data, channel.size_in_bytes);
|
||||
case DEPTH_16_BIT:
|
||||
return ::is_uniform_b<uint16_t>(channel.data, channel.size_in_bytes / 2);
|
||||
return is_uniform_b<uint16_t>(channel.data, channel.size_in_bytes / 2);
|
||||
case DEPTH_32_BIT:
|
||||
return ::is_uniform_b<uint32_t>(channel.data, channel.size_in_bytes / 4);
|
||||
return is_uniform_b<uint32_t>(channel.data, channel.size_in_bytes / 4);
|
||||
case DEPTH_64_BIT:
|
||||
return ::is_uniform_b<uint64_t>(channel.data, channel.size_in_bytes / 8);
|
||||
return is_uniform_b<uint64_t>(channel.data, channel.size_in_bytes / 8);
|
||||
default:
|
||||
CRASH_NOW();
|
||||
break;
|
||||
@ -644,7 +635,7 @@ bool VoxelBufferInternal::create_channel(int i, uint64_t defval) {
|
||||
size_t VoxelBufferInternal::get_size_in_bytes_for_volume(Vector3i size, Depth depth) {
|
||||
// Calculate appropriate size based on bit depth
|
||||
const size_t volume = size.x * size.y * size.z;
|
||||
const size_t bits = volume * ::get_depth_bit_count(depth);
|
||||
const size_t bits = volume * get_depth_bit_count(depth);
|
||||
const size_t size_in_bytes = (bits >> 3);
|
||||
return size_in_bytes;
|
||||
}
|
||||
@ -779,10 +770,6 @@ VoxelBufferInternal::Depth VoxelBufferInternal::get_channel_depth(unsigned int c
|
||||
return _channels[channel_index].depth;
|
||||
}
|
||||
|
||||
uint32_t VoxelBufferInternal::get_depth_bit_count(Depth d) {
|
||||
return ::get_depth_bit_count(d);
|
||||
}
|
||||
|
||||
float VoxelBufferInternal::get_sdf_quantization_scale(Depth d) {
|
||||
switch (d) {
|
||||
// Normalized
|
||||
@ -926,3 +913,5 @@ Ref<Image> VoxelBufferInternal::debug_print_sdf_to_image_top_down() {
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
@ -15,6 +15,12 @@
|
||||
class VoxelTool;
|
||||
class Image;
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
// TODO This class is still suffixed "Internal" to avoid conflict with the registered Godot class.
|
||||
// Even though the other class is not namespaced yet, it is unsure if it will remain that way after the future port
|
||||
// to GDExtension
|
||||
|
||||
// Dense voxels data storage.
|
||||
// Organized in channels of configurable bit depth.
|
||||
// Values can be interpreted either as unsigned integers or normalized floats.
|
||||
@ -42,13 +48,24 @@ public:
|
||||
COMPRESSION_COUNT
|
||||
};
|
||||
|
||||
enum Depth { DEPTH_8_BIT, DEPTH_16_BIT, DEPTH_32_BIT, DEPTH_64_BIT, DEPTH_COUNT };
|
||||
enum Depth { //
|
||||
DEPTH_8_BIT,
|
||||
DEPTH_16_BIT,
|
||||
DEPTH_32_BIT,
|
||||
DEPTH_64_BIT,
|
||||
DEPTH_COUNT
|
||||
};
|
||||
|
||||
static inline uint32_t get_depth_byte_count(VoxelBufferInternal::Depth d) {
|
||||
CRASH_COND(d < 0 || d >= VoxelBufferInternal::DEPTH_COUNT);
|
||||
return 1 << d;
|
||||
}
|
||||
|
||||
static inline uint32_t get_depth_bit_count(Depth d) {
|
||||
//CRASH_COND(d < 0 || d >= VoxelBufferInternal::DEPTH_COUNT);
|
||||
return get_depth_byte_count(d) << 3;
|
||||
}
|
||||
|
||||
static inline Depth get_depth_from_size(size_t size) {
|
||||
switch (size) {
|
||||
case 1:
|
||||
@ -199,7 +216,8 @@ public:
|
||||
// `action_func` receives a voxel value from the channel, and returns a modified value.
|
||||
// if the returned value is different, it will be applied to the buffer.
|
||||
// Can be used to blend voxels together.
|
||||
template <typename F> inline void read_write_action(Box3i box, unsigned int channel_index, F action_func) {
|
||||
template <typename F>
|
||||
inline void read_write_action(Box3i box, unsigned int channel_index, F action_func) {
|
||||
ERR_FAIL_INDEX(channel_index, MAX_CHANNELS);
|
||||
|
||||
box.clip(Box3i(Vector3i(), _size));
|
||||
@ -228,7 +246,8 @@ public:
|
||||
return y + _size.y * (x + _size.x * z); // ZXY index
|
||||
}
|
||||
|
||||
template <typename F> inline void for_each_index_and_pos(const Box3i &box, F f) {
|
||||
template <typename F>
|
||||
inline void for_each_index_and_pos(const Box3i &box, F f) {
|
||||
const Vector3i min_pos = box.pos;
|
||||
const Vector3i max_pos = box.pos + box.size;
|
||||
Vector3i pos;
|
||||
@ -284,7 +303,8 @@ public:
|
||||
compress_if_uniform(channel1);
|
||||
}
|
||||
|
||||
template <typename F> void write_box(const Box3i &box, unsigned int channel_index, F action_func, Vector3i offset) {
|
||||
template <typename F>
|
||||
void write_box(const Box3i &box, unsigned int channel_index, F action_func, Vector3i offset) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_FAIL_INDEX(channel_index, MAX_CHANNELS);
|
||||
#endif
|
||||
@ -384,7 +404,6 @@ public:
|
||||
|
||||
void set_channel_depth(unsigned int channel_index, Depth new_depth);
|
||||
Depth get_channel_depth(unsigned int channel_index) const;
|
||||
static uint32_t get_depth_bit_count(Depth d);
|
||||
|
||||
// When using lower than 32-bit resolution for terrain signed distance fields,
|
||||
// it should be scaled to better fit the range of represented values since the storage is normalized to -1..1.
|
||||
@ -400,7 +419,8 @@ public:
|
||||
Variant get_voxel_metadata(Vector3i pos) const;
|
||||
void set_voxel_metadata(Vector3i pos, Variant meta);
|
||||
|
||||
template <typename F> void for_each_voxel_metadata_in_area(Box3i box, F callback) const {
|
||||
template <typename F>
|
||||
void for_each_voxel_metadata_in_area(Box3i box, F callback) const {
|
||||
const Map<Vector3i, Variant>::Element *elem = _voxel_metadata.front();
|
||||
while (elem != nullptr) {
|
||||
if (box.contains(elem->key())) {
|
||||
@ -461,8 +481,6 @@ private:
|
||||
RWLock _rw_lock;
|
||||
};
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
inline void debug_check_texture_indices_packed_u16(const VoxelBufferInternal &voxels) {
|
||||
for (int z = 0; z < voxels.get_size().z; ++z) {
|
||||
for (int x = 0; x < voxels.get_size().x; ++x) {
|
||||
|
@ -13,36 +13,36 @@ public:
|
||||
const unsigned int lod_index = 0;
|
||||
VoxelRefCount viewers;
|
||||
|
||||
static VoxelDataBlock *create(
|
||||
Vector3i bpos, std::shared_ptr<VoxelBufferInternal> &buffer, unsigned int size, unsigned int p_lod_index) {
|
||||
static VoxelDataBlock *create(Vector3i bpos, std::shared_ptr<zylann::voxel::VoxelBufferInternal> &buffer,
|
||||
unsigned int size, unsigned int p_lod_index) {
|
||||
const int bs = size;
|
||||
ERR_FAIL_COND_V(buffer == nullptr, nullptr);
|
||||
ERR_FAIL_COND_V(buffer->get_size() != Vector3i(bs, bs, bs), nullptr);
|
||||
return memnew(VoxelDataBlock(bpos, buffer, p_lod_index));
|
||||
}
|
||||
|
||||
VoxelBufferInternal &get_voxels() {
|
||||
zylann::voxel::VoxelBufferInternal &get_voxels() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(_voxels == nullptr);
|
||||
#endif
|
||||
return *_voxels;
|
||||
}
|
||||
|
||||
const VoxelBufferInternal &get_voxels_const() const {
|
||||
const zylann::voxel::VoxelBufferInternal &get_voxels_const() const {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(_voxels == nullptr);
|
||||
#endif
|
||||
return *_voxels;
|
||||
}
|
||||
|
||||
std::shared_ptr<VoxelBufferInternal> get_voxels_shared() const {
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> get_voxels_shared() const {
|
||||
#ifdef DEBUG_ENABLED
|
||||
CRASH_COND(_voxels == nullptr);
|
||||
#endif
|
||||
return _voxels;
|
||||
}
|
||||
|
||||
void set_voxels(std::shared_ptr<VoxelBufferInternal> &buffer) {
|
||||
void set_voxels(std::shared_ptr<zylann::voxel::VoxelBufferInternal> &buffer) {
|
||||
ERR_FAIL_COND(buffer == nullptr);
|
||||
_voxels = buffer;
|
||||
}
|
||||
@ -69,10 +69,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
VoxelDataBlock(Vector3i bpos, std::shared_ptr<VoxelBufferInternal> &buffer, unsigned int p_lod_index) :
|
||||
VoxelDataBlock(
|
||||
Vector3i bpos, std::shared_ptr<zylann::voxel::VoxelBufferInternal> &buffer, unsigned int p_lod_index) :
|
||||
position(bpos), lod_index(p_lod_index), _voxels(buffer) {}
|
||||
|
||||
std::shared_ptr<VoxelBufferInternal> _voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> _voxels;
|
||||
|
||||
// The block was edited, which requires its LOD counterparts to be recomputed
|
||||
bool _needs_lodding = false;
|
||||
|
@ -23,7 +23,8 @@ public:
|
||||
}
|
||||
|
||||
// D action(Vector3i pos, D value)
|
||||
template <typename F> void write_box(Box3i voxel_box, unsigned int channel, F action) {
|
||||
template <typename F>
|
||||
void write_box(Box3i voxel_box, unsigned int channel, F action) {
|
||||
_box_loop(voxel_box, [action, channel](VoxelBufferInternal &voxels, Box3i local_box, Vector3i voxel_offset) {
|
||||
voxels.write_box(local_box, channel, action, voxel_offset);
|
||||
});
|
||||
@ -44,7 +45,8 @@ private:
|
||||
return _block_size;
|
||||
}
|
||||
|
||||
template <typename Block_F> inline void _box_loop(Box3i voxel_box, Block_F block_action) {
|
||||
template <typename Block_F>
|
||||
inline void _box_loop(Box3i voxel_box, Block_F block_action) {
|
||||
Vector3i block_rpos;
|
||||
const Vector3i area_origin_in_voxels = _offset_in_blocks * _block_size;
|
||||
unsigned int index = 0;
|
||||
@ -85,7 +87,7 @@ private:
|
||||
pos.z < _size_in_blocks.z;
|
||||
}
|
||||
|
||||
inline void set_block(Vector3i position, std::shared_ptr<VoxelBufferInternal> block) {
|
||||
inline void set_block(Vector3i position, std::shared_ptr<zylann::voxel::VoxelBufferInternal> block) {
|
||||
ERR_FAIL_COND(!is_valid_position(position));
|
||||
position -= _offset_in_blocks;
|
||||
const unsigned int index = Vector3iUtil::get_zxy_index(position, _size_in_blocks);
|
||||
@ -93,7 +95,7 @@ private:
|
||||
_blocks[index] = block;
|
||||
}
|
||||
|
||||
inline VoxelBufferInternal *get_block(Vector3i position) {
|
||||
inline zylann::voxel::VoxelBufferInternal *get_block(Vector3i position) {
|
||||
ERR_FAIL_COND_V(!is_valid_position(position), nullptr);
|
||||
position -= _offset_in_blocks;
|
||||
const unsigned int index = Vector3iUtil::get_zxy_index(position, _size_in_blocks);
|
||||
@ -102,7 +104,7 @@ private:
|
||||
}
|
||||
|
||||
// Flat grid indexed in ZXY order
|
||||
std::vector<std::shared_ptr<VoxelBufferInternal>> _blocks;
|
||||
std::vector<std::shared_ptr<zylann::voxel::VoxelBufferInternal>> _blocks;
|
||||
// Size of the grid in blocks
|
||||
Vector3i _size_in_blocks;
|
||||
// Block coordinates offset. This is used for when we cache a sub-region of a map, we need to keep the origin
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <limits>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
VoxelDataMap::VoxelDataMap() {
|
||||
// TODO Make it configurable in editor (with all necessary notifications and updatings!)
|
||||
|
@ -53,32 +53,34 @@ public:
|
||||
int get_voxel(Vector3i pos, unsigned int c = 0) const;
|
||||
void set_voxel(int value, Vector3i pos, unsigned int c = 0);
|
||||
|
||||
float get_voxel_f(Vector3i pos, unsigned int c = VoxelBufferInternal::CHANNEL_SDF) const;
|
||||
void set_voxel_f(real_t value, Vector3i pos, unsigned int c = VoxelBufferInternal::CHANNEL_SDF);
|
||||
float get_voxel_f(Vector3i pos, unsigned int c = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF) const;
|
||||
void set_voxel_f(real_t value, Vector3i pos, unsigned int c = zylann::voxel::VoxelBufferInternal::CHANNEL_SDF);
|
||||
|
||||
void set_default_voxel(int value, unsigned int channel = 0);
|
||||
int get_default_voxel(unsigned int channel = 0);
|
||||
|
||||
inline void copy(Vector3i min_pos, VoxelBufferInternal &dst_buffer, unsigned int channels_mask) const {
|
||||
inline void copy(
|
||||
Vector3i min_pos, zylann::voxel::VoxelBufferInternal &dst_buffer, unsigned int channels_mask) const {
|
||||
copy(min_pos, dst_buffer, channels_mask, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Gets a copy of all voxels in the area starting at min_pos having the same size as dst_buffer.
|
||||
void copy(Vector3i min_pos, VoxelBufferInternal &dst_buffer, unsigned int channels_mask, void *,
|
||||
void (*gen_func)(void *, VoxelBufferInternal &, Vector3i)) const;
|
||||
void copy(Vector3i min_pos, zylann::voxel::VoxelBufferInternal &dst_buffer, unsigned int channels_mask, void *,
|
||||
void (*gen_func)(void *, zylann::voxel::VoxelBufferInternal &, Vector3i)) const;
|
||||
|
||||
void paste(Vector3i min_pos, VoxelBufferInternal &src_buffer, unsigned int channels_mask, bool use_mask,
|
||||
uint64_t mask_value, bool create_new_blocks);
|
||||
void paste(Vector3i min_pos, zylann::voxel::VoxelBufferInternal &src_buffer, unsigned int channels_mask,
|
||||
bool use_mask, uint64_t mask_value, bool create_new_blocks);
|
||||
|
||||
// Moves the given buffer into a block of the map. The buffer is referenced, no copy is made.
|
||||
VoxelDataBlock *set_block_buffer(
|
||||
Vector3i bpos, std::shared_ptr<VoxelBufferInternal> &buffer, bool overwrite = true);
|
||||
Vector3i bpos, std::shared_ptr<zylann::voxel::VoxelBufferInternal> &buffer, bool overwrite = true);
|
||||
|
||||
struct NoAction {
|
||||
inline void operator()(VoxelDataBlock *block) {}
|
||||
};
|
||||
|
||||
template <typename Action_T> void remove_block(Vector3i bpos, Action_T pre_delete) {
|
||||
template <typename Action_T>
|
||||
void remove_block(Vector3i bpos, Action_T pre_delete) {
|
||||
auto it = _blocks_map.find(bpos);
|
||||
if (it != _blocks_map.end()) {
|
||||
const unsigned int i = it->second;
|
||||
@ -104,14 +106,16 @@ public:
|
||||
int get_block_count() const;
|
||||
|
||||
// TODO Rename for_each_block
|
||||
template <typename Op_T> inline void for_all_blocks(Op_T op) {
|
||||
template <typename Op_T>
|
||||
inline void for_all_blocks(Op_T op) {
|
||||
for (auto it = _blocks.begin(); it != _blocks.end(); ++it) {
|
||||
op(*it);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Rename for_each_block
|
||||
template <typename Op_T> inline void for_all_blocks(Op_T op) const {
|
||||
template <typename Op_T>
|
||||
inline void for_all_blocks(Op_T op) const {
|
||||
for (auto it = _blocks.begin(); it != _blocks.end(); ++it) {
|
||||
op(*it);
|
||||
}
|
||||
@ -119,7 +123,8 @@ public:
|
||||
|
||||
bool is_area_fully_loaded(const Box3i voxels_box) const;
|
||||
|
||||
template <typename F> inline void write_box(const Box3i &voxel_box, unsigned int channel, F action) {
|
||||
template <typename F>
|
||||
inline void write_box(const Box3i &voxel_box, unsigned int channel, F action) {
|
||||
write_box(voxel_box, channel, action, [](const VoxelBufferInternal &, const Vector3i &) {});
|
||||
}
|
||||
|
||||
@ -179,7 +184,7 @@ private:
|
||||
|
||||
private:
|
||||
// Voxel values that will be returned if access is out of map bounds
|
||||
FixedArray<uint64_t, VoxelBufferInternal::MAX_CHANNELS> _default_voxel;
|
||||
FixedArray<uint64_t, zylann::voxel::VoxelBufferInternal::MAX_CHANNELS> _default_voxel;
|
||||
|
||||
// Blocks stored with a spatial hash in all 3D directions.
|
||||
// Before I used Godot's HashMap with RELATIONSHIP = 2 because that delivers better performance compared to
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
namespace {
|
||||
const uint8_t FORMAT_VERSION = 3;
|
||||
@ -21,7 +22,7 @@ const char *META_FILE_NAME = "meta.vxrm";
|
||||
|
||||
} // namespace
|
||||
|
||||
thread_local zylann::voxel::BlockSerializer VoxelStreamRegionFiles::_block_serializer;
|
||||
thread_local BlockSerializer VoxelStreamRegionFiles::_block_serializer;
|
||||
|
||||
// Sorts a sequence without modifying it, returning a sorted list of pointers
|
||||
template <typename T, typename Comparer_T>
|
||||
@ -425,7 +426,7 @@ String VoxelStreamRegionFiles::get_region_file_path(const Vector3i ®ion_pos,
|
||||
a[1] = region_pos.x;
|
||||
a[2] = region_pos.y;
|
||||
a[3] = region_pos.z;
|
||||
a[4] = zylann::voxel::RegionFormat::FILE_EXTENSION;
|
||||
a[4] = RegionFormat::FILE_EXTENSION;
|
||||
return _directory_path.plus_file(String("regions/lod{0}/r.{1}.{2}.{3}.{4}").format(a));
|
||||
}
|
||||
|
||||
@ -463,7 +464,7 @@ VoxelStreamRegionFiles::CachedRegion *VoxelStreamRegionFiles::open_region(
|
||||
|
||||
// Configure format because we might have to create the file, and some old file versions don't embed format
|
||||
{
|
||||
zylann::voxel::RegionFormat format;
|
||||
RegionFormat format;
|
||||
format.block_size_po2 = _meta.block_size_po2;
|
||||
format.channel_depths = _meta.channel_depths;
|
||||
// TODO Palette support
|
||||
@ -497,7 +498,7 @@ VoxelStreamRegionFiles::CachedRegion *VoxelStreamRegionFiles::open_region(
|
||||
|
||||
// Make sure it has correct format
|
||||
{
|
||||
const zylann::voxel::RegionFormat &format = cached_region->region.get_format();
|
||||
const RegionFormat &format = cached_region->region.get_format();
|
||||
if (format.block_size_po2 != _meta.block_size_po2 //
|
||||
|| format.channel_depths != _meta.channel_depths //
|
||||
|| format.region_size != Vector3iUtil::create(1 << _meta.region_size_po2) //
|
||||
@ -618,7 +619,7 @@ void VoxelStreamRegionFiles::_convert_files(Meta new_meta) {
|
||||
for (int lod = 0; lod < old_meta.lod_count; ++lod) {
|
||||
const String lod_folder =
|
||||
old_stream->_directory_path.plus_file("regions").plus_file("lod") + String::num_int64(lod);
|
||||
const String ext = String(".") + zylann::voxel::RegionFormat::FILE_EXTENSION;
|
||||
const String ext = String(".") + RegionFormat::FILE_EXTENSION;
|
||||
|
||||
DirAccessRef da = DirAccess::open(lod_folder);
|
||||
if (!da) {
|
||||
|
@ -24,8 +24,8 @@ public:
|
||||
VoxelStreamRegionFiles();
|
||||
~VoxelStreamRegionFiles();
|
||||
|
||||
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
|
||||
void emerge_blocks(Span<VoxelBlockRequest> p_blocks, Vector<Result> &out_results) override;
|
||||
void immerge_blocks(Span<VoxelBlockRequest> p_blocks) override;
|
||||
@ -64,8 +64,8 @@ private:
|
||||
EMERGE_FAILED
|
||||
};
|
||||
|
||||
EmergeResult _emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
|
||||
void _immerge_block(VoxelBufferInternal &voxel_buffer, Vector3i origin_in_voxels, int lod);
|
||||
EmergeResult _emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
|
||||
void _immerge_block(zylann::voxel::VoxelBufferInternal &voxel_buffer, Vector3i origin_in_voxels, int lod);
|
||||
|
||||
VoxelFileResult save_meta();
|
||||
VoxelFileResult load_meta();
|
||||
@ -83,7 +83,8 @@ private:
|
||||
uint8_t lod_count = 0;
|
||||
uint8_t block_size_po2 = 0; // How many voxels in a cubic block
|
||||
uint8_t region_size_po2 = 0; // How many blocks in one cubic region
|
||||
FixedArray<VoxelBufferInternal::Depth, VoxelBufferInternal::MAX_CHANNELS> channel_depths;
|
||||
FixedArray<zylann::voxel::VoxelBufferInternal::Depth, zylann::voxel::VoxelBufferInternal::MAX_CHANNELS>
|
||||
channel_depths;
|
||||
uint32_t sector_size = 0; // Blocks are stored at offsets multiple of that size
|
||||
};
|
||||
|
||||
|
@ -572,7 +572,10 @@ void VoxelStreamSQLiteInternal::save_meta(Meta meta) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
thread_local zylann::voxel::BlockSerializer VoxelStreamSQLite::_voxel_block_serializer;
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
thread_local BlockSerializer VoxelStreamSQLite::_voxel_block_serializer;
|
||||
thread_local std::vector<uint8_t> VoxelStreamSQLite::_temp_block_data;
|
||||
thread_local std::vector<uint8_t> VoxelStreamSQLite::_temp_compressed_block_data;
|
||||
|
||||
@ -770,8 +773,7 @@ void VoxelStreamSQLite::load_instance_blocks(
|
||||
const Result res = con->load_block(loc, _temp_compressed_block_data, VoxelStreamSQLiteInternal::INSTANCES);
|
||||
|
||||
if (res == RESULT_BLOCK_FOUND) {
|
||||
if (!zylann::voxel::CompressedData::decompress(
|
||||
to_span_const(_temp_compressed_block_data), _temp_block_data)) {
|
||||
if (!CompressedData::decompress(to_span_const(_temp_compressed_block_data), _temp_block_data)) {
|
||||
ERR_PRINT("Failed to decompress instance block");
|
||||
out_results[i] = RESULT_ERROR;
|
||||
continue;
|
||||
@ -838,14 +840,14 @@ void VoxelStreamSQLite::load_all_blocks(FullLoadingResult &result) {
|
||||
result_block.lod = location.lod;
|
||||
|
||||
if (voxel_data.size() > 0) {
|
||||
std::shared_ptr<VoxelBufferInternal> voxels = zylann::gd_make_shared<VoxelBufferInternal>();
|
||||
std::shared_ptr<VoxelBufferInternal> voxels = gd_make_shared<VoxelBufferInternal>();
|
||||
ERR_FAIL_COND(!ctx->stream._voxel_block_serializer.decompress_and_deserialize(voxel_data, *voxels));
|
||||
result_block.voxels = voxels;
|
||||
}
|
||||
|
||||
if (instances_data.size() > 0) {
|
||||
std::vector<uint8_t> &temp_block_data = ctx->stream._temp_block_data;
|
||||
if (!zylann::voxel::CompressedData::decompress(instances_data, temp_block_data)) {
|
||||
if (!CompressedData::decompress(instances_data, temp_block_data)) {
|
||||
ERR_PRINT("Failed to decompress instance block");
|
||||
return;
|
||||
}
|
||||
@ -885,7 +887,7 @@ void VoxelStreamSQLite::flush_cache(VoxelStreamSQLiteInternal *con) {
|
||||
PRINT_VERBOSE(String("VoxelStreamSQLite: Flushing cache ({0} elements)")
|
||||
.format(varray(_cache.get_indicative_block_count())));
|
||||
|
||||
zylann::voxel::BlockSerializer &serializer = _voxel_block_serializer;
|
||||
BlockSerializer &serializer = _voxel_block_serializer;
|
||||
|
||||
ERR_FAIL_COND(con == nullptr);
|
||||
ERR_FAIL_COND(con->begin_transaction() == false);
|
||||
@ -909,7 +911,7 @@ void VoxelStreamSQLite::flush_cache(VoxelStreamSQLiteInternal *con) {
|
||||
const std::vector<uint8_t> empty;
|
||||
con->save_block(loc, empty, VoxelStreamSQLiteInternal::VOXELS);
|
||||
} else {
|
||||
zylann::voxel::BlockSerializer::SerializeResult res = serializer.serialize_and_compress(block.voxels);
|
||||
BlockSerializer::SerializeResult res = serializer.serialize_and_compress(block.voxels);
|
||||
ERR_FAIL_COND(!res.success);
|
||||
con->save_block(loc, res.data, VoxelStreamSQLiteInternal::VOXELS);
|
||||
}
|
||||
@ -922,8 +924,8 @@ void VoxelStreamSQLite::flush_cache(VoxelStreamSQLiteInternal *con) {
|
||||
|
||||
ERR_FAIL_COND(!serialize_instance_block_data(*block.instances, temp_data));
|
||||
|
||||
ERR_FAIL_COND(!zylann::voxel::CompressedData::compress(
|
||||
to_span_const(temp_data), temp_compressed_data, zylann::voxel::CompressedData::COMPRESSION_NONE));
|
||||
ERR_FAIL_COND(!CompressedData::compress(
|
||||
to_span_const(temp_data), temp_compressed_data, CompressedData::COMPRESSION_NONE));
|
||||
}
|
||||
con->save_block(loc, temp_compressed_data, VoxelStreamSQLiteInternal::INSTANCES);
|
||||
|
||||
|
@ -21,8 +21,8 @@ public:
|
||||
void set_database_path(String path);
|
||||
String get_database_path() const;
|
||||
|
||||
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
|
||||
void emerge_blocks(Span<VoxelBlockRequest> p_blocks, Vector<Result> &out_results) override;
|
||||
void immerge_blocks(Span<VoxelBlockRequest> p_blocks) override;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "vox_data.h"
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
Error VoxelVoxLoader::load_from_file(String fpath, Ref<VoxelBuffer> p_voxels, Ref<VoxelColorPalette> palette) {
|
||||
ERR_FAIL_COND_V(p_voxels.is_null(), ERR_INVALID_PARAMETER);
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
// TODO Rename VoxelStreamBlockRequest
|
||||
struct VoxelBlockRequest {
|
||||
VoxelBufferInternal &voxel_buffer;
|
||||
zylann::voxel::VoxelBufferInternal &voxel_buffer;
|
||||
Vector3i origin_in_voxels;
|
||||
int lod;
|
||||
};
|
||||
|
@ -8,10 +8,11 @@
|
||||
#include <vector>
|
||||
|
||||
class StreamPeer;
|
||||
class VoxelBufferInternal;
|
||||
|
||||
namespace zylann::voxel {
|
||||
|
||||
class VoxelBufferInternal;
|
||||
|
||||
class BlockSerializer {
|
||||
// Had to be named differently to not conflict with the wrapper for Godot script API
|
||||
public:
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "voxel_stream.h"
|
||||
#include <core/object/script_language.h>
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelStream::VoxelStream() {}
|
||||
|
||||
VoxelStream::~VoxelStream() {}
|
||||
|
@ -36,10 +36,10 @@ public:
|
||||
// Queries a block of voxels beginning at the given world-space voxel position and LOD.
|
||||
// If you use LOD, the result at a given coordinate must always remain the same regardless of it.
|
||||
// In other words, voxels values must solely depend on their coordinates or fixed parameters.
|
||||
virtual Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
|
||||
virtual Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod);
|
||||
|
||||
// TODO Deprecate
|
||||
virtual void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod);
|
||||
virtual void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod);
|
||||
|
||||
// TODO Rename load_voxel_blocks
|
||||
// Note: Don't modify the order of `p_blocks`.
|
||||
@ -59,7 +59,7 @@ public:
|
||||
|
||||
struct FullLoadingResult {
|
||||
struct Block {
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances_data;
|
||||
Vector3i position;
|
||||
unsigned int lod;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <core/io/dir_access.h>
|
||||
#include <core/io/file_access.h>
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
namespace {
|
||||
const uint8_t FORMAT_VERSION = 1;
|
||||
const char *FORMAT_META_MAGIC = "VXBM";
|
||||
@ -12,7 +14,7 @@ const char *META_FILE_NAME = "meta.vxbm";
|
||||
const char *BLOCK_FILE_EXTENSION = ".vxb";
|
||||
} // namespace
|
||||
|
||||
thread_local zylann::voxel::BlockSerializer VoxelStreamBlockFiles::_block_serializer;
|
||||
thread_local BlockSerializer VoxelStreamBlockFiles::_block_serializer;
|
||||
|
||||
VoxelStreamBlockFiles::VoxelStreamBlockFiles() {
|
||||
// Defaults
|
||||
@ -141,7 +143,7 @@ void VoxelStreamBlockFiles::immerge_block(VoxelBufferInternal &buffer, Vector3i
|
||||
f->store_buffer((uint8_t *)FORMAT_BLOCK_MAGIC, 4);
|
||||
f->store_8(FORMAT_VERSION);
|
||||
|
||||
zylann::voxel::BlockSerializer::SerializeResult res = _block_serializer.serialize_and_compress(buffer);
|
||||
BlockSerializer::SerializeResult res = _block_serializer.serialize_and_compress(buffer);
|
||||
if (!res.success) {
|
||||
memdelete(f);
|
||||
ERR_PRINT("Failed to save block");
|
||||
|
@ -15,8 +15,8 @@ class VoxelStreamBlockFiles : public VoxelStream {
|
||||
public:
|
||||
VoxelStreamBlockFiles();
|
||||
|
||||
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
|
||||
int get_used_channels_mask() const override;
|
||||
|
||||
@ -43,7 +43,8 @@ private:
|
||||
uint8_t version = -1;
|
||||
uint8_t lod_count = 0;
|
||||
uint8_t block_size_po2 = 0; // How many voxels in a block
|
||||
FixedArray<VoxelBufferInternal::Depth, VoxelBufferInternal::MAX_CHANNELS> channel_depths;
|
||||
FixedArray<zylann::voxel::VoxelBufferInternal::Depth, zylann::voxel::VoxelBufferInternal::MAX_CHANNELS>
|
||||
channel_depths;
|
||||
};
|
||||
|
||||
Meta _meta;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "voxel_stream_cache.h"
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
bool VoxelStreamCache::load_voxel_block(Vector3i position, uint8_t lod_index, VoxelBufferInternal &out_voxels) {
|
||||
const Lod &lod = _cache[lod_index];
|
||||
lod.rw_lock.read_lock();
|
||||
|
@ -20,15 +20,15 @@ public:
|
||||
bool has_voxels = false;
|
||||
bool voxels_deleted = false;
|
||||
|
||||
VoxelBufferInternal voxels;
|
||||
zylann::voxel::VoxelBufferInternal voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances;
|
||||
};
|
||||
|
||||
// Copies cached block into provided buffer
|
||||
bool load_voxel_block(Vector3i position, uint8_t lod_index, VoxelBufferInternal &out_voxels);
|
||||
bool load_voxel_block(Vector3i position, uint8_t lod_index, zylann::voxel::VoxelBufferInternal &out_voxels);
|
||||
|
||||
// Stores provided block into the cache. The cache will take ownership of the provided data.
|
||||
void save_voxel_block(Vector3i position, uint8_t lod_index, VoxelBufferInternal &voxels);
|
||||
void save_voxel_block(Vector3i position, uint8_t lod_index, zylann::voxel::VoxelBufferInternal &voxels);
|
||||
|
||||
// Copies cached data into the provided pointer. A new instance will be made if found.
|
||||
bool load_instance_block(
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "../constants/voxel_string_names.h"
|
||||
#include "../util/godot/funcs.h"
|
||||
|
||||
using namespace zylann::voxel;
|
||||
|
||||
VoxelStream::Result VoxelStreamScript::emerge_block(
|
||||
VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) {
|
||||
Variant output;
|
||||
|
@ -11,8 +11,8 @@
|
||||
class VoxelStreamScript : public VoxelStream {
|
||||
GDCLASS(VoxelStreamScript, VoxelStream)
|
||||
public:
|
||||
Result emerge_block(VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
Result emerge_block(zylann::voxel::VoxelBufferInternal &out_buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
void immerge_block(zylann::voxel::VoxelBufferInternal &buffer, Vector3i origin_in_voxels, int lod) override;
|
||||
|
||||
int get_used_channels_mask() const override;
|
||||
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
bool is_area_editable(Box3i p_box) const;
|
||||
VoxelSingleValue get_voxel(Vector3i pos, unsigned int channel, VoxelSingleValue defval);
|
||||
bool try_set_voxel_without_update(Vector3i pos, unsigned int channel, uint64_t value);
|
||||
void copy(Vector3i p_origin_voxels, VoxelBufferInternal &dst_buffer, uint8_t channels_mask);
|
||||
void copy(Vector3i p_origin_voxels, zylann::voxel::VoxelBufferInternal &dst_buffer, uint8_t channels_mask);
|
||||
|
||||
template <typename F>
|
||||
void write_box(const Box3i &p_voxel_box, unsigned int channel, F action) {
|
||||
@ -100,7 +100,7 @@ public:
|
||||
{
|
||||
RWLockWrite wlock(data_lod0.map_lock);
|
||||
data_lod0.map.write_box(
|
||||
voxel_box, channel, action, [&generator](VoxelBufferInternal &voxels, Vector3i pos) {
|
||||
voxel_box, channel, action, [&generator](zylann::voxel::VoxelBufferInternal &voxels, Vector3i pos) {
|
||||
if (generator.is_valid()) {
|
||||
VoxelBlockRequest r{ voxels, pos, 0 };
|
||||
generator->generate_block(r);
|
||||
@ -187,7 +187,7 @@ public:
|
||||
void remesh_all_blocks() override;
|
||||
|
||||
struct BlockToSave {
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
|
||||
Vector3i position;
|
||||
uint8_t lod;
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <scene/3d/mesh_instance_3d.h>
|
||||
|
||||
using namespace zylann;
|
||||
using namespace voxel;
|
||||
|
||||
VoxelTerrain::VoxelTerrain() {
|
||||
// Note: don't do anything heavy in the constructor.
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
const Stats &get_stats() const;
|
||||
|
||||
struct BlockToSave {
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::shared_ptr<zylann::voxel::VoxelBufferInternal> voxels;
|
||||
Vector3i position;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user