Namespaced remaining stuff
This commit is contained in:
parent
b67ca3d903
commit
9c6118806f
@ -154,7 +154,7 @@ In performance-critical areas which run a lot:
|
||||
|
||||
### 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.
|
||||
|
||||
|
@ -413,7 +413,7 @@ void VoxelServer::request_voxel_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);
|
||||
ERR_FAIL_COND(volume.stream.is_null());
|
||||
CRASH_COND(volume.stream_dependency == nullptr);
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
|
||||
Type type;
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances;
|
||||
std::unique_ptr<InstanceBlockData> instances;
|
||||
Vector3i position;
|
||||
uint8_t lod;
|
||||
bool dropped;
|
||||
@ -116,7 +116,7 @@ public:
|
||||
void request_voxel_block_save(
|
||||
uint32_t volume_id, std::shared_ptr<VoxelBufferInternal> voxels, Vector3i block_pos, int lod);
|
||||
void request_instance_block_save(
|
||||
uint32_t volume_id, std::unique_ptr<VoxelInstanceBlockData> instances, Vector3i block_pos, int lod);
|
||||
uint32_t volume_id, std::unique_ptr<InstanceBlockData> instances, Vector3i block_pos, int lod);
|
||||
void remove_volume(uint32_t volume_id);
|
||||
bool is_volume_valid(uint32_t volume_id) const;
|
||||
|
||||
@ -281,7 +281,7 @@ private:
|
||||
void apply_result() override;
|
||||
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances;
|
||||
std::unique_ptr<InstanceBlockData> instances;
|
||||
Vector3i position; // In data blocks of the specified lod
|
||||
uint32_t volume_id;
|
||||
uint8_t lod;
|
||||
|
@ -4,15 +4,15 @@
|
||||
#include "../util/serialization.h"
|
||||
#include <core/variant/variant.h>
|
||||
|
||||
using namespace zylann;
|
||||
namespace zylann::voxel {
|
||||
|
||||
namespace {
|
||||
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?
|
||||
|
||||
@ -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 instance_format = VoxelInstanceBlockData::FORMAT_SIMPLE_11B_V1;
|
||||
const uint8_t instance_format = InstanceBlockData::FORMAT_SIMPLE_11B_V1;
|
||||
|
||||
// TODO Apparently big-endian is dead
|
||||
// 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);
|
||||
|
||||
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(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;
|
||||
|
||||
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);
|
||||
|
||||
float scale_min = layer.scale_min;
|
||||
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_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);
|
||||
@ -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);
|
||||
|
||||
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.y * 0xffff));
|
||||
@ -113,9 +113,9 @@ bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vecto
|
||||
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_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);
|
||||
|
||||
@ -128,7 +128,7 @@ bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uin
|
||||
dst.position_range = r.get_float();
|
||||
|
||||
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();
|
||||
|
||||
@ -157,7 +157,7 @@ bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uin
|
||||
cq.w = r.get_8();
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -168,3 +168,5 @@ bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uin
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
@ -4,8 +4,10 @@
|
||||
#include "../util/span.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
|
||||
struct VoxelInstanceBlockData {
|
||||
struct InstanceBlockData {
|
||||
struct InstanceData {
|
||||
Transform3D transform;
|
||||
};
|
||||
@ -46,13 +48,15 @@ struct VoxelInstanceBlockData {
|
||||
float position_range;
|
||||
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
|
||||
dst = *this;
|
||||
}
|
||||
};
|
||||
|
||||
bool serialize_instance_block_data(const VoxelInstanceBlockData &src, std::vector<uint8_t> &dst);
|
||||
bool deserialize_instance_block_data(VoxelInstanceBlockData &dst, Span<const uint8_t> src);
|
||||
bool serialize_instance_block_data(const InstanceBlockData &src, std::vector<uint8_t> &dst);
|
||||
bool deserialize_instance_block_data(InstanceBlockData &dst, Span<const uint8_t> src);
|
||||
|
||||
} // namespace zylann::voxel
|
||||
|
||||
#endif // VOXEL_INSTANCE_DATA_H
|
||||
|
@ -777,7 +777,7 @@ void VoxelStreamSQLite::load_instance_blocks(
|
||||
out_results[i] = RESULT_ERROR;
|
||||
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))) {
|
||||
ERR_PRINT("Failed to deserialize instance block");
|
||||
out_results[i] = RESULT_ERROR;
|
||||
@ -850,7 +850,7 @@ void VoxelStreamSQLite::load_all_blocks(FullLoadingResult &result) {
|
||||
ERR_PRINT("Failed to decompress instance block");
|
||||
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))) {
|
||||
ERR_PRINT("Failed to deserialize instance block");
|
||||
return;
|
||||
|
@ -16,7 +16,7 @@ struct VoxelBlockRequest {
|
||||
};
|
||||
|
||||
struct VoxelStreamInstanceDataRequest {
|
||||
std::unique_ptr<VoxelInstanceBlockData> data;
|
||||
std::unique_ptr<InstanceBlockData> data;
|
||||
Vector3i position;
|
||||
uint8_t lod;
|
||||
};
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
struct FullLoadingResult {
|
||||
struct Block {
|
||||
std::shared_ptr<VoxelBufferInternal> voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances_data;
|
||||
std::unique_ptr<InstanceBlockData> instances_data;
|
||||
Vector3i position;
|
||||
unsigned int lod;
|
||||
};
|
||||
|
@ -50,7 +50,7 @@ void VoxelStreamCache::save_voxel_block(Vector3i position, uint8_t lod_index, Vo
|
||||
}
|
||||
|
||||
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];
|
||||
lod.rw_lock.read_lock();
|
||||
auto it = lod.blocks.find(position);
|
||||
@ -68,7 +68,7 @@ bool VoxelStreamCache::load_instance_block(
|
||||
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ bool VoxelStreamCache::load_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];
|
||||
RWLockWrite wlock(lod.rw_lock);
|
||||
auto it = lod.blocks.find(position);
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
bool voxels_deleted = false;
|
||||
|
||||
VoxelBufferInternal voxels;
|
||||
std::unique_ptr<VoxelInstanceBlockData> instances;
|
||||
std::unique_ptr<InstanceBlockData> instances;
|
||||
};
|
||||
|
||||
// Copies cached block into provided buffer
|
||||
@ -33,11 +33,10 @@ public:
|
||||
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.
|
||||
bool load_instance_block(
|
||||
Vector3i position, uint8_t lod_index, std::unique_ptr<VoxelInstanceBlockData> &out_instances);
|
||||
bool load_instance_block(Vector3i position, uint8_t lod_index, std::unique_ptr<InstanceBlockData> &out_instances);
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -704,7 +704,7 @@ void VoxelInstancer::remove_block(unsigned int block_index) {
|
||||
}
|
||||
|
||||
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());
|
||||
Lod &lod = _lods[lod_index];
|
||||
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) {
|
||||
const VoxelInstanceBlockData::LayerData &layer = instances_data.layers[i];
|
||||
const InstanceBlockData::LayerData &layer = instances_data.layers[i];
|
||||
if (layer.id == id) {
|
||||
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()) {
|
||||
// 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);
|
||||
|
||||
const VoxelInstanceBlockData::LayerData *layer_data =
|
||||
find_layer_data(*instances_data, layer_id);
|
||||
const InstanceBlockData::LayerData *layer_data = find_layer_data(*instances_data, layer_id);
|
||||
|
||||
if (layer_data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1085,7 +1084,7 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
|
||||
|
||||
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;
|
||||
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];
|
||||
ERR_CONTINUE(render_block == nullptr);
|
||||
|
||||
data->layers.push_back(VoxelInstanceBlockData::LayerData());
|
||||
VoxelInstanceBlockData::LayerData &layer_data = data->layers.back();
|
||||
data->layers.push_back(InstanceBlockData::LayerData());
|
||||
InstanceBlockData::LayerData &layer_data = data->layers.back();
|
||||
|
||||
layer_data.instances.clear();
|
||||
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 =
|
||||
VoxelInstanceGenerator::get_octant_index(t.origin, half_render_block_size);
|
||||
if (instance_octant_index == octant_index) {
|
||||
VoxelInstanceBlockData::InstanceData d;
|
||||
InstanceBlockData::InstanceData d;
|
||||
d.transform = t;
|
||||
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 =
|
||||
VoxelInstanceGenerator::get_octant_index(t.origin, half_render_block_size);
|
||||
if (instance_octant_index == octant_index) {
|
||||
VoxelInstanceBlockData::InstanceData d;
|
||||
InstanceBlockData::InstanceData d;
|
||||
d.transform = t;
|
||||
layer_data.instances.push_back(d);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
// Event handlers
|
||||
|
||||
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_exit(Vector3i render_grid_position, unsigned int lod_index);
|
||||
void on_area_edited(Box3i p_voxel_box);
|
||||
@ -188,7 +188,7 @@ private:
|
||||
// it will get generated instances.
|
||||
// Keys follows the data block coordinate system.
|
||||
// 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;
|
||||
|
||||
|
@ -693,9 +693,9 @@ void test_unordered_remove_if() {
|
||||
|
||||
void test_instance_data_serialization() {
|
||||
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) {
|
||||
VoxelInstanceBlockData::InstanceData d;
|
||||
InstanceBlockData::InstanceData d;
|
||||
d.transform = Transform3D(
|
||||
Basis().rotated(Vector3(rotx, roty, rotz)).scaled(Vector3(scale, scale, scale)), Vector3(x, y, z));
|
||||
return d;
|
||||
@ -703,11 +703,11 @@ void test_instance_data_serialization() {
|
||||
};
|
||||
|
||||
// Create some example data
|
||||
VoxelInstanceBlockData src_data;
|
||||
InstanceBlockData src_data;
|
||||
{
|
||||
src_data.position_range = 30;
|
||||
{
|
||||
VoxelInstanceBlockData::LayerData layer;
|
||||
InstanceBlockData::LayerData layer;
|
||||
layer.id = 1;
|
||||
layer.scale_min = 1.f;
|
||||
layer.scale_max = 1.f;
|
||||
@ -718,7 +718,7 @@ void test_instance_data_serialization() {
|
||||
src_data.layers.push_back(layer);
|
||||
}
|
||||
{
|
||||
VoxelInstanceBlockData::LayerData layer;
|
||||
InstanceBlockData::LayerData layer;
|
||||
layer.id = 2;
|
||||
layer.scale_min = 1.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));
|
||||
|
||||
VoxelInstanceBlockData dst_data;
|
||||
InstanceBlockData dst_data;
|
||||
ERR_FAIL_COND(!deserialize_instance_block_data(dst_data, to_span_const(serialized_data)));
|
||||
|
||||
// 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 != src_data.position_range);
|
||||
|
||||
const float distance_error = math::max(src_data.position_range, VoxelInstanceBlockData::POSITION_RANGE_MINIMUM) /
|
||||
float(VoxelInstanceBlockData::POSITION_RESOLUTION);
|
||||
const float distance_error = math::max(src_data.position_range, InstanceBlockData::POSITION_RANGE_MINIMUM) /
|
||||
float(InstanceBlockData::POSITION_RESOLUTION);
|
||||
|
||||
// Compare layers
|
||||
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 VoxelInstanceBlockData::LayerData &dst_layer = dst_data.layers[layer_index];
|
||||
const InstanceBlockData::LayerData &src_layer = src_data.layers[layer_index];
|
||||
const InstanceBlockData::LayerData &dst_layer = dst_data.layers[layer_index];
|
||||
|
||||
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);
|
||||
} else {
|
||||
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());
|
||||
|
||||
const float scale_error = math::max(src_layer.scale_max - src_layer.scale_min,
|
||||
VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) /
|
||||
float(VoxelInstanceBlockData::SIMPLE_11B_V1_SCALE_RESOLUTION);
|
||||
InstanceBlockData::SIMPLE_11B_V1_SCALE_RANGE_MINIMUM) /
|
||||
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
|
||||
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 VoxelInstanceBlockData::InstanceData &dst_instance = dst_layer.instances[instance_index];
|
||||
const InstanceBlockData::InstanceData &src_instance = src_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);
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "vector3i.h"
|
||||
#include <core/variant/variant.h>
|
||||
|
||||
namespace zylann {
|
||||
|
||||
// Axis-aligned 3D box using integer coordinates
|
||||
class Box3i {
|
||||
public:
|
||||
@ -33,16 +35,16 @@ public:
|
||||
static inline Box3i get_bounding_box(Box3i a, Box3i b) {
|
||||
Box3i box;
|
||||
|
||||
box.pos.x = zylann::math::min(a.pos.x, b.pos.x);
|
||||
box.pos.y = zylann::math::min(a.pos.y, b.pos.y);
|
||||
box.pos.z = zylann::math::min(a.pos.z, b.pos.z);
|
||||
box.pos.x = math::min(a.pos.x, b.pos.x);
|
||||
box.pos.y = math::min(a.pos.y, b.pos.y);
|
||||
box.pos.z = math::min(a.pos.z, b.pos.z);
|
||||
|
||||
Vector3i max_a = a.pos + a.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.y = zylann::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.x = math::max(max_a.x, max_b.x) - box.pos.x;
|
||||
box.size.y = math::max(max_a.y, max_b.y) - box.pos.y;
|
||||
box.size.z = math::max(max_a.z, max_b.z) - box.pos.z;
|
||||
|
||||
return box;
|
||||
}
|
||||
@ -293,8 +295,8 @@ public:
|
||||
int max_pos = pos + size;
|
||||
int lim_max_pos = lim_pos + lim_size;
|
||||
|
||||
pos = zylann::math::clamp(pos, lim_pos, lim_max_pos);
|
||||
max_pos = zylann::math::clamp(max_pos, lim_pos, lim_max_pos);
|
||||
pos = math::clamp(pos, lim_pos, lim_max_pos);
|
||||
max_pos = math::clamp(max_pos, lim_pos, lim_max_pos);
|
||||
|
||||
size = max_pos - pos;
|
||||
if (size < 0) {
|
||||
@ -334,13 +336,13 @@ public:
|
||||
|
||||
void merge_with(const Box3i &other) {
|
||||
const Vector3i min_pos( //
|
||||
zylann::math::min(pos.x, other.pos.x), //
|
||||
zylann::math::min(pos.y, other.pos.y), //
|
||||
zylann::math::min(pos.z, other.pos.z));
|
||||
math::min(pos.x, other.pos.x), //
|
||||
math::min(pos.y, other.pos.y), //
|
||||
math::min(pos.z, other.pos.z));
|
||||
const Vector3i max_pos( //
|
||||
zylann::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), //
|
||||
zylann::math::max(pos.z + size.z, other.pos.z + other.size.z));
|
||||
math::max(pos.x + size.x, other.pos.x + other.size.x), //
|
||||
math::max(pos.y + size.y, other.pos.y + other.size.y), //
|
||||
math::max(pos.z + size.z, other.pos.z + other.size.z));
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace zylann
|
||||
|
||||
#endif // BOX3I_H
|
||||
|
@ -268,7 +268,7 @@ _FORCE_INLINE_ int64_t Vector3i::distance_sq(const Vector3i &other) const {
|
||||
|
||||
#else
|
||||
|
||||
namespace Vector3iUtil {
|
||||
namespace zylann::Vector3iUtil {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace Vector3iUtil
|
||||
} // namespace zylann::Vector3iUtil
|
||||
|
||||
inline Vector3i operator<<(const Vector3i &a, int b) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
14
util/span.h
14
util/span.h
@ -4,6 +4,8 @@
|
||||
#include "fixed_array.h"
|
||||
#include <vector>
|
||||
|
||||
namespace zylann {
|
||||
|
||||
// View into an array, referencing a pointer and a size.
|
||||
// STL equivalent would be std::span<T> in C++20
|
||||
template <typename T>
|
||||
@ -38,7 +40,7 @@ public:
|
||||
|
||||
// TODO Remove this one, prefer to_span() specializations
|
||||
template <unsigned int N>
|
||||
inline Span(zylann::FixedArray<T, N> &a) {
|
||||
inline Span(FixedArray<T, N> &a) {
|
||||
_ptr = a.data();
|
||||
_size = a.size();
|
||||
}
|
||||
@ -124,24 +126,24 @@ Span<const T> to_span_const(const std::vector<T> &vec) {
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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());
|
||||
return Span<T>(a.data(), count);
|
||||
}
|
||||
|
||||
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());
|
||||
return Span<const T>(a.data(), count);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -150,4 +152,6 @@ Span<const T> to_span_const(const Span<T> &a) {
|
||||
return Span<const T>(a.data(), 0, a.size());
|
||||
}
|
||||
|
||||
} // namespace zylann
|
||||
|
||||
#endif // SPAN_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user