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