Namespaced remaining stuff

This commit is contained in:
Marc Gilleron 2022-01-09 22:46:26 +00:00
parent b67ca3d903
commit 9c6118806f
16 changed files with 97 additions and 85 deletions

View File

@ -154,7 +154,7 @@ In performance-critical areas which run a lot:
### Namespaces ### Namespaces
The intented namespaces are `zylann::` as main, and `zylann::voxel::` for voxel-related stuff. There may be others for different parts of the module. Namespaces are a work in progress, so a lot of places still miss them. The intented namespaces are `zylann::` as main, and `zylann::voxel::` for voxel-related stuff. There may be others for different parts of the module.
Registered classes are also namespaced, but are still largely prefixed with `Voxel`. Classes registered to the engine must have a unique name regardless of namespaces. Registered classes are also namespaced, but are still largely prefixed with `Voxel`. Classes registered to the engine must have a unique name regardless of namespaces.

View File

@ -413,7 +413,7 @@ void VoxelServer::request_voxel_block_save(
} }
void VoxelServer::request_instance_block_save( void VoxelServer::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<InstanceBlockData> instances, Vector3i block_pos, int lod) {
const Volume &volume = _world.volumes.get(volume_id); const Volume &volume = _world.volumes.get(volume_id);
ERR_FAIL_COND(volume.stream.is_null()); ERR_FAIL_COND(volume.stream.is_null());
CRASH_COND(volume.stream_dependency == nullptr); CRASH_COND(volume.stream_dependency == nullptr);

View File

@ -42,7 +42,7 @@ public:
Type type; Type type;
std::shared_ptr<VoxelBufferInternal> voxels; std::shared_ptr<VoxelBufferInternal> voxels;
std::unique_ptr<VoxelInstanceBlockData> instances; std::unique_ptr<InstanceBlockData> instances;
Vector3i position; Vector3i position;
uint8_t lod; uint8_t lod;
bool dropped; bool dropped;
@ -116,7 +116,7 @@ public:
void request_voxel_block_save( void request_voxel_block_save(
uint32_t volume_id, std::shared_ptr<VoxelBufferInternal> voxels, Vector3i block_pos, int lod); uint32_t volume_id, std::shared_ptr<VoxelBufferInternal> voxels, 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<InstanceBlockData> instances, Vector3i block_pos, int lod);
void remove_volume(uint32_t volume_id); void remove_volume(uint32_t volume_id);
bool is_volume_valid(uint32_t volume_id) const; bool is_volume_valid(uint32_t volume_id) const;
@ -281,7 +281,7 @@ private:
void apply_result() override; void apply_result() override;
std::shared_ptr<VoxelBufferInternal> voxels; std::shared_ptr<VoxelBufferInternal> voxels;
std::unique_ptr<VoxelInstanceBlockData> instances; std::unique_ptr<InstanceBlockData> 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;
uint8_t lod; uint8_t lod;

View File

@ -4,15 +4,15 @@
#include "../util/serialization.h" #include "../util/serialization.h"
#include <core/variant/variant.h> #include <core/variant/variant.h>
using namespace zylann; namespace zylann::voxel {
namespace { namespace {
const uint32_t TRAILING_MAGIC = 0x900df00d; const uint32_t TRAILING_MAGIC = 0x900df00d;
} }
const float VoxelInstanceBlockData::POSITION_RANGE_MINIMUM = 0.01f; const float InstanceBlockData::POSITION_RANGE_MINIMUM = 0.01f;
const float VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM = 0.01f; const float InstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM = 0.01f;
// TODO Unify with functions from VoxelBuffer? // TODO Unify with functions from VoxelBuffer?
@ -49,9 +49,9 @@ struct CompressedQuaternion4b {
} }
}; };
bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vector<uint8_t> &dst) { bool serialize_instance_block_data(const InstanceBlockData &src, std::vector<uint8_t> &dst) {
const uint8_t version = 0; const uint8_t version = 0;
const uint8_t instance_format = VoxelInstanceBlockData::FORMAT_SIMPLE_11B_V1; const uint8_t instance_format = InstanceBlockData::FORMAT_SIMPLE_11B_V1;
// TODO Apparently big-endian is dead // TODO Apparently big-endian is dead
// I chose it originally to match "network byte order", // I chose it originally to match "network byte order",
@ -59,7 +59,7 @@ bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vecto
zylann::MemoryWriter w(dst, zylann::ENDIANESS_BIG_ENDIAN); zylann::MemoryWriter w(dst, zylann::ENDIANESS_BIG_ENDIAN);
ERR_FAIL_COND_V(src.position_range < 0.f, false); ERR_FAIL_COND_V(src.position_range < 0.f, false);
const float position_range = math::max(src.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM); const float position_range = math::max(src.position_range, InstanceBlockData::POSITION_RANGE_MINIMUM);
w.store_8(version); w.store_8(version);
w.store_8(src.layers.size()); w.store_8(src.layers.size());
@ -70,15 +70,15 @@ bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vecto
const float pos_norm_scale = 1.f / position_range; const float pos_norm_scale = 1.f / position_range;
for (size_t i = 0; i < src.layers.size(); ++i) { for (size_t i = 0; i < src.layers.size(); ++i) {
const VoxelInstanceBlockData::LayerData &layer = src.layers[i]; const InstanceBlockData::LayerData &layer = src.layers[i];
ERR_FAIL_COND_V(layer.scale_max < layer.scale_min, false); ERR_FAIL_COND_V(layer.scale_max < layer.scale_min, false);
float scale_min = layer.scale_min; float scale_min = layer.scale_min;
float scale_max = layer.scale_max; float scale_max = layer.scale_max;
if (scale_max - scale_min < VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) { if (scale_max - scale_min < InstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) {
scale_min = layer.scale_min; scale_min = layer.scale_min;
scale_max = scale_min + VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM; scale_max = scale_min + InstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM;
} }
w.store_16(layer.id); w.store_16(layer.id);
@ -90,7 +90,7 @@ bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vecto
const float scale_norm_scale = 1.f / (scale_max - scale_min); const float scale_norm_scale = 1.f / (scale_max - scale_min);
for (size_t j = 0; j < layer.instances.size(); ++j) { for (size_t j = 0; j < layer.instances.size(); ++j) {
const VoxelInstanceBlockData::InstanceData &instance = layer.instances[j]; const InstanceBlockData::InstanceData &instance = layer.instances[j];
w.store_16(static_cast<uint16_t>(pos_norm_scale * instance.transform.origin.x * 0xffff)); w.store_16(static_cast<uint16_t>(pos_norm_scale * instance.transform.origin.x * 0xffff));
w.store_16(static_cast<uint16_t>(pos_norm_scale * instance.transform.origin.y * 0xffff)); w.store_16(static_cast<uint16_t>(pos_norm_scale * instance.transform.origin.y * 0xffff));
@ -113,9 +113,9 @@ bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vecto
return true; return true;
} }
bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uint8_t> src) { bool deserialize_instance_block_data(InstanceBlockData &dst, Span<const uint8_t> src) {
const uint8_t expected_version = 0; const uint8_t expected_version = 0;
const uint8_t expected_instance_format = VoxelInstanceBlockData::FORMAT_SIMPLE_11B_V1; const uint8_t expected_instance_format = InstanceBlockData::FORMAT_SIMPLE_11B_V1;
zylann::MemoryReader r(src, zylann::ENDIANESS_BIG_ENDIAN); zylann::MemoryReader r(src, zylann::ENDIANESS_BIG_ENDIAN);
@ -128,7 +128,7 @@ bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uin
dst.position_range = r.get_float(); dst.position_range = r.get_float();
for (size_t i = 0; i < dst.layers.size(); ++i) { for (size_t i = 0; i < dst.layers.size(); ++i) {
VoxelInstanceBlockData::LayerData &layer = dst.layers[i]; InstanceBlockData::LayerData &layer = dst.layers[i];
layer.id = r.get_16(); layer.id = r.get_16();
@ -157,7 +157,7 @@ bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uin
cq.w = r.get_8(); cq.w = r.get_8();
const Quaternion q = cq.to_quaternion(); const Quaternion q = cq.to_quaternion();
VoxelInstanceBlockData::InstanceData &instance = layer.instances[j]; InstanceBlockData::InstanceData &instance = layer.instances[j];
instance.transform = Transform3D(Basis(q).scaled(Vector3(s, s, s)), Vector3(x, y, z)); instance.transform = Transform3D(Basis(q).scaled(Vector3(s, s, s)), Vector3(x, y, z));
} }
} }
@ -168,3 +168,5 @@ bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uin
return true; return true;
} }
} // namespace zylann::voxel

View File

@ -4,8 +4,10 @@
#include "../util/span.h" #include "../util/span.h"
#include <core/math/transform_3d.h> #include <core/math/transform_3d.h>
namespace zylann::voxel {
// Stores data to pass around until it either gets saved or turned into actual instances // Stores data to pass around until it either gets saved or turned into actual instances
struct VoxelInstanceBlockData { struct InstanceBlockData {
struct InstanceData { struct InstanceData {
Transform3D transform; Transform3D transform;
}; };
@ -46,13 +48,15 @@ struct VoxelInstanceBlockData {
float position_range; float position_range;
std::vector<LayerData> layers; std::vector<LayerData> layers;
void copy_to(VoxelInstanceBlockData &dst) const { void copy_to(InstanceBlockData &dst) const {
// It's all POD so it should work for now // It's all POD so it should work for now
dst = *this; dst = *this;
} }
}; };
bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vector<uint8_t> &dst); bool serialize_instance_block_data(const InstanceBlockData &src, std::vector<uint8_t> &dst);
bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uint8_t> src); bool deserialize_instance_block_data(InstanceBlockData &dst, Span<const uint8_t> src);
} // namespace zylann::voxel
#endif // VOXEL_INSTANCE_DATA_H #endif // VOXEL_INSTANCE_DATA_H

View File

@ -777,7 +777,7 @@ void VoxelStreamSQLite::load_instance_blocks(
out_results[i] = RESULT_ERROR; out_results[i] = RESULT_ERROR;
continue; continue;
} }
r.data = std::make_unique<VoxelInstanceBlockData>(); r.data = std::make_unique<InstanceBlockData>();
if (!deserialize_instance_block_data(*r.data, to_span_const(_temp_block_data))) { if (!deserialize_instance_block_data(*r.data, to_span_const(_temp_block_data))) {
ERR_PRINT("Failed to deserialize instance block"); ERR_PRINT("Failed to deserialize instance block");
out_results[i] = RESULT_ERROR; out_results[i] = RESULT_ERROR;
@ -850,7 +850,7 @@ void VoxelStreamSQLite::load_all_blocks(FullLoadingResult &result) {
ERR_PRINT("Failed to decompress instance block"); ERR_PRINT("Failed to decompress instance block");
return; return;
} }
result_block.instances_data = std::make_unique<VoxelInstanceBlockData>(); result_block.instances_data = std::make_unique<InstanceBlockData>();
if (!deserialize_instance_block_data(*result_block.instances_data, to_span_const(temp_block_data))) { if (!deserialize_instance_block_data(*result_block.instances_data, to_span_const(temp_block_data))) {
ERR_PRINT("Failed to deserialize instance block"); ERR_PRINT("Failed to deserialize instance block");
return; return;

View File

@ -16,7 +16,7 @@ struct VoxelBlockRequest {
}; };
struct VoxelStreamInstanceDataRequest { struct VoxelStreamInstanceDataRequest {
std::unique_ptr<VoxelInstanceBlockData> data; std::unique_ptr<InstanceBlockData> data;
Vector3i position; Vector3i position;
uint8_t lod; uint8_t lod;
}; };

View File

@ -62,7 +62,7 @@ public:
struct FullLoadingResult { struct FullLoadingResult {
struct Block { struct Block {
std::shared_ptr<VoxelBufferInternal> voxels; std::shared_ptr<VoxelBufferInternal> voxels;
std::unique_ptr<VoxelInstanceBlockData> instances_data; std::unique_ptr<InstanceBlockData> instances_data;
Vector3i position; Vector3i position;
unsigned int lod; unsigned int lod;
}; };

View File

@ -50,7 +50,7 @@ void VoxelStreamCache::save_voxel_block(Vector3i position, uint8_t lod_index, Vo
} }
bool VoxelStreamCache::load_instance_block( bool VoxelStreamCache::load_instance_block(
Vector3i position, uint8_t lod_index, std::unique_ptr<VoxelInstanceBlockData> &out_instances) { Vector3i position, uint8_t lod_index, std::unique_ptr<InstanceBlockData> &out_instances) {
const Lod &lod = _cache[lod_index]; const Lod &lod = _cache[lod_index];
lod.rw_lock.read_lock(); lod.rw_lock.read_lock();
auto it = lod.blocks.find(position); auto it = lod.blocks.find(position);
@ -68,7 +68,7 @@ bool VoxelStreamCache::load_instance_block(
} else { } else {
// Copying is required since the cache has ownership on its data // Copying is required since the cache has ownership on its data
out_instances = std::make_unique<VoxelInstanceBlockData>(); out_instances = std::make_unique<InstanceBlockData>();
it->second.instances->copy_to(*out_instances); it->second.instances->copy_to(*out_instances);
} }
@ -78,7 +78,7 @@ bool VoxelStreamCache::load_instance_block(
} }
void VoxelStreamCache::save_instance_block( void VoxelStreamCache::save_instance_block(
Vector3i position, uint8_t lod_index, std::unique_ptr<VoxelInstanceBlockData> instances) { Vector3i position, uint8_t lod_index, std::unique_ptr<InstanceBlockData> instances) {
Lod &lod = _cache[lod_index]; Lod &lod = _cache[lod_index];
RWLockWrite wlock(lod.rw_lock); RWLockWrite wlock(lod.rw_lock);
auto it = lod.blocks.find(position); auto it = lod.blocks.find(position);

View File

@ -23,7 +23,7 @@ public:
bool voxels_deleted = false; bool voxels_deleted = false;
VoxelBufferInternal voxels; VoxelBufferInternal voxels;
std::unique_ptr<VoxelInstanceBlockData> instances; std::unique_ptr<InstanceBlockData> instances;
}; };
// Copies cached block into provided buffer // Copies cached block into provided buffer
@ -33,11 +33,10 @@ public:
void save_voxel_block(Vector3i position, uint8_t lod_index, VoxelBufferInternal &voxels); void save_voxel_block(Vector3i position, uint8_t lod_index, 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(Vector3i position, uint8_t lod_index, std::unique_ptr<InstanceBlockData> &out_instances);
Vector3i position, uint8_t lod_index, std::unique_ptr<VoxelInstanceBlockData> &out_instances);
// 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_instance_block(Vector3i position, uint8_t lod_index, std::unique_ptr<VoxelInstanceBlockData> instances); void save_instance_block(Vector3i position, uint8_t lod_index, std::unique_ptr<InstanceBlockData> instances);
unsigned int get_indicative_block_count() const; unsigned int get_indicative_block_count() const;

View File

@ -704,7 +704,7 @@ void VoxelInstancer::remove_block(unsigned int block_index) {
} }
void VoxelInstancer::on_data_block_loaded( void VoxelInstancer::on_data_block_loaded(
Vector3i grid_position, unsigned int lod_index, std::unique_ptr<VoxelInstanceBlockData> instances) { Vector3i grid_position, unsigned int lod_index, std::unique_ptr<InstanceBlockData> instances) {
ERR_FAIL_COND(lod_index >= _lods.size()); ERR_FAIL_COND(lod_index >= _lods.size());
Lod &lod = _lods[lod_index]; Lod &lod = _lods[lod_index];
lod.loaded_instances_data.insert(std::make_pair(grid_position, std::move(instances))); lod.loaded_instances_data.insert(std::make_pair(grid_position, std::move(instances)));
@ -963,9 +963,9 @@ void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Tr
} }
} }
static const VoxelInstanceBlockData::LayerData *find_layer_data(const VoxelInstanceBlockData &instances_data, int id) { static const InstanceBlockData::LayerData *find_layer_data(const InstanceBlockData &instances_data, int id) {
for (size_t i = 0; i < instances_data.layers.size(); ++i) { for (size_t i = 0; i < instances_data.layers.size(); ++i) {
const VoxelInstanceBlockData::LayerData &layer = instances_data.layers[i]; const InstanceBlockData::LayerData &layer = instances_data.layers[i];
if (layer.id == id) { if (layer.id == id) {
return &layer; return &layer;
} }
@ -1022,18 +1022,17 @@ void VoxelInstancer::create_render_blocks(Vector3i render_grid_position, int lod
if (instances_data_it != lod.loaded_instances_data.end()) { if (instances_data_it != lod.loaded_instances_data.end()) {
// This area has user-edited instances // This area has user-edited instances
const VoxelInstanceBlockData *instances_data = instances_data_it->second.get(); const InstanceBlockData *instances_data = instances_data_it->second.get();
CRASH_COND(instances_data == nullptr); CRASH_COND(instances_data == nullptr);
const VoxelInstanceBlockData::LayerData *layer_data = const InstanceBlockData::LayerData *layer_data = find_layer_data(*instances_data, layer_id);
find_layer_data(*instances_data, layer_id);
if (layer_data == nullptr) { if (layer_data == nullptr) {
continue; continue;
} }
for (auto it = layer_data->instances.begin(); it != layer_data->instances.end(); ++it) { for (auto it = layer_data->instances.begin(); it != layer_data->instances.end(); ++it) {
const VoxelInstanceBlockData::InstanceData &d = *it; const InstanceBlockData::InstanceData &d = *it;
_transform_cache.push_back(d.transform); _transform_cache.push_back(d.transform);
} }
@ -1085,7 +1084,7 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
const Lod &lod = _lods[lod_index]; const Lod &lod = _lods[lod_index];
std::unique_ptr<VoxelInstanceBlockData> data = std::make_unique<VoxelInstanceBlockData>(); std::unique_ptr<InstanceBlockData> data = std::make_unique<InstanceBlockData>();
const int data_block_size = _parent->get_data_block_size() << lod_index; const int data_block_size = _parent->get_data_block_size() << lod_index;
data->position_range = data_block_size; data->position_range = data_block_size;
@ -1124,8 +1123,8 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
Block *render_block = _blocks[render_block_index]; Block *render_block = _blocks[render_block_index];
ERR_CONTINUE(render_block == nullptr); ERR_CONTINUE(render_block == nullptr);
data->layers.push_back(VoxelInstanceBlockData::LayerData()); data->layers.push_back(InstanceBlockData::LayerData());
VoxelInstanceBlockData::LayerData &layer_data = data->layers.back(); InstanceBlockData::LayerData &layer_data = data->layers.back();
layer_data.instances.clear(); layer_data.instances.clear();
layer_data.id = layer_id; layer_data.id = layer_id;
@ -1165,7 +1164,7 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
const int instance_octant_index = const int instance_octant_index =
VoxelInstanceGenerator::get_octant_index(t.origin, half_render_block_size); VoxelInstanceGenerator::get_octant_index(t.origin, half_render_block_size);
if (instance_octant_index == octant_index) { if (instance_octant_index == octant_index) {
VoxelInstanceBlockData::InstanceData d; InstanceBlockData::InstanceData d;
d.transform = t; d.transform = t;
layer_data.instances.push_back(d); layer_data.instances.push_back(d);
} }
@ -1195,7 +1194,7 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
const int instance_octant_index = const int instance_octant_index =
VoxelInstanceGenerator::get_octant_index(t.origin, half_render_block_size); VoxelInstanceGenerator::get_octant_index(t.origin, half_render_block_size);
if (instance_octant_index == octant_index) { if (instance_octant_index == octant_index) {
VoxelInstanceBlockData::InstanceData d; InstanceBlockData::InstanceData d;
d.transform = t; d.transform = t;
layer_data.instances.push_back(d); layer_data.instances.push_back(d);
} }

View File

@ -64,7 +64,7 @@ public:
// Event handlers // Event handlers
void on_data_block_loaded( void on_data_block_loaded(
Vector3i grid_position, unsigned int lod_index, std::unique_ptr<VoxelInstanceBlockData> instances); Vector3i grid_position, unsigned int lod_index, std::unique_ptr<InstanceBlockData> instances);
void on_mesh_block_enter(Vector3i render_grid_position, unsigned int lod_index, Array surface_arrays); void on_mesh_block_enter(Vector3i render_grid_position, unsigned int lod_index, Array surface_arrays);
void on_mesh_block_exit(Vector3i render_grid_position, unsigned int lod_index); void on_mesh_block_exit(Vector3i render_grid_position, unsigned int lod_index);
void on_area_edited(Box3i p_voxel_box); void on_area_edited(Box3i p_voxel_box);
@ -188,7 +188,7 @@ private:
// it will get generated instances. // it will get generated instances.
// Keys follows the data block coordinate system. // Keys follows the data block coordinate system.
// Can't use `HashMap` because it lacks move semantics. // Can't use `HashMap` because it lacks move semantics.
std::unordered_map<Vector3i, std::unique_ptr<VoxelInstanceBlockData>> loaded_instances_data; std::unordered_map<Vector3i, std::unique_ptr<InstanceBlockData>> loaded_instances_data;
FixedArray<MeshLodDistances, VoxelInstanceLibraryItem::MAX_MESH_LODS> mesh_lod_distances; FixedArray<MeshLodDistances, VoxelInstanceLibraryItem::MAX_MESH_LODS> mesh_lod_distances;

View File

@ -693,9 +693,9 @@ void test_unordered_remove_if() {
void test_instance_data_serialization() { void test_instance_data_serialization() {
struct L { struct L {
static VoxelInstanceBlockData::InstanceData create_instance( static InstanceBlockData::InstanceData create_instance(
float x, float y, float z, float rotx, float roty, float rotz, float scale) { float x, float y, float z, float rotx, float roty, float rotz, float scale) {
VoxelInstanceBlockData::InstanceData d; InstanceBlockData::InstanceData d;
d.transform = Transform3D( d.transform = Transform3D(
Basis().rotated(Vector3(rotx, roty, rotz)).scaled(Vector3(scale, scale, scale)), Vector3(x, y, z)); Basis().rotated(Vector3(rotx, roty, rotz)).scaled(Vector3(scale, scale, scale)), Vector3(x, y, z));
return d; return d;
@ -703,11 +703,11 @@ void test_instance_data_serialization() {
}; };
// Create some example data // Create some example data
VoxelInstanceBlockData src_data; InstanceBlockData src_data;
{ {
src_data.position_range = 30; src_data.position_range = 30;
{ {
VoxelInstanceBlockData::LayerData layer; InstanceBlockData::LayerData layer;
layer.id = 1; layer.id = 1;
layer.scale_min = 1.f; layer.scale_min = 1.f;
layer.scale_max = 1.f; layer.scale_max = 1.f;
@ -718,7 +718,7 @@ void test_instance_data_serialization() {
src_data.layers.push_back(layer); src_data.layers.push_back(layer);
} }
{ {
VoxelInstanceBlockData::LayerData layer; InstanceBlockData::LayerData layer;
layer.id = 2; layer.id = 2;
layer.scale_min = 1.f; layer.scale_min = 1.f;
layer.scale_max = 4.f; layer.scale_max = 4.f;
@ -734,7 +734,7 @@ void test_instance_data_serialization() {
ERR_FAIL_COND(!serialize_instance_block_data(src_data, serialized_data)); ERR_FAIL_COND(!serialize_instance_block_data(src_data, serialized_data));
VoxelInstanceBlockData dst_data; InstanceBlockData dst_data;
ERR_FAIL_COND(!deserialize_instance_block_data(dst_data, to_span_const(serialized_data))); ERR_FAIL_COND(!deserialize_instance_block_data(dst_data, to_span_const(serialized_data)));
// Compare blocks // Compare blocks
@ -742,16 +742,16 @@ void test_instance_data_serialization() {
ERR_FAIL_COND(dst_data.position_range < 0.f); ERR_FAIL_COND(dst_data.position_range < 0.f);
ERR_FAIL_COND(dst_data.position_range != src_data.position_range); ERR_FAIL_COND(dst_data.position_range != src_data.position_range);
const float distance_error = math::max(src_data.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM) / const float distance_error = math::max(src_data.position_range, InstanceBlockData::POSITION_RANGE_MINIMUM) /
float(VoxelInstanceBlockData::POSITION_RESOLUTION); float(InstanceBlockData::POSITION_RESOLUTION);
// Compare layers // Compare layers
for (unsigned int layer_index = 0; layer_index < dst_data.layers.size(); ++layer_index) { for (unsigned int layer_index = 0; layer_index < dst_data.layers.size(); ++layer_index) {
const VoxelInstanceBlockData::LayerData &src_layer = src_data.layers[layer_index]; const InstanceBlockData::LayerData &src_layer = src_data.layers[layer_index];
const VoxelInstanceBlockData::LayerData &dst_layer = dst_data.layers[layer_index]; const InstanceBlockData::LayerData &dst_layer = dst_data.layers[layer_index];
ERR_FAIL_COND(src_layer.id != dst_layer.id); ERR_FAIL_COND(src_layer.id != dst_layer.id);
if (src_layer.scale_max - src_layer.scale_min < VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) { if (src_layer.scale_max - src_layer.scale_min < InstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) {
ERR_FAIL_COND(src_layer.scale_min != dst_layer.scale_min); ERR_FAIL_COND(src_layer.scale_min != dst_layer.scale_min);
} else { } else {
ERR_FAIL_COND(src_layer.scale_min != dst_layer.scale_min); ERR_FAIL_COND(src_layer.scale_min != dst_layer.scale_min);
@ -760,15 +760,15 @@ void test_instance_data_serialization() {
ERR_FAIL_COND(src_layer.instances.size() != dst_layer.instances.size()); ERR_FAIL_COND(src_layer.instances.size() != dst_layer.instances.size());
const float scale_error = math::max(src_layer.scale_max - src_layer.scale_min, const float scale_error = math::max(src_layer.scale_max - src_layer.scale_min,
VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) / InstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) /
float(VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RESOLUTION); float(InstanceBlockData::SIMPLE_11B_V1_SCALE_RESOLUTION);
const float rotation_error = 2.f / float(VoxelInstanceBlockData::SIMPLE_11B_V1_QUAT_RESOLUTION); const float rotation_error = 2.f / float(InstanceBlockData::SIMPLE_11B_V1_QUAT_RESOLUTION);
// Compare instances // Compare instances
for (unsigned int instance_index = 0; instance_index < src_layer.instances.size(); ++instance_index) { for (unsigned int instance_index = 0; instance_index < src_layer.instances.size(); ++instance_index) {
const VoxelInstanceBlockData::InstanceData &src_instance = src_layer.instances[instance_index]; const InstanceBlockData::InstanceData &src_instance = src_layer.instances[instance_index];
const VoxelInstanceBlockData::InstanceData &dst_instance = dst_layer.instances[instance_index]; const InstanceBlockData::InstanceData &dst_instance = dst_layer.instances[instance_index];
ERR_FAIL_COND(src_instance.transform.origin.distance_to(dst_instance.transform.origin) > distance_error); ERR_FAIL_COND(src_instance.transform.origin.distance_to(dst_instance.transform.origin) > distance_error);

View File

@ -4,6 +4,8 @@
#include "vector3i.h" #include "vector3i.h"
#include <core/variant/variant.h> #include <core/variant/variant.h>
namespace zylann {
// Axis-aligned 3D box using integer coordinates // Axis-aligned 3D box using integer coordinates
class Box3i { class Box3i {
public: public:
@ -33,16 +35,16 @@ public:
static inline Box3i get_bounding_box(Box3i a, Box3i b) { static inline Box3i get_bounding_box(Box3i a, Box3i b) {
Box3i box; Box3i box;
box.pos.x = zylann::math::min(a.pos.x, b.pos.x); box.pos.x = math::min(a.pos.x, b.pos.x);
box.pos.y = zylann::math::min(a.pos.y, b.pos.y); box.pos.y = math::min(a.pos.y, b.pos.y);
box.pos.z = zylann::math::min(a.pos.z, b.pos.z); box.pos.z = math::min(a.pos.z, b.pos.z);
Vector3i max_a = a.pos + a.size; Vector3i max_a = a.pos + a.size;
Vector3i max_b = b.pos + b.size; Vector3i max_b = b.pos + b.size;
box.size.x = zylann::math::max(max_a.x, max_b.x) - box.pos.x; box.size.x = math::max(max_a.x, max_b.x) - box.pos.x;
box.size.y = zylann::math::max(max_a.y, max_b.y) - box.pos.y; box.size.y = math::max(max_a.y, max_b.y) - box.pos.y;
box.size.z = zylann::math::max(max_a.z, max_b.z) - box.pos.z; box.size.z = math::max(max_a.z, max_b.z) - box.pos.z;
return box; return box;
} }
@ -293,8 +295,8 @@ public:
int max_pos = pos + size; int max_pos = pos + size;
int lim_max_pos = lim_pos + lim_size; int lim_max_pos = lim_pos + lim_size;
pos = zylann::math::clamp(pos, lim_pos, lim_max_pos); pos = math::clamp(pos, lim_pos, lim_max_pos);
max_pos = zylann::math::clamp(max_pos, lim_pos, lim_max_pos); max_pos = math::clamp(max_pos, lim_pos, lim_max_pos);
size = max_pos - pos; size = max_pos - pos;
if (size < 0) { if (size < 0) {
@ -334,13 +336,13 @@ public:
void merge_with(const Box3i &other) { void merge_with(const Box3i &other) {
const Vector3i min_pos( // const Vector3i min_pos( //
zylann::math::min(pos.x, other.pos.x), // math::min(pos.x, other.pos.x), //
zylann::math::min(pos.y, other.pos.y), // math::min(pos.y, other.pos.y), //
zylann::math::min(pos.z, other.pos.z)); math::min(pos.z, other.pos.z));
const Vector3i max_pos( // const Vector3i max_pos( //
zylann::math::max(pos.x + size.x, other.pos.x + other.size.x), // math::max(pos.x + size.x, other.pos.x + other.size.x), //
zylann::math::max(pos.y + size.y, other.pos.y + other.size.y), // math::max(pos.y + size.y, other.pos.y + other.size.y), //
zylann::math::max(pos.z + size.z, other.pos.z + other.size.z)); math::max(pos.z + size.z, other.pos.z + other.size.z));
pos = min_pos; pos = min_pos;
size = max_pos - min_pos; size = max_pos - min_pos;
} }
@ -354,4 +356,6 @@ inline bool operator==(const Box3i &a, const Box3i &b) {
return a.pos == b.pos && a.size == b.size; return a.pos == b.pos && a.size == b.size;
} }
} // namespace zylann
#endif // BOX3I_H #endif // BOX3I_H

View File

@ -268,7 +268,7 @@ _FORCE_INLINE_ int64_t Vector3i::distance_sq(const Vector3i &other) const {
#else #else
namespace Vector3iUtil { namespace zylann::Vector3iUtil {
constexpr int AXIS_COUNT = 3; constexpr int AXIS_COUNT = 3;
@ -344,7 +344,7 @@ inline bool is_unit_vector(const Vector3i v) {
return Math::abs(v.x) + Math::abs(v.y) + Math::abs(v.z) == 1; return Math::abs(v.x) + Math::abs(v.y) + Math::abs(v.z) == 1;
} }
} // namespace Vector3iUtil } // namespace zylann::Vector3iUtil
inline Vector3i operator<<(const Vector3i &a, int b) { inline Vector3i operator<<(const Vector3i &a, int b) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED

View File

@ -4,6 +4,8 @@
#include "fixed_array.h" #include "fixed_array.h"
#include <vector> #include <vector>
namespace zylann {
// View into an array, referencing a pointer and a size. // View into an array, referencing a pointer and a size.
// STL equivalent would be std::span<T> in C++20 // STL equivalent would be std::span<T> in C++20
template <typename T> template <typename T>
@ -38,7 +40,7 @@ public:
// TODO Remove this one, prefer to_span() specializations // TODO Remove this one, prefer to_span() specializations
template <unsigned int N> template <unsigned int N>
inline Span(zylann::FixedArray<T, N> &a) { inline Span(FixedArray<T, N> &a) {
_ptr = a.data(); _ptr = a.data();
_size = a.size(); _size = a.size();
} }
@ -124,24 +126,24 @@ Span<const T> to_span_const(const std::vector<T> &vec) {
} }
template <typename T, unsigned int N> template <typename T, unsigned int N>
Span<T> to_span(zylann::FixedArray<T, N> &a) { Span<T> to_span(FixedArray<T, N> &a) {
return Span<T>(a.data(), a.size()); return Span<T>(a.data(), a.size());
} }
template <typename T, unsigned int N> template <typename T, unsigned int N>
Span<T> to_span(zylann::FixedArray<T, N> &a, unsigned int count) { Span<T> to_span(FixedArray<T, N> &a, unsigned int count) {
CRASH_COND(count > a.size()); CRASH_COND(count > a.size());
return Span<T>(a.data(), count); return Span<T>(a.data(), count);
} }
template <typename T, unsigned int N> template <typename T, unsigned int N>
Span<const T> to_span_const(const zylann::FixedArray<T, N> &a, unsigned int count) { Span<const T> to_span_const(const FixedArray<T, N> &a, unsigned int count) {
CRASH_COND(count > a.size()); CRASH_COND(count > a.size());
return Span<const T>(a.data(), count); return Span<const T>(a.data(), count);
} }
template <typename T, unsigned int N> template <typename T, unsigned int N>
Span<const T> to_span_const(const zylann::FixedArray<T, N> &a) { Span<const T> to_span_const(const FixedArray<T, N> &a) {
return Span<const T>(a.data(), 0, a.size()); return Span<const T>(a.data(), 0, a.size());
} }
@ -150,4 +152,6 @@ Span<const T> to_span_const(const Span<T> &a) {
return Span<const T>(a.data(), 0, a.size()); return Span<const T>(a.data(), 0, a.size());
} }
} // namespace zylann
#endif // SPAN_H #endif // SPAN_H