From 3d54b428631a6fd04ed4e5b40d5bc4a40fd7fc4e Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Wed, 15 May 2024 14:40:17 +0300 Subject: [PATCH] Patching voxel --- Makefile | 2 +- ...enamed-FixedArray-to-VoxelFixedArray.patch | 1449 +++++++++++++++++ 2 files changed, 1450 insertions(+), 1 deletion(-) create mode 100644 src/patches/voxel/0001-Renamed-FixedArray-to-VoxelFixedArray.patch diff --git a/Makefile b/Makefile index 6c22bfb..fe70d33 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ godot-editor-main: patch patch: ./src/godot/scene/animation/skeleton_ik.cpp cd ./src/godot && git reset --hard HEAD && for p in ../patches/*.patch; do git apply $$p; done sed -e 's/ERR_FAIL_COND_V(-1 == p_task->root_bone, false);//g' -i ./src/godot/scene/animation/skeleton_ik.cpp - + cd ./src/modules/voxel && git reset --hard HEAD && for p in ../patches/voxel/*.patch; do git apply $$p; done export: export-models export-clothes rm -Rf godot/.import diff --git a/src/patches/voxel/0001-Renamed-FixedArray-to-VoxelFixedArray.patch b/src/patches/voxel/0001-Renamed-FixedArray-to-VoxelFixedArray.patch new file mode 100644 index 0000000..dbf03e5 --- /dev/null +++ b/src/patches/voxel/0001-Renamed-FixedArray-to-VoxelFixedArray.patch @@ -0,0 +1,1449 @@ +From f74519e4acccebe4f22361da95b5650834c97b4c Mon Sep 17 00:00:00 2001 +From: Sergey Lapin +Date: Wed, 15 May 2024 14:34:26 +0300 +Subject: [PATCH] Renamed FixedArray to VoxelFixedArray + +--- + edition/funcs.h | 12 ++-- + edition/voxel_tool_buffer.cpp | 2 +- + editor/graph/voxel_graph_editor.cpp | 2 +- + .../terrain/voxel_terrain_editor_plugin.cpp | 2 +- + editor/vox/vox_importer.cpp | 2 +- + editor/vox/vox_mesh_importer.cpp | 2 +- + editor/voxel_debug.cpp | 2 +- + generators/graph/image_range_grid.h | 2 +- + generators/graph/voxel_generator_graph.cpp | 24 +++---- + generators/graph/voxel_generator_graph.h | 8 +-- + generators/graph/voxel_graph_node_db.cpp | 2 +- + generators/graph/voxel_graph_node_db.h | 2 +- + generators/graph/voxel_graph_runtime.cpp | 2 +- + generators/graph/voxel_graph_runtime.h | 2 +- + generators/simple/voxel_generator_image.cpp | 2 + + meshers/blocky/voxel.cpp | 6 +- + meshers/blocky/voxel.h | 12 ++-- + meshers/blocky/voxel_mesher_blocky.cpp | 8 +-- + meshers/blocky/voxel_mesher_blocky.h | 2 +- + meshers/cubes/voxel_color_palette.h | 2 +- + meshers/cubes/voxel_mesher_cubes.cpp | 24 +++---- + meshers/cubes/voxel_mesher_cubes.h | 2 +- + meshers/transvoxel/transvoxel.cpp | 72 +++++++++---------- + meshers/transvoxel/transvoxel.h | 10 +-- + meshers/voxel_mesher.h | 2 +- + server/voxel_server.cpp | 2 +- + server/voxel_server.h | 6 +- + server/voxel_thread_pool.h | 2 +- + storage/funcs.h | 12 ++-- + storage/voxel_buffer_internal.cpp | 2 +- + storage/voxel_buffer_internal.h | 10 +-- + storage/voxel_data_map.cpp | 2 +- + storage/voxel_data_map.h | 4 +- + storage/voxel_memory_pool.h | 2 +- + streams/region/region_file.cpp | 2 +- + streams/region/region_file.h | 4 +- + streams/region/voxel_stream_region_files.h | 2 +- + streams/sqlite/voxel_stream_sqlite.cpp | 2 +- + streams/vox_data.h | 4 +- + streams/voxel_stream_block_files.h | 2 +- + streams/voxel_stream_cache.h | 2 +- + .../instancing/voxel_instance_library_item.h | 2 +- + terrain/instancing/voxel_instancer.cpp | 2 +- + terrain/instancing/voxel_instancer.h | 4 +- + terrain/voxel_lod_terrain.cpp | 2 +- + terrain/voxel_lod_terrain.h | 2 +- + terrain/voxel_mesh_block.h | 2 +- + tests/tests.cpp | 10 +-- + util/fixed_array.h | 18 ++--- + util/island_finder.h | 2 +- + util/span.h | 10 +-- + 51 files changed, 162 insertions(+), 160 deletions(-) + +diff --git a/edition/funcs.h b/edition/funcs.h +index 230f3686..2c66b243 100644 +--- a/edition/funcs.h ++++ b/edition/funcs.h +@@ -4,7 +4,7 @@ + #include "../storage/funcs.h" + #include "../util/fixed_array.h" + +-inline void _normalize_weights_preserving(FixedArray &weights, unsigned int preserved_index, ++inline void _normalize_weights_preserving(VoxelFixedArray &weights, unsigned int preserved_index, + unsigned int other0, unsigned int other1, unsigned int other2) { + const float part_sum = weights[other0] + weights[other1] + weights[other2]; + // It is assumed the preserved channel is already clamped to [0, 1] +@@ -23,7 +23,7 @@ inline void _normalize_weights_preserving(FixedArray &weights, unsigne + } + } + +-inline void normalize_weights_preserving(FixedArray &weights, unsigned int preserved_index) { ++inline void normalize_weights_preserving(VoxelFixedArray &weights, unsigned int preserved_index) { + switch (preserved_index) { + case 0: + _normalize_weights_preserving(weights, 0, 1, 2, 3); +@@ -40,7 +40,7 @@ inline void normalize_weights_preserving(FixedArray &weights, unsigned + } + } + +-/*inline void normalize_weights(FixedArray &weights) { ++/*inline void normalize_weights(VoxelFixedArray &weights) { + float sum = 0; + for (unsigned int i = 0; i < weights.size(); ++i) { + sum += weights[i]; +@@ -57,8 +57,8 @@ inline void blend_texture_packed_u16(int texture_index, float target_weight, + ERR_FAIL_COND(target_weight < 0.f || target_weight > 1.f); + #endif + +- FixedArray indices = decode_indices_from_packed_u16(encoded_indices); +- FixedArray weights = decode_weights_from_packed_u16(encoded_weights); ++ VoxelFixedArray indices = decode_indices_from_packed_u16(encoded_indices); ++ VoxelFixedArray weights = decode_weights_from_packed_u16(encoded_weights); + + // Search if our texture index is already present + unsigned int component_index = 4; +@@ -87,7 +87,7 @@ inline void blend_texture_packed_u16(int texture_index, float target_weight, + + // TODO Optimization in case target_weight is 1? + +- FixedArray weights_f; ++ VoxelFixedArray weights_f; + for (unsigned int i = 0; i < weights.size(); ++i) { + weights_f[i] = weights[i] / 255.f; + } +diff --git a/edition/voxel_tool_buffer.cpp b/edition/voxel_tool_buffer.cpp +index 6e796bb4..5419ba64 100644 +--- a/edition/voxel_tool_buffer.cpp ++++ b/edition/voxel_tool_buffer.cpp +@@ -93,7 +93,7 @@ void VoxelToolBuffer::paste(Vector3i p_pos, Ref p_voxels, uint8_t c + } + + unsigned int channel_count; +- FixedArray channels = ++ VoxelFixedArray channels = + VoxelBufferInternal::mask_to_channels_list(channels_mask, channel_count); + + const Vector3i box_max = box.pos + box.size; +diff --git a/editor/graph/voxel_graph_editor.cpp b/editor/graph/voxel_graph_editor.cpp +index 1f52ca2f..7ef66881 100644 +--- a/editor/graph/voxel_graph_editor.cpp ++++ b/editor/graph/voxel_graph_editor.cpp +@@ -207,7 +207,7 @@ VoxelGraphEditor::VoxelGraphEditor() { + add_child(vbox_container); + + _context_menu = memnew(PopupMenu); +- FixedArray category_menus; ++ VoxelFixedArray category_menus; + for (unsigned int i = 0; i < category_menus.size(); ++i) { + String name = VoxelGraphNodeDB::get_category_name(VoxelGraphNodeDB::Category(i)); + PopupMenu *menu = memnew(PopupMenu); +diff --git a/editor/terrain/voxel_terrain_editor_plugin.cpp b/editor/terrain/voxel_terrain_editor_plugin.cpp +index 536a4310..48feb753 100644 +--- a/editor/terrain/voxel_terrain_editor_plugin.cpp ++++ b/editor/terrain/voxel_terrain_editor_plugin.cpp +@@ -153,7 +153,7 @@ private: + Label *label = nullptr; + }; + +- FixedArray _stats; ++ VoxelFixedArray _stats; + }; + + VoxelTerrainEditorPlugin::VoxelTerrainEditorPlugin(EditorNode *p_node) { +diff --git a/editor/vox/vox_importer.cpp b/editor/vox/vox_importer.cpp +index b3f75cc2..da16152e 100644 +--- a/editor/vox/vox_importer.cpp ++++ b/editor/vox/vox_importer.cpp +@@ -263,7 +263,7 @@ Error VoxelVoxImporter::import(const String &p_source_file, const String &p_save + mesher->set_greedy_meshing_enabled(true); + mesher->set_store_colors_in_texture(p_store_colors_in_textures); + +- FixedArray, 2> materials; ++ VoxelFixedArray, 2> materials; + for (unsigned int i = 0; i < materials.size(); ++i) { + Ref &mat = materials[i]; + mat.instance(); +diff --git a/editor/vox/vox_mesh_importer.cpp b/editor/vox/vox_mesh_importer.cpp +index 98fb513a..8b97ec05 100644 +--- a/editor/vox/vox_mesh_importer.cpp ++++ b/editor/vox/vox_mesh_importer.cpp +@@ -310,7 +310,7 @@ Error VoxelVoxMeshImporter::import(const String &p_source_file, const String &p_ + // atlas->save_png(String("debug_atlas{0}.png").format(varray(model_index))); + // } + +- FixedArray, 2> materials; ++ VoxelFixedArray, 2> materials; + for (unsigned int i = 0; i < materials.size(); ++i) { + Ref &mat = materials[i]; + mat.instance(); +diff --git a/editor/voxel_debug.cpp b/editor/voxel_debug.cpp +index 360dfd3e..8469feb6 100644 +--- a/editor/voxel_debug.cpp ++++ b/editor/voxel_debug.cpp +@@ -7,7 +7,7 @@ + + namespace VoxelDebug { + +-FixedArray, ID_COUNT> g_wirecubes; ++VoxelFixedArray, ID_COUNT> g_wirecubes; + bool g_finalized = false; + + template +diff --git a/generators/graph/image_range_grid.h b/generators/graph/image_range_grid.h +index 139a4da0..4aaabd08 100644 +--- a/generators/graph/image_range_grid.h ++++ b/generators/graph/image_range_grid.h +@@ -34,7 +34,7 @@ private: + + Interval _total_range; + +- FixedArray _lods; ++ VoxelFixedArray _lods; + }; + + #endif // IMAGE_RANGE_GRID_H +diff --git a/generators/graph/voxel_generator_graph.cpp b/generators/graph/voxel_generator_graph.cpp +index 17f21a54..fcf7852f 100644 +--- a/generators/graph/voxel_generator_graph.cpp ++++ b/generators/graph/voxel_generator_graph.cpp +@@ -276,14 +276,14 @@ bool VoxelGeneratorGraph::is_using_xz_caching() const { + // The problem is that it's harder to manage at the moment, to support edited blocks and LOD... + void VoxelGeneratorGraph::gather_indices_and_weights(Span weight_outputs, + const VoxelGraphRuntime::State &state, Vector3i rmin, Vector3i rmax, int ry, +- VoxelBufferInternal &out_voxel_buffer, FixedArray spare_indices) { ++ VoxelBufferInternal &out_voxel_buffer, VoxelFixedArray spare_indices) { + VOXEL_PROFILE_SCOPE(); + + // TODO Optimization: exclude up-front outputs that are known to be zero? + // So we choose the cases below based on non-zero outputs instead of total output count + + // TODO Could maybe put this part outside? +- FixedArray, 16> buffers; ++ VoxelFixedArray, 16> buffers; + const unsigned int buffers_count = weight_outputs.size(); + for (unsigned int oi = 0; oi < buffers_count; ++oi) { + const WeightOutput &info = weight_outputs[oi]; +@@ -296,8 +296,8 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span we + unsigned int value_index = 0; + for (int rz = rmin.z; rz < rmax.z; ++rz) { + for (int rx = rmin.x; rx < rmax.x; ++rx) { +- FixedArray weights; +- FixedArray indices = spare_indices; ++ VoxelFixedArray weights; ++ VoxelFixedArray indices = spare_indices; + weights.fill(0); + for (unsigned int oi = 0; oi < buffers_count; ++oi) { + const float weight = buffers[oi][value_index]; +@@ -323,8 +323,8 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span we + unsigned int value_index = 0; + for (int rz = rmin.z; rz < rmax.z; ++rz) { + for (int rx = rmin.x; rx < rmax.x; ++rx) { +- FixedArray weights; +- FixedArray indices; ++ VoxelFixedArray weights; ++ VoxelFixedArray indices; + for (unsigned int oi = 0; oi < buffers_count; ++oi) { + const float weight = buffers[oi][value_index]; + weights[oi] = clamp(weight * 255.f, 0.f, 255.f); +@@ -345,11 +345,11 @@ void VoxelGeneratorGraph::gather_indices_and_weights(Span we + // More weights than we can have per voxel. Will need to pick most represented weights + const float pivot = 1.f / 5.f; + unsigned int value_index = 0; +- FixedArray skipped_outputs; ++ VoxelFixedArray skipped_outputs; + for (int rz = rmin.z; rz < rmax.z; ++rz) { + for (int rx = rmin.x; rx < rmax.x; ++rx) { +- FixedArray weights; +- FixedArray indices; ++ VoxelFixedArray weights; ++ VoxelFixedArray indices; + unsigned int skipped_outputs_count = 0; + indices.fill(0); + weights[0] = 1.f; +@@ -447,7 +447,7 @@ VoxelGenerator::Result VoxelGeneratorGraph::generate_block(VoxelBlockRequest &in + const float air_sdf = _debug_clipped_blocks ? -1.f : 1.f; + const float matter_sdf = _debug_clipped_blocks ? 1.f : -1.f; + +- FixedArray spare_texture_indices = runtime_ptr->spare_texture_indices; ++ VoxelFixedArray spare_texture_indices = runtime_ptr->spare_texture_indices; + const unsigned int sdf_output_buffer_index = runtime_ptr->sdf_output_buffer_index; + + bool all_sdf_is_uniform = true; +@@ -699,8 +699,8 @@ VoxelGraphRuntime::CompilationResult VoxelGeneratorGraph::compile() { + + // Calculate spare indices + { +- FixedArray used_indices_map; +- FixedArray spare_indices; ++ VoxelFixedArray used_indices_map; ++ VoxelFixedArray spare_indices; + used_indices_map.fill(false); + for (unsigned int i = 0; i < r->weight_outputs.size(); ++i) { + used_indices_map[r->weight_outputs[i].layer_index] = true; +diff --git a/generators/graph/voxel_generator_graph.h b/generators/graph/voxel_generator_graph.h +index 18f74a7e..b04a80b1 100644 +--- a/generators/graph/voxel_generator_graph.h ++++ b/generators/graph/voxel_generator_graph.h +@@ -186,7 +186,7 @@ private: + + static void gather_indices_and_weights(Span weight_outputs, + const VoxelGraphRuntime::State &state, Vector3i rmin, Vector3i rmax, int ry, +- VoxelBufferInternal &out_voxel_buffer, FixedArray spare_indices); ++ VoxelBufferInternal &out_voxel_buffer, VoxelFixedArray spare_indices); + + static void _bind_methods(); + +@@ -218,12 +218,12 @@ private: + VoxelGraphRuntime runtime; + // Indices that are not used in the graph. + // This is used when there are less than 4 texture weight outputs. +- FixedArray spare_texture_indices; ++ VoxelFixedArray spare_texture_indices; + // Index to the SDF output + int sdf_output_buffer_index = -1; +- FixedArray weight_outputs; ++ VoxelFixedArray weight_outputs; + // List of indices to feed queries. The order doesn't matter, can be different from `weight_outputs`. +- FixedArray weight_output_indices; ++ VoxelFixedArray weight_output_indices; + unsigned int weight_outputs_count = 0; + }; + +diff --git a/generators/graph/voxel_graph_node_db.cpp b/generators/graph/voxel_graph_node_db.cpp +index ba9f1076..19780028 100644 +--- a/generators/graph/voxel_graph_node_db.cpp ++++ b/generators/graph/voxel_graph_node_db.cpp +@@ -245,7 +245,7 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() { + typedef VoxelGraphRuntime::ProcessBufferContext ProcessBufferContext; + typedef VoxelGraphRuntime::RangeAnalysisContext RangeAnalysisContext; + +- FixedArray &types = _types; ++ VoxelFixedArray &types = _types; + + // TODO Most operations need SIMD support + +diff --git a/generators/graph/voxel_graph_node_db.h b/generators/graph/voxel_graph_node_db.h +index b7c2fbcb..18257254 100644 +--- a/generators/graph/voxel_graph_node_db.h ++++ b/generators/graph/voxel_graph_node_db.h +@@ -82,7 +82,7 @@ public: + bool try_get_input_index_from_name(uint32_t type_id, const String &name, uint32_t &out_input_index) const; + + private: +- FixedArray _types; ++ VoxelFixedArray _types; + HashMap _type_name_to_id; + }; + +diff --git a/generators/graph/voxel_graph_runtime.cpp b/generators/graph/voxel_graph_runtime.cpp +index 61cf89b8..7a5aff73 100644 +--- a/generators/graph/voxel_graph_runtime.cpp ++++ b/generators/graph/voxel_graph_runtime.cpp +@@ -437,7 +437,7 @@ bool VoxelGraphRuntime::is_operation_constant(const State &state, uint16_t op_ad + + void VoxelGraphRuntime::generate_optimized_execution_map(const State &state, ExecutionMap &execution_map, + bool debug) const { +- FixedArray all_outputs; ++ VoxelFixedArray all_outputs; + for (unsigned int i = 0; i < _program.outputs_count; ++i) { + all_outputs[i] = i; + } +diff --git a/generators/graph/voxel_graph_runtime.h b/generators/graph/voxel_graph_runtime.h +index 4c3fa62d..4884a520 100644 +--- a/generators/graph/voxel_graph_runtime.h ++++ b/generators/graph/voxel_graph_runtime.h +@@ -454,7 +454,7 @@ private: + // Address within the State's array of buffers where the Z input may be. + int z_input_address = -1; + +- FixedArray outputs; ++ VoxelFixedArray outputs; + unsigned int outputs_count = 0; + + // Maximum amount of buffers this program will need to do a full run. +diff --git a/generators/simple/voxel_generator_image.cpp b/generators/simple/voxel_generator_image.cpp +index ab0f2cfb..df0b4c13 100644 +--- a/generators/simple/voxel_generator_image.cpp ++++ b/generators/simple/voxel_generator_image.cpp +@@ -75,6 +75,8 @@ VoxelGenerator::Result VoxelGeneratorImage::generate_block(VoxelBlockRequest &in + Result result; + + ERR_FAIL_COND_V(params.image.is_null(), result); ++ ERR_FAIL_COND_V(params.image->get_width() == 0, result); ++ ERR_FAIL_COND_V(params.image->get_height() == 0, result); + const Image &image = **params.image; + + if (params.blur_enabled) { +diff --git a/meshers/blocky/voxel.cpp b/meshers/blocky/voxel.cpp +index d384dbfc..14bd4546 100644 +--- a/meshers/blocky/voxel.cpp ++++ b/meshers/blocky/voxel.cpp +@@ -330,9 +330,9 @@ static void bake_mesh_geometry(Voxel &config, Voxel::BakedData &baked_data, bool + PoolVector2Array::Read uvs_read = uvs.read(); + PoolVector::Read tangents_read = tangents.read(); + +- FixedArray, Cube::SIDE_COUNT> added_side_indices; ++ VoxelFixedArray, Cube::SIDE_COUNT> added_side_indices; + HashMap added_regular_indices; +- FixedArray tri_positions; ++ VoxelFixedArray tri_positions; + + Voxel::BakedData::Model &model = baked_data.model; + +@@ -343,7 +343,7 @@ static void bake_mesh_geometry(Voxel &config, Voxel::BakedData &baked_data, bool + tri_positions[1] = positions_read[indices_read[i + 1]]; + tri_positions[2] = positions_read[indices_read[i + 2]]; + +- FixedArray tangent; ++ VoxelFixedArray tangent; + + if (tangents_empty && bake_tangents) { + //If tangents are empty then we calculate them +diff --git a/meshers/blocky/voxel.h b/meshers/blocky/voxel.h +index 1ae8d664..34528ed7 100644 +--- a/meshers/blocky/voxel.h ++++ b/meshers/blocky/voxel.h +@@ -34,12 +34,12 @@ public: + // Model sides: + // They are separated because this way we can occlude them easily. + // Due to these defining cube side triangles, normals are known already. +- FixedArray, Cube::SIDE_COUNT> side_positions; +- FixedArray, Cube::SIDE_COUNT> side_uvs; +- FixedArray, Cube::SIDE_COUNT> side_indices; +- FixedArray, Cube::SIDE_COUNT> side_tangents; ++ VoxelFixedArray, Cube::SIDE_COUNT> side_positions; ++ VoxelFixedArray, Cube::SIDE_COUNT> side_uvs; ++ VoxelFixedArray, Cube::SIDE_COUNT> side_indices; ++ VoxelFixedArray, Cube::SIDE_COUNT> side_tangents; + +- FixedArray side_pattern_indices; ++ VoxelFixedArray side_pattern_indices; + + void clear() { + positions.clear(); +@@ -168,7 +168,7 @@ private: + + Color _color; + GeometryType _geometry_type; +- FixedArray _cube_tiles; ++ VoxelFixedArray _cube_tiles; + Ref _custom_mesh; + std::vector _collision_aabbs; + bool _random_tickable = false; +diff --git a/meshers/blocky/voxel_mesher_blocky.cpp b/meshers/blocky/voxel_mesher_blocky.cpp +index d00c2e2c..19f34f91 100644 +--- a/meshers/blocky/voxel_mesher_blocky.cpp ++++ b/meshers/blocky/voxel_mesher_blocky.cpp +@@ -51,7 +51,7 @@ inline bool contributes_to_ao(const VoxelLibrary::BakedData &lib, uint32_t voxel + + template + static void generate_blocky_mesh( +- FixedArray &out_arrays_per_material, ++ VoxelFixedArray &out_arrays_per_material, + const Span type_buffer, + const Vector3i block_size, + const VoxelLibrary::BakedData &library, +@@ -72,7 +72,7 @@ static void generate_blocky_mesh( + + int index_offsets[VoxelMesherBlocky::MAX_MATERIALS] = { 0 }; + +- FixedArray side_neighbor_lut; ++ VoxelFixedArray side_neighbor_lut; + side_neighbor_lut[Cube::SIDE_LEFT] = row_size; + side_neighbor_lut[Cube::SIDE_RIGHT] = -row_size; + side_neighbor_lut[Cube::SIDE_BACK] = -deck_size; +@@ -80,7 +80,7 @@ static void generate_blocky_mesh( + side_neighbor_lut[Cube::SIDE_BOTTOM] = -1; + side_neighbor_lut[Cube::SIDE_TOP] = 1; + +- FixedArray edge_neighbor_lut; ++ VoxelFixedArray edge_neighbor_lut; + edge_neighbor_lut[Cube::EDGE_BOTTOM_BACK] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_BACK]; + edge_neighbor_lut[Cube::EDGE_BOTTOM_FRONT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_FRONT]; + edge_neighbor_lut[Cube::EDGE_BOTTOM_LEFT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_LEFT]; +@@ -94,7 +94,7 @@ static void generate_blocky_mesh( + edge_neighbor_lut[Cube::EDGE_TOP_LEFT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_LEFT]; + edge_neighbor_lut[Cube::EDGE_TOP_RIGHT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_RIGHT]; + +- FixedArray corner_neighbor_lut; ++ VoxelFixedArray corner_neighbor_lut; + + corner_neighbor_lut[Cube::CORNER_BOTTOM_BACK_LEFT] = + side_neighbor_lut[Cube::SIDE_BOTTOM] + +diff --git a/meshers/blocky/voxel_mesher_blocky.h b/meshers/blocky/voxel_mesher_blocky.h +index 6b3dfaf4..a8d3d1c3 100644 +--- a/meshers/blocky/voxel_mesher_blocky.h ++++ b/meshers/blocky/voxel_mesher_blocky.h +@@ -68,7 +68,7 @@ private: + }; + + struct Cache { +- FixedArray arrays_per_material; ++ VoxelFixedArray arrays_per_material; + }; + + // Parameters +diff --git a/meshers/cubes/voxel_color_palette.h b/meshers/cubes/voxel_color_palette.h +index c146210f..3932c7fe 100644 +--- a/meshers/cubes/voxel_color_palette.h ++++ b/meshers/cubes/voxel_color_palette.h +@@ -37,7 +37,7 @@ private: + + static void _bind_methods(); + +- FixedArray _colors; ++ VoxelFixedArray _colors; + }; + + #endif // VOXEL_COLOR_PALETTE_H +diff --git a/meshers/cubes/voxel_mesher_cubes.cpp b/meshers/cubes/voxel_mesher_cubes.cpp +index 2fb9fa84..006d4d8e 100644 +--- a/meshers/cubes/voxel_mesher_cubes.cpp ++++ b/meshers/cubes/voxel_mesher_cubes.cpp +@@ -61,7 +61,7 @@ inline uint8_t get_alpha_index(Color8 c) { + + template + void build_voxel_mesh_as_simple_cubes( +- FixedArray &out_arrays_per_material, ++ VoxelFixedArray &out_arrays_per_material, + const Span voxel_buffer, + const Vector3i block_size, + Color_F color_func) { +@@ -76,12 +76,12 @@ void build_voxel_mesh_as_simple_cubes( + const unsigned int deck_size = block_size.x * row_size; + + // Note: voxel buffers are indexed in ZXY order +- FixedArray neighbor_offset_d_lut; ++ VoxelFixedArray neighbor_offset_d_lut; + neighbor_offset_d_lut[Vector3i::AXIS_X] = block_size.y; + neighbor_offset_d_lut[Vector3i::AXIS_Y] = 1; + neighbor_offset_d_lut[Vector3i::AXIS_Z] = block_size.x * block_size.y; + +- FixedArray index_offsets(0); ++ VoxelFixedArray index_offsets(0); + + // For each axis + for (unsigned int za = 0; za < Vector3i::AXIS_COUNT; ++za) { +@@ -93,7 +93,7 @@ void build_voxel_mesh_as_simple_cubes( + // For each cell of the deck, gather face info + for (unsigned int fy = min_pos[ya]; fy < (unsigned int)max_pos[ya]; ++fy) { + for (unsigned int fx = min_pos[xa]; fx < (unsigned int)max_pos[xa]; ++fx) { +- FixedArray pos; ++ VoxelFixedArray pos; + pos[xa] = fx; + pos[ya] = fy; + pos[za] = d; +@@ -194,7 +194,7 @@ void build_voxel_mesh_as_simple_cubes( + + template + void build_voxel_mesh_as_greedy_cubes( +- FixedArray &out_arrays_per_material, ++ VoxelFixedArray &out_arrays_per_material, + const Span voxel_buffer, + const Vector3i block_size, + std::vector &mask_memory_pool, +@@ -223,12 +223,12 @@ void build_voxel_mesh_as_greedy_cubes( + const unsigned int deck_size = block_size.x * row_size; + + // Note: voxel buffers are indexed in ZXY order +- FixedArray neighbor_offset_d_lut; ++ VoxelFixedArray neighbor_offset_d_lut; + neighbor_offset_d_lut[Vector3i::AXIS_X] = block_size.y; + neighbor_offset_d_lut[Vector3i::AXIS_Y] = 1; + neighbor_offset_d_lut[Vector3i::AXIS_Z] = block_size.x * block_size.y; + +- FixedArray index_offsets(0); ++ VoxelFixedArray index_offsets(0); + + // For each axis + for (unsigned int za = 0; za < Vector3i::AXIS_COUNT; ++za) { +@@ -247,7 +247,7 @@ void build_voxel_mesh_as_greedy_cubes( + // For each cell of the deck, gather face info + for (unsigned int fy = min_pos[ya]; fy < (unsigned int)max_pos[ya]; ++fy) { + for (unsigned int fx = min_pos[xa]; fx < (unsigned int)max_pos[xa]; ++fx) { +- FixedArray pos; ++ VoxelFixedArray pos; + pos[xa] = fx; + pos[ya] = fy; + pos[za] = d; +@@ -387,7 +387,7 @@ void build_voxel_mesh_as_greedy_cubes( + + template + void build_voxel_mesh_as_greedy_cubes_atlased( +- FixedArray &out_arrays_per_material, ++ VoxelFixedArray &out_arrays_per_material, + VoxelMesherCubes::GreedyAtlasData &out_greedy_atlas_data, + const Span voxel_buffer, + const Vector3i block_size, +@@ -420,12 +420,12 @@ void build_voxel_mesh_as_greedy_cubes_atlased( + const unsigned int deck_size = block_size.x * row_size; + + // Note: voxel buffers are indexed in ZXY order +- FixedArray neighbor_offset_d_lut; ++ VoxelFixedArray neighbor_offset_d_lut; + neighbor_offset_d_lut[Vector3i::AXIS_X] = block_size.y; + neighbor_offset_d_lut[Vector3i::AXIS_Y] = 1; + neighbor_offset_d_lut[Vector3i::AXIS_Z] = block_size.x * block_size.y; + +- FixedArray index_offsets(0); ++ VoxelFixedArray index_offsets(0); + + // For each axis + for (unsigned int za = 0; za < Vector3i::AXIS_COUNT; ++za) { +@@ -447,7 +447,7 @@ void build_voxel_mesh_as_greedy_cubes_atlased( + // For each cell of the deck, gather face info + for (unsigned int fy = min_pos[ya]; fy < (unsigned int)max_pos[ya]; ++fy) { + for (unsigned int fx = min_pos[xa]; fx < (unsigned int)max_pos[xa]; ++fx) { +- FixedArray pos; ++ VoxelFixedArray pos; + pos[xa] = fx; + pos[ya] = fy; + pos[za] = d; +diff --git a/meshers/cubes/voxel_mesher_cubes.h b/meshers/cubes/voxel_mesher_cubes.h +index 0aa0a0fc..561cf4cb 100644 +--- a/meshers/cubes/voxel_mesher_cubes.h ++++ b/meshers/cubes/voxel_mesher_cubes.h +@@ -102,7 +102,7 @@ private: + }; + + struct Cache { +- FixedArray arrays_per_material; ++ VoxelFixedArray arrays_per_material; + std::vector mask_memory_pool; + GreedyAtlasData greedy_atlas_data; + }; +diff --git a/meshers/transvoxel/transvoxel.cpp b/meshers/transvoxel/transvoxel.cpp +index dada61e6..7955f760 100644 +--- a/meshers/transvoxel/transvoxel.cpp ++++ b/meshers/transvoxel/transvoxel.cpp +@@ -141,12 +141,12 @@ inline Vector3 get_corner_gradient( + return Vector3(nx - px, ny - py, nz - pz); + } + +-inline uint32_t pack_bytes(const FixedArray &a) { ++inline uint32_t pack_bytes(const VoxelFixedArray &a) { + return (a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)); + } + + void add_texture_data(std::vector &uv, unsigned int packed_indices, +- FixedArray weights) { ++ VoxelFixedArray weights) { + struct IntUV { + uint32_t x; + uint32_t y; +@@ -162,12 +162,12 @@ void add_texture_data(std::vector &uv, unsigned int packed_indices, + template + struct CellTextureDatas { + uint32_t packed_indices = 0; +- FixedArray indices; +- FixedArray, NVoxels> weights; ++ VoxelFixedArray indices; ++ VoxelFixedArray, NVoxels> weights; + }; + + template +-CellTextureDatas select_textures(const FixedArray &voxel_indices, ++CellTextureDatas select_textures(const VoxelFixedArray &voxel_indices, + Span indices_data, const WeightSampler_T &weights_sampler) { + // TODO Optimization: this function takes almost half of the time when polygonizing non-empty cells. + // I wonder how it can be optimized further? +@@ -177,8 +177,8 @@ CellTextureDatas select_textures(const FixedArray, NVoxels> cell_texture_weights_temp; +- FixedArray indexed_weight_sums; ++ VoxelFixedArray, NVoxels> cell_texture_weights_temp; ++ VoxelFixedArray indexed_weight_sums; + + // Find 4 most-used indices in voxels + for (unsigned int i = 0; i < indexed_weight_sums.size(); ++i) { +@@ -188,10 +188,10 @@ CellTextureDatas select_textures(const FixedArray indices = decode_indices_from_packed_u16(indices_data[data_index]); +- const FixedArray weights = weights_sampler.get_weights(data_index); ++ const VoxelFixedArray indices = decode_indices_from_packed_u16(indices_data[data_index]); ++ const VoxelFixedArray weights = weights_sampler.get_weights(data_index); + +- FixedArray &weights_temp = cell_texture_weights_temp[ci]; ++ VoxelFixedArray &weights_temp = cell_texture_weights_temp[ci]; + weights_temp.fill(0); + + for (unsigned int j = 0; j < indices.size(); ++j) { +@@ -229,8 +229,8 @@ CellTextureDatas select_textures(const FixedArray &src_weights = cell_texture_weights_temp[ci]; +- FixedArray &dst_weights = cell_textures.weights[ci]; ++ const VoxelFixedArray &src_weights = cell_texture_weights_temp[ci]; ++ VoxelFixedArray &dst_weights = cell_textures.weights[ci]; + + for (unsigned int i = 0; i < cell_textures.indices.size(); ++i) { + const unsigned int ti = cell_textures.indices[i]; +@@ -243,14 +243,14 @@ CellTextureDatas select_textures(const FixedArray buffer; +- FixedArray default_indices; ++ VoxelFixedArray default_indices; + uint32_t packed_default_indices; + }; + + template + inline void get_cell_texture_data(CellTextureDatas &cell_textures, + const TextureIndicesData &texture_indices_data, +- const FixedArray &voxel_indices, ++ const VoxelFixedArray &voxel_indices, + const WeightSampler_T &weights_data) { + if (texture_indices_data.buffer.size() == 0) { + // Indices are known for the whole block, just read weights directly +@@ -356,7 +356,7 @@ void build_regular_mesh( + // |/ |/ |/ + // 0-------1 o--x + +- FixedArray corner_data_indices; ++ VoxelFixedArray corner_data_indices; + corner_data_indices[0] = data_index; + corner_data_indices[1] = data_index + n100; + corner_data_indices[2] = data_index + n010; +@@ -366,7 +366,7 @@ void build_regular_mesh( + corner_data_indices[6] = data_index + n011; + corner_data_indices[7] = data_index + n111; + +- FixedArray cell_samples_sdf; ++ VoxelFixedArray cell_samples_sdf; + for (unsigned int i = 0; i < corner_data_indices.size(); ++i) { + cell_samples_sdf[i] = sdf_as_float(sdf_data[corner_data_indices[i]]); + // TODO Need to investigate if there is a better way to eliminate degenerate triangles. +@@ -407,7 +407,7 @@ void build_regular_mesh( + + CRASH_COND(case_code > 255); + +- FixedArray padded_corner_positions; ++ VoxelFixedArray padded_corner_positions; + padded_corner_positions[0] = Vector3i(pos.x, pos.y, pos.z); + padded_corner_positions[1] = Vector3i(pos.x + 1, pos.y, pos.z); + padded_corner_positions[2] = Vector3i(pos.x, pos.y + 1, pos.z); +@@ -423,7 +423,7 @@ void build_regular_mesh( + current_reuse_cell.packed_texture_indices = cell_textures.packed_indices; + } + +- FixedArray corner_positions; ++ VoxelFixedArray corner_positions; + for (unsigned int i = 0; i < padded_corner_positions.size(); ++i) { + const Vector3i p = padded_corner_positions[i]; + // Undo padding here. From this point, corner positions are actual positions. +@@ -446,7 +446,7 @@ void build_regular_mesh( + const uint8_t triangle_count = regular_cell_data.geometryCounts & 0x0f; + const uint8_t vertex_count = (regular_cell_data.geometryCounts & 0xf0) >> 4; + +- FixedArray cell_vertex_indices(-1); ++ VoxelFixedArray cell_vertex_indices(-1); + + const uint8_t cell_border_mask = get_border_mask(pos - min_pos, block_size - Vector3i(1)); + +@@ -554,9 +554,9 @@ void build_regular_mesh( + output.add_vertex(primaryf, normal, border_mask, secondary); + + if (texturing_mode == TEXTURES_BLEND_4_OVER_16) { +- const FixedArray weights0 = cell_textures.weights[v0]; +- const FixedArray weights1 = cell_textures.weights[v1]; +- FixedArray weights; ++ const VoxelFixedArray weights0 = cell_textures.weights[v0]; ++ const VoxelFixedArray weights1 = cell_textures.weights[v1]; ++ VoxelFixedArray weights; + for (unsigned int i = 0; i < MAX_TEXTURE_BLENDS; ++i) { + weights[i] = static_cast( + clamp(Math::lerp(weights0[i], weights1[i], t1), 0.f, 255.f)); +@@ -593,7 +593,7 @@ void build_regular_mesh( + output.add_vertex(primaryf, normal, border_mask, secondary); + + if (texturing_mode == TEXTURES_BLEND_4_OVER_16) { +- const FixedArray weights1 = cell_textures.weights[v1]; ++ const VoxelFixedArray weights1 = cell_textures.weights[v1]; + add_texture_data(output.uv, cell_textures.packed_indices, weights1); + } + +@@ -642,7 +642,7 @@ void build_regular_mesh( + output.add_vertex(primaryf, normal, border_mask, secondary); + + if (texturing_mode == TEXTURES_BLEND_4_OVER_16) { +- const FixedArray weights = cell_textures.weights[vi]; ++ const VoxelFixedArray weights = cell_textures.weights[vi]; + add_texture_data(output.uv, cell_textures.packed_indices, weights); + } + } +@@ -802,7 +802,7 @@ void build_transition_mesh( + const int fn20 = 2 * fn10; + const int fn02 = 2 * fn01; + +- FixedArray cell_positions; ++ VoxelFixedArray cell_positions; + const int fz = MIN_PADDING; + + const Sdf_T isolevel = get_isolevel(); +@@ -834,7 +834,7 @@ void build_transition_mesh( + } + } + +- FixedArray cell_data_indices; ++ VoxelFixedArray cell_data_indices; + cell_data_indices[0] = data_index; + cell_data_indices[1] = data_index + fn10; + cell_data_indices[2] = data_index + fn20; +@@ -852,7 +852,7 @@ void build_transition_mesh( + // 0---1---2 + + // Full-resolution samples 0..8 +- FixedArray cell_samples; ++ VoxelFixedArray cell_samples; + for (unsigned int i = 0; i < 9; ++i) { + cell_samples[i] = sdf_as_float(sdf_data[cell_data_indices[i]]); + } +@@ -908,7 +908,7 @@ void build_transition_mesh( + CRASH_COND(case_code > 511); + + // TODO We may not need all of them! +- FixedArray cell_gradients; ++ VoxelFixedArray cell_gradients; + for (unsigned int i = 0; i < 9; ++i) { + const unsigned int di = cell_data_indices[i]; + +@@ -951,7 +951,7 @@ void build_transition_mesh( + const bool flip_triangles = ((cell_class & 128) != 0); + + const unsigned int vertex_count = cell_data.GetVertexCount(); +- FixedArray cell_vertex_indices(-1); ++ VoxelFixedArray cell_vertex_indices(-1); + CRASH_COND(vertex_count > cell_vertex_indices.size()); + + const uint8_t direction_validity_mask = (fx > min_fpos_x ? 1 : 0) | ((fy > min_fpos_y ? 1 : 0) << 1); +@@ -1045,9 +1045,9 @@ void build_transition_mesh( + cell_vertex_indices[vertex_index] = output.add_vertex(primaryf, normal, border_mask, secondary); + + if (texturing_mode == TEXTURES_BLEND_4_OVER_16) { +- const FixedArray weights0 = cell_textures.weights[index_vertex_a]; +- const FixedArray weights1 = cell_textures.weights[index_vertex_b]; +- FixedArray weights; ++ const VoxelFixedArray weights0 = cell_textures.weights[index_vertex_a]; ++ const VoxelFixedArray weights1 = cell_textures.weights[index_vertex_b]; ++ VoxelFixedArray weights; + for (unsigned int i = 0; i < cell_textures.indices.size(); ++i) { + weights[i] = static_cast( + clamp(Math::lerp(weights0[i], weights1[i], t1), 0.f, 255.f)); +@@ -1106,7 +1106,7 @@ void build_transition_mesh( + cell_vertex_indices[vertex_index] = output.add_vertex(primaryf, normal, border_mask, secondary); + + if (texturing_mode == TEXTURES_BLEND_4_OVER_16) { +- const FixedArray weights = cell_textures.weights[cell_index]; ++ const VoxelFixedArray weights = cell_textures.weights[cell_index]; + add_texture_data(output.uv, cell_textures.packed_indices, weights); + } + +@@ -1194,8 +1194,8 @@ struct WeightSampler3U8 { + Span u8_data0; + Span u8_data1; + Span u8_data2; +- inline FixedArray get_weights(int i) const { +- FixedArray w; ++ inline VoxelFixedArray get_weights(int i) const { ++ VoxelFixedArray w; + w[0] = u8_data0[i]; + w[1] = u8_data1[i]; + w[2] = u8_data2[i]; +@@ -1211,7 +1211,7 @@ thread_local std::vector s_weights_backing_buffer_u8_2; + #else + struct WeightSamplerPackedU16 { + Span u16_data; +- inline FixedArray get_weights(int i) const { ++ inline VoxelFixedArray get_weights(int i) const { + return decode_weights_from_packed_u16(u16_data[i]); + } + }; +diff --git a/meshers/transvoxel/transvoxel.h b/meshers/transvoxel/transvoxel.h +index 549ee070..fb09166a 100644 +--- a/meshers/transvoxel/transvoxel.h ++++ b/meshers/transvoxel/transvoxel.h +@@ -54,12 +54,12 @@ struct MeshArrays { + }; + + struct ReuseCell { +- FixedArray vertices; ++ VoxelFixedArray vertices; + unsigned int packed_texture_indices = 0; + }; + + struct ReuseTransitionCell { +- FixedArray vertices; ++ VoxelFixedArray vertices; + unsigned int packed_texture_indices = 0; + }; + +@@ -102,14 +102,14 @@ public: + } + + private: +- FixedArray, 2> _cache; +- FixedArray, 2> _cache_2d; ++ VoxelFixedArray, 2> _cache; ++ VoxelFixedArray, 2> _cache_2d; + Vector3i _block_size; + }; + + // This is only to re-use some data computed for regular mesh into transition meshes + struct DefaultTextureIndicesData { +- FixedArray indices; ++ VoxelFixedArray indices; + uint32_t packed_indices; + bool use; + }; +diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h +index e2bcf4a4..dbb40885 100644 +--- a/meshers/voxel_mesher.h ++++ b/meshers/voxel_mesher.h +@@ -19,7 +19,7 @@ public: + struct Output { + // Each surface correspond to a different material + Vector surfaces; +- FixedArray, Cube::SIDE_COUNT> transition_surfaces; ++ VoxelFixedArray, Cube::SIDE_COUNT> transition_surfaces; + Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES; + unsigned int compression_flags = Mesh::ARRAY_COMPRESS_DEFAULT; + Ref atlas_image; +diff --git a/server/voxel_server.cpp b/server/voxel_server.cpp +index cc8ecc19..10910f19 100644 +--- a/server/voxel_server.cpp ++++ b/server/voxel_server.cpp +@@ -1035,7 +1035,7 @@ static void copy_block_and_neighbors(Span> + + // Extract wanted channels in a list + unsigned int channels_count = 0; +- FixedArray channels = ++ VoxelFixedArray channels = + VoxelBufferInternal::mask_to_channels_list(channels_mask, channels_count); + + // Determine size of the cube of blocks +diff --git a/server/voxel_server.h b/server/voxel_server.h +index e36f72bd..c4e1a440 100644 +--- a/server/voxel_server.h ++++ b/server/voxel_server.h +@@ -72,7 +72,7 @@ public: + + struct BlockMeshInput { + // Moore area ordered by forward XYZ iteration +- FixedArray, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST> data_blocks; ++ VoxelFixedArray, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST> data_blocks; + unsigned int data_blocks_count = 0; + Vector3i render_block_position; + uint8_t lod = 0; +@@ -367,9 +367,9 @@ private: + bool is_cancelled() override; + void apply_result() override; + +- FixedArray, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST> blocks; ++ VoxelFixedArray, VoxelConstants::MAX_BLOCK_COUNT_PER_REQUEST> blocks; + // TODO Need to provide format +- //FixedArray channel_depths; ++ //VoxelFixedArray channel_depths; + Vector3i position; // In mesh blocks of the specified lod + uint32_t volume_id; + uint8_t lod; +diff --git a/server/voxel_thread_pool.h b/server/voxel_thread_pool.h +index 47f0785e..73251c7c 100644 +--- a/server/voxel_thread_pool.h ++++ b/server/voxel_thread_pool.h +@@ -128,7 +128,7 @@ private: + void create_thread(ThreadData &d, uint32_t i); + void destroy_all_threads(); + +- FixedArray _threads; ++ VoxelFixedArray _threads; + uint32_t _thread_count = 0; + + // TODO Optimization: use a less naive design? Maybe moodycamel +diff --git a/storage/funcs.h b/storage/funcs.h +index cdf0d078..03a0fc0c 100644 +--- a/storage/funcs.h ++++ b/storage/funcs.h +@@ -129,8 +129,8 @@ static inline uint16_t real_to_quantized_u16(float v) { + return norm_to_u16(v * VoxelConstants::QUANTIZED_SDF_16_BITS_SCALE); + }*/ + +-inline FixedArray decode_weights_from_packed_u16(uint16_t packed_weights) { +- FixedArray weights; ++inline VoxelFixedArray decode_weights_from_packed_u16(uint16_t packed_weights) { ++ VoxelFixedArray weights; + // SIMDable? + // weights[0] = ((packed_weights >> 0) & 0x0f) << 4; + // weights[1] = ((packed_weights >> 4) & 0x0f) << 4; +@@ -153,8 +153,8 @@ inline FixedArray decode_weights_from_packed_u16(uint16_t packed_wei + return weights; + } + +-inline FixedArray decode_indices_from_packed_u16(uint16_t packed_indices) { +- FixedArray indices; ++inline VoxelFixedArray decode_indices_from_packed_u16(uint16_t packed_indices) { ++ VoxelFixedArray indices; + // SIMDable? + indices[0] = (packed_indices >> 0) & 0x0f; + indices[1] = (packed_indices >> 4) & 0x0f; +@@ -172,8 +172,8 @@ inline uint16_t encode_weights_to_packed_u16(uint8_t a, uint8_t b, uint8_t c, ui + } + + // Checks if there are no duplicate indices in any voxel +-inline void debug_check_texture_indices(FixedArray indices) { +- FixedArray checked; ++inline void debug_check_texture_indices(VoxelFixedArray indices) { ++ VoxelFixedArray checked; + checked.fill(false); + for (unsigned int i = 0; i < indices.size(); ++i) { + unsigned int ti = indices[i]; +diff --git a/storage/voxel_buffer_internal.cpp b/storage/voxel_buffer_internal.cpp +index b2061557..2251ebf5 100644 +--- a/storage/voxel_buffer_internal.cpp ++++ b/storage/voxel_buffer_internal.cpp +@@ -201,7 +201,7 @@ void VoxelBufferInternal::clear_channel_f(unsigned int channel_index, real_t cle + clear_channel(channel_index, real_to_raw_voxel(clear_value, channel.depth)); + } + +-void VoxelBufferInternal::set_default_values(FixedArray values) { ++void VoxelBufferInternal::set_default_values(VoxelFixedArray values) { + for (unsigned int i = 0; i < MAX_CHANNELS; ++i) { + _channels[i].defval = clamp_value_for_depth(values[i], _channels[i].depth); + } +diff --git a/storage/voxel_buffer_internal.h b/storage/voxel_buffer_internal.h +index c27a2dbc..deceba0f 100644 +--- a/storage/voxel_buffer_internal.h ++++ b/storage/voxel_buffer_internal.h +@@ -111,7 +111,7 @@ public: + + _FORCE_INLINE_ const Vector3i &get_size() const { return _size; } + +- void set_default_values(FixedArray values); ++ void set_default_values(VoxelFixedArray values); + + uint64_t get_voxel(int x, int y, int z, unsigned int channel_index = 0) const; + void set_voxel(uint64_t value, int x, int y, int z, unsigned int channel_index = 0); +@@ -350,9 +350,9 @@ public: + } + }*/ + +- static inline FixedArray mask_to_channels_list( ++ static inline VoxelFixedArray mask_to_channels_list( + uint8_t channels_mask, unsigned int &out_count) { +- FixedArray channels; ++ VoxelFixedArray channels; + unsigned int channel_count = 0; + + for (unsigned int channel_index = 0; channel_index < VoxelBufferInternal::MAX_CHANNELS; ++channel_index) { +@@ -450,7 +450,7 @@ private: + private: + // Each channel can store arbitary data. + // For example, you can decide to store colors (R, G, B, A), gameplay types (type, state, light) or both. +- FixedArray _channels; ++ VoxelFixedArray _channels; + + // How many voxels are there in the three directions. All populated channels have the same size. + Vector3i _size; +@@ -469,7 +469,7 @@ inline void debug_check_texture_indices_packed_u16(const VoxelBufferInternal &vo + for (int x = 0; x < voxels.get_size().x; ++x) { + for (int y = 0; y < voxels.get_size().y; ++y) { + uint16_t pi = voxels.get_voxel(x, y, z, VoxelBufferInternal::CHANNEL_INDICES); +- FixedArray indices = decode_indices_from_packed_u16(pi); ++ VoxelFixedArray indices = decode_indices_from_packed_u16(pi); + debug_check_texture_indices(indices); + } + } +diff --git a/storage/voxel_data_map.cpp b/storage/voxel_data_map.cpp +index 4f1cae3c..e69fb6a6 100644 +--- a/storage/voxel_data_map.cpp ++++ b/storage/voxel_data_map.cpp +@@ -218,7 +218,7 @@ void VoxelDataMap::copy(Vector3i min_pos, VoxelBufferInternal &dst_buffer, unsig + const Vector3i block_size_v(_block_size, _block_size, _block_size); + + unsigned int channels_count; +- FixedArray channels = ++ VoxelFixedArray channels = + VoxelBufferInternal::mask_to_channels_list(channels_mask, channels_count); + + Vector3i bpos; +diff --git a/storage/voxel_data_map.h b/storage/voxel_data_map.h +index 4cde81c5..056a8c29 100644 +--- a/storage/voxel_data_map.h ++++ b/storage/voxel_data_map.h +@@ -179,7 +179,7 @@ private: + + private: + // Voxel values that will be returned if access is out of map bounds +- FixedArray _default_voxel; ++ VoxelFixedArray _default_voxel; + + // Blocks stored with a spatial hash in all 3D directions. + // Before I used Godot's HashMap with RELATIONSHIP = 2 because that delivers better performance compared to +@@ -211,7 +211,7 @@ struct VoxelDataLodMap { + // It is possible to unlock it after we are done querying the map. + RWLock map_lock; + }; +- FixedArray lods; ++ VoxelFixedArray lods; + unsigned int lod_count = 1; + }; + +diff --git a/storage/voxel_memory_pool.h b/storage/voxel_memory_pool.h +index be114e9e..526c297e 100644 +--- a/storage/voxel_memory_pool.h ++++ b/storage/voxel_memory_pool.h +@@ -89,7 +89,7 @@ private: + // This is chosen based on practical needs. + // Each slot in this array corresponds to allocations + // that contain 2^index bytes in them. +- FixedArray _pot_pools; ++ VoxelFixedArray _pot_pools; + #ifdef DEBUG_ENABLED + DebugUsedBlocks _debug_nonpooled_used_blocks; + #endif +diff --git a/streams/region/region_file.cpp b/streams/region/region_file.cpp +index f76f3e15..6fb0131e 100644 +--- a/streams/region/region_file.cpp ++++ b/streams/region/region_file.cpp +@@ -113,7 +113,7 @@ static bool load_header(FileAccess *f, uint8_t &out_version, VoxelRegionFormat & + ERR_FAIL_COND_V(f->get_position() != 0, false); + ERR_FAIL_COND_V(f->get_len() < MAGIC_AND_VERSION_SIZE, false); + +- FixedArray magic(0); ++ VoxelFixedArray magic(0); + ERR_FAIL_COND_V(f->get_buffer(reinterpret_cast(magic.data()), 4) != 4, false); + ERR_FAIL_COND_V(strcmp(magic.data(), FORMAT_REGION_MAGIC) != 0, false); + +diff --git a/streams/region/region_file.h b/streams/region/region_file.h +index 58faf65e..6b086c1f 100644 +--- a/streams/region/region_file.h ++++ b/streams/region/region_file.h +@@ -22,10 +22,10 @@ struct VoxelRegionFormat { + uint8_t block_size_po2 = 0; + // How many blocks across all dimensions (stored as 3 bytes) + Vector3i region_size; +- FixedArray channel_depths; ++ VoxelFixedArray channel_depths; + // Blocks are stored at offsets multiple of that size + uint32_t sector_size = 0; +- FixedArray palette; ++ VoxelFixedArray palette; + bool has_palette = false; + + bool validate() const; +diff --git a/streams/region/voxel_stream_region_files.h b/streams/region/voxel_stream_region_files.h +index b3dcd26e..4463082e 100644 +--- a/streams/region/voxel_stream_region_files.h ++++ b/streams/region/voxel_stream_region_files.h +@@ -85,7 +85,7 @@ private: + uint8_t lod_count = 0; + uint8_t block_size_po2 = 0; // How many voxels in a cubic block + uint8_t region_size_po2 = 0; // How many blocks in one cubic region +- FixedArray channel_depths; ++ VoxelFixedArray channel_depths; + uint32_t sector_size = 0; // Blocks are stored at offsets multiple of that size + }; + +diff --git a/streams/sqlite/voxel_stream_sqlite.cpp b/streams/sqlite/voxel_stream_sqlite.cpp +index 76bd1518..1dfc4b63 100644 +--- a/streams/sqlite/voxel_stream_sqlite.cpp ++++ b/streams/sqlite/voxel_stream_sqlite.cpp +@@ -58,7 +58,7 @@ public: + bool used = false; + }; + +- FixedArray channels; ++ VoxelFixedArray channels; + }; + + enum BlockType { +diff --git a/streams/vox_data.h b/streams/vox_data.h +index 4d171c5c..8248bc26 100644 +--- a/streams/vox_data.h ++++ b/streams/vox_data.h +@@ -125,7 +125,7 @@ public: + const int get_material_id_for_palette_index(unsigned int palette_index) const; + const Material &get_material_by_id(int id) const; + +- inline const FixedArray &get_palette() const { ++ inline const VoxelFixedArray &get_palette() const { + return _palette; + } + +@@ -138,7 +138,7 @@ private: + // Material IDs are supposedly tied to palette indices + std::unordered_map> _materials; + int _root_node_id = -1; +- FixedArray _palette; ++ VoxelFixedArray _palette; + }; + + } // namespace vox +diff --git a/streams/voxel_stream_block_files.h b/streams/voxel_stream_block_files.h +index f1e05cb8..a6c07b4c 100644 +--- a/streams/voxel_stream_block_files.h ++++ b/streams/voxel_stream_block_files.h +@@ -43,7 +43,7 @@ private: + uint8_t version = -1; + uint8_t lod_count = 0; + uint8_t block_size_po2 = 0; // How many voxels in a block +- FixedArray channel_depths; ++ VoxelFixedArray channel_depths; + }; + + Meta _meta; +diff --git a/streams/voxel_stream_cache.h b/streams/voxel_stream_cache.h +index 7672be12..e2a78b7d 100644 +--- a/streams/voxel_stream_cache.h ++++ b/streams/voxel_stream_cache.h +@@ -60,7 +60,7 @@ private: + RWLock rw_lock; + }; + +- FixedArray _cache; ++ VoxelFixedArray _cache; + unsigned int _count = 0; + }; + +diff --git a/terrain/instancing/voxel_instance_library_item.h b/terrain/instancing/voxel_instance_library_item.h +index ac3c082e..7093ccac 100644 +--- a/terrain/instancing/voxel_instance_library_item.h ++++ b/terrain/instancing/voxel_instance_library_item.h +@@ -59,7 +59,7 @@ private: + void _b_set_mesh_lod2(Ref mesh) { set_mesh(mesh, 2); } + void _b_set_mesh_lod3(Ref mesh) { set_mesh(mesh, 3); } + +- FixedArray, MAX_MESH_LODS> _mesh_lods; ++ VoxelFixedArray, MAX_MESH_LODS> _mesh_lods; + unsigned int _mesh_lod_count = 1; + + // It is preferred to have materials on the mesh already, +diff --git a/terrain/instancing/voxel_instancer.cpp b/terrain/instancing/voxel_instancer.cpp +index 8b2e3dcf..e1076f11 100644 +--- a/terrain/instancing/voxel_instancer.cpp ++++ b/terrain/instancing/voxel_instancer.cpp +@@ -181,7 +181,7 @@ void VoxelInstancer::process_mesh_lods() { + { + const int block_region_extent = _parent->get_mesh_block_region_extent(); + +- FixedArray coeffs; ++ VoxelFixedArray coeffs; + coeffs[0] = 0; + coeffs[1] = 0.1; + coeffs[2] = 0.25; +diff --git a/terrain/instancing/voxel_instancer.h b/terrain/instancing/voxel_instancer.h +index 17ae70a2..5ba2e574 100644 +--- a/terrain/instancing/voxel_instancer.h ++++ b/terrain/instancing/voxel_instancer.h +@@ -172,7 +172,7 @@ private: + // Can't use `HashMap` because it lacks move semantics. + std::unordered_map> loaded_instances_data; + +- FixedArray mesh_lod_distances; ++ VoxelFixedArray mesh_lod_distances; + + Lod() = default; + Lod(const Lod &) = delete; // non construction-copyable +@@ -181,7 +181,7 @@ private: + + UpMode _up_mode = UP_MODE_POSITIVE_Y; + +- FixedArray _lods; ++ VoxelFixedArray _lods; + std::vector _blocks; // Does not have nulls + HashMap _layers; // Each layer corresponds to a library item + Ref _library; +diff --git a/terrain/voxel_lod_terrain.cpp b/terrain/voxel_lod_terrain.cpp +index 83e45281..8cc973b3 100644 +--- a/terrain/voxel_lod_terrain.cpp ++++ b/terrain/voxel_lod_terrain.cpp +@@ -1231,7 +1231,7 @@ bool VoxelLodTerrain::check_block_mesh_updated(VoxelMeshBlock *block, std::vecto + const Vector3i data_block_pos0 = factor * block->position; + const Box3i data_box(data_block_pos0 - Vector3i(1), Vector3i(factor) + Vector3i(2)); + const Box3i bounds = _bounds_in_voxels.downscaled(data_block_size); +- FixedArray neighbor_positions; ++ VoxelFixedArray neighbor_positions; + unsigned int neighbor_positions_count = 0; + data_box.for_inner_outline([bounds, &neighbor_positions, &neighbor_positions_count](Vector3i pos) { + if (bounds.contains(pos)) { +diff --git a/terrain/voxel_lod_terrain.h b/terrain/voxel_lod_terrain.h +index ee0d98d9..860b0dc0 100644 +--- a/terrain/voxel_lod_terrain.h ++++ b/terrain/voxel_lod_terrain.h +@@ -372,7 +372,7 @@ private: + } + }; + +- FixedArray _lods; ++ VoxelFixedArray _lods; + unsigned int _lod_count = 0; + // Distance between a viewer and the end of LOD0 + float _lod_distance = 0.f; +diff --git a/terrain/voxel_mesh_block.h b/terrain/voxel_mesh_block.h +index 993f850a..84493718 100644 +--- a/terrain/voxel_mesh_block.h ++++ b/terrain/voxel_mesh_block.h +@@ -123,7 +123,7 @@ private: + + Ref _shader_material; + DirectMeshInstance _mesh_instance; +- FixedArray _transition_mesh_instances; ++ VoxelFixedArray _transition_mesh_instances; + DirectStaticBody _static_body; + Ref _world; + +diff --git a/tests/tests.cpp b/tests/tests.cpp +index 1ce71d8a..312c887e 100644 +--- a/tests/tests.cpp ++++ b/tests/tests.cpp +@@ -224,7 +224,7 @@ void test_voxel_data_map_copy() { + } + + void test_encode_weights_packed_u16() { +- FixedArray weights; ++ VoxelFixedArray weights; + // There is data loss of the 4 smaller bits in this encoding, + // so to test this we may use values greater than 16. + // There is a compromise in decoding, where we choose that only values multiple of 16 are bijective. +@@ -233,7 +233,7 @@ void test_encode_weights_packed_u16() { + weights[2] = 10 << 4; + weights[3] = 15 << 4; + const uint16_t encoded_weights = encode_weights_to_packed_u16(weights[0], weights[1], weights[2], weights[3]); +- FixedArray decoded_weights = decode_weights_from_packed_u16(encoded_weights); ++ VoxelFixedArray decoded_weights = decode_weights_from_packed_u16(encoded_weights); + ERR_FAIL_COND(weights != decoded_weights); + } + +@@ -448,8 +448,8 @@ void test_voxel_graph_generator_texturing() { + bool weight0_must_be_1, bool weight1_must_be_1) { + const uint16_t encoded_indices = buffer.get_voxel(pos, VoxelBufferInternal::CHANNEL_INDICES); + const uint16_t encoded_weights = buffer.get_voxel(pos, VoxelBufferInternal::CHANNEL_WEIGHTS); +- const FixedArray indices = decode_indices_from_packed_u16(encoded_indices); +- const FixedArray weights = decode_weights_from_packed_u16(encoded_weights); ++ const VoxelFixedArray indices = decode_indices_from_packed_u16(encoded_indices); ++ const VoxelFixedArray weights = decode_weights_from_packed_u16(encoded_weights); + for (unsigned int i = 0; i < indices.size(); ++i) { + switch (indices[i]) { + case 0: +@@ -819,7 +819,7 @@ void test_transform_3d_array_zxy() { + const Vector3i src_size(3, 4, 2); + const int volume = src_size.volume(); + +- FixedArray dst_grid; ++ VoxelFixedArray dst_grid; + ERR_FAIL_COND(dst_grid.size() != volume); + + { +diff --git a/util/fixed_array.h b/util/fixed_array.h +index bbaefa70..787aebab 100644 +--- a/util/fixed_array.h ++++ b/util/fixed_array.h +@@ -1,16 +1,16 @@ +-#ifndef FIXED_ARRAY_H +-#define FIXED_ARRAY_H ++#ifndef FIXED_ARRAY_H_ ++#define FIXED_ARRAY_H_ + + #include + + // TODO Could use std::array, but due to how Godot compiles, + // I couldn't find a way to enable boundary checks without failing to link my module with the rest of Godot... + template +-class FixedArray { ++class VoxelFixedArray { + public: +- inline FixedArray() {} ++ inline VoxelFixedArray() {} + +- inline FixedArray(T defval) { ++ inline VoxelFixedArray(T defval) { + fill(defval); + } + +@@ -36,7 +36,7 @@ public: + return _data[i]; + } + +- inline bool equals(const FixedArray &other) const { ++ inline bool equals(const VoxelFixedArray &other) const { + for (unsigned int i = 0; i < N; ++i) { + if (_data[i] != other._data[i]) { + return false; +@@ -45,15 +45,15 @@ public: + return true; + } + +- inline bool operator==(const FixedArray &other) const { ++ inline bool operator==(const VoxelFixedArray &other) const { + return equals(other); + } + +- inline bool operator!=(const FixedArray &other) const { ++ inline bool operator!=(const VoxelFixedArray &other) const { + return !equals(other); + } + +- inline void operator=(const FixedArray &other) { ++ inline void operator=(const VoxelFixedArray &other) { + for (unsigned int i = 0; i < N; ++i) { + _data[i] = other._data[i]; + } +diff --git a/util/island_finder.h b/util/island_finder.h +index af1bbe2d..7fa07b32 100644 +--- a/util/island_finder.h ++++ b/util/island_finder.h +@@ -201,7 +201,7 @@ private: + } + + private: +- FixedArray _equivalences; ++ VoxelFixedArray _equivalences; + }; + + #endif // ISLAND_FINDER_H +diff --git a/util/span.h b/util/span.h +index 44d4df39..418eef58 100644 +--- a/util/span.h ++++ b/util/span.h +@@ -43,7 +43,7 @@ public: + + // TODO Remove this one, prefer to_span() specializations + template +- inline Span(FixedArray &a) { ++ inline Span(VoxelFixedArray &a) { + _ptr = a.data(); + _size = a.size(); + } +@@ -129,24 +129,24 @@ Span to_span_const(const std::vector &vec) { + } + + template +-Span to_span(FixedArray &a) { ++Span to_span(VoxelFixedArray &a) { + return Span(a.data(), a.size()); + } + + template +-Span to_span(FixedArray &a, unsigned int count) { ++Span to_span(VoxelFixedArray &a, unsigned int count) { + CRASH_COND(count > a.size()); + return Span(a.data(), count); + } + + template +-Span to_span_const(const FixedArray &a, unsigned int count) { ++Span to_span_const(const VoxelFixedArray &a, unsigned int count) { + CRASH_COND(count > a.size()); + return Span(a.data(), count); + } + + template +-Span to_span_const(const FixedArray &a) { ++Span to_span_const(const VoxelFixedArray &a) { + return Span(a.data(), 0, a.size()); + } + +-- +2.34.1 +