Use STL containers

This commit is contained in:
Marc Gilleron 2022-04-14 22:32:34 +01:00
parent bfa24402ac
commit 9fef29442f
2 changed files with 105 additions and 109 deletions

View File

@ -56,9 +56,9 @@ void VoxelInstancer::clear_blocks() {
} }
_blocks.clear(); _blocks.clear();
const int *key = nullptr; const int *key = nullptr;
while ((key = _layers.next(key))) { for (auto it = _layers.begin(); it != _layers.end(); ++it) {
Layer *layer = get_layer(*key); Layer &layer = it->second;
layer->blocks.clear(); layer.blocks.clear();
} }
for (unsigned int lod_index = 0; lod_index < _lods.size(); ++lod_index) { for (unsigned int lod_index = 0; lod_index < _lods.size(); ++lod_index) {
Lod &lod = _lods[lod_index]; Lod &lod = _lods[lod_index];
@ -242,16 +242,16 @@ void VoxelInstancer::process_gizmos() {
#endif #endif
VoxelInstancer::Layer *VoxelInstancer::get_layer(int id) { VoxelInstancer::Layer &VoxelInstancer::get_layer(int id) {
Layer *ptr = _layers.getptr(id); auto it = _layers.find(id);
CRASH_COND(ptr == nullptr); ZN_ASSERT(it != _layers.end());
return ptr; return it->second;
} }
const VoxelInstancer::Layer *VoxelInstancer::get_layer_const(int id) const { const VoxelInstancer::Layer &VoxelInstancer::get_layer_const(int id) const {
const Layer *ptr = _layers.getptr(id); auto it = _layers.find(id);
CRASH_COND(ptr == nullptr); ZN_ASSERT(it != _layers.end());
return ptr; return it->second;
} }
void VoxelInstancer::process_mesh_lods() { void VoxelInstancer::process_mesh_lods() {
@ -378,8 +378,8 @@ void VoxelInstancer::set_up_mode(UpMode mode) {
} }
_up_mode = mode; _up_mode = mode;
const int *key = nullptr; const int *key = nullptr;
while ((key = _layers.next(key))) { for (auto it = _layers.begin(); it != _layers.end(); ++it) {
regenerate_layer(*key, false); regenerate_layer(it->first, false);
} }
} }
@ -424,10 +424,9 @@ void VoxelInstancer::regenerate_layer(uint16_t layer_id, bool regenerate_blocks)
Ref<World3D> world_ref = get_world_3d(); Ref<World3D> world_ref = get_world_3d();
ERR_FAIL_COND(world_ref.is_null()); ERR_FAIL_COND(world_ref.is_null());
World3D *world = *world_ref; World3D &world = **world_ref;
Layer *layer = get_layer(layer_id); Layer &layer = get_layer(layer_id);
CRASH_COND(layer == nullptr);
Ref<VoxelInstanceLibraryItem> item = _library->get_item(layer_id); Ref<VoxelInstanceLibraryItem> item = _library->get_item(layer_id);
ERR_FAIL_COND(item.is_null()); ERR_FAIL_COND(item.is_null());
@ -445,7 +444,7 @@ void VoxelInstancer::regenerate_layer(uint16_t layer_id, bool regenerate_blocks)
std::vector<Vector3i> positions; std::vector<Vector3i> positions;
if (parent_vlt != nullptr) { if (parent_vlt != nullptr) {
parent_vlt->get_meshed_block_positions_at_lod(layer->lod_index, positions); parent_vlt->get_meshed_block_positions_at_lod(layer.lod_index, positions);
} else if (parent_vt != nullptr) { } else if (parent_vt != nullptr) {
parent_vt->get_meshed_block_positions(positions); parent_vt->get_meshed_block_positions(positions);
} }
@ -453,8 +452,8 @@ void VoxelInstancer::regenerate_layer(uint16_t layer_id, bool regenerate_blocks)
for (unsigned int i = 0; i < positions.size(); ++i) { for (unsigned int i = 0; i < positions.size(); ++i) {
const Vector3i pos = positions[i]; const Vector3i pos = positions[i];
const unsigned int *iptr = layer->blocks.getptr(pos); auto it = layer.blocks.find(pos);
if (iptr != nullptr) { if (it != layer.blocks.end()) {
continue; continue;
} }
@ -469,7 +468,7 @@ void VoxelInstancer::regenerate_layer(uint16_t layer_id, bool regenerate_blocks)
// Does not return a bool so it can be used in bit-shifting operations without a compiler warning. // Does not return a bool so it can be used in bit-shifting operations without a compiler warning.
// Can be treated like a bool too. // Can be treated like a bool too.
static inline uint8_t has_edited_block(const Lod &lod, Vector3i pos) { static inline uint8_t has_edited_block(const Lod &lod, Vector3i pos) {
return lod.modified_blocks.has(pos) || return lod.modified_blocks.find(pos) != lod.modified_blocks.end() ||
lod.loaded_instances_data.find(pos) != lod.loaded_instances_data.end(); lod.loaded_instances_data.find(pos) != lod.loaded_instances_data.end();
} }
@ -554,7 +553,7 @@ void VoxelInstancer::regenerate_layer(uint16_t layer_id, bool regenerate_blocks)
// We may setup a local transform list as well since it's expensive to get it from VisualServer // We may setup a local transform list as well since it's expensive to get it from VisualServer
} }
update_block_from_transforms(block_index, to_span_const(_transform_cache), block->grid_position, layer, *item, update_block_from_transforms(block_index, to_span_const(_transform_cache), block->grid_position, layer, **item,
layer_id, world, block_transform); layer_id, world, block_transform);
} }
} }
@ -647,15 +646,14 @@ void VoxelInstancer::on_library_item_changed(int item_id, VoxelInstanceLibraryIt
clear_blocks_in_layer(item_id); clear_blocks_in_layer(item_id);
Layer *layer = get_layer(item_id); Layer &layer = get_layer(item_id);
CRASH_COND(layer == nullptr);
Lod &prev_lod = _lods[layer->lod_index]; Lod &prev_lod = _lods[layer.lod_index];
unordered_remove_value(prev_lod.layers, item_id); unordered_remove_value(prev_lod.layers, item_id);
layer->lod_index = item->get_lod_index(); layer.lod_index = item->get_lod_index();
Lod &new_lod = _lods[layer->lod_index]; Lod &new_lod = _lods[layer.lod_index];
new_lod.layers.push_back(item_id); new_lod.layers.push_back(item_id);
regenerate_layer(item_id, true); regenerate_layer(item_id, true);
@ -670,7 +668,7 @@ void VoxelInstancer::on_library_item_changed(int item_id, VoxelInstanceLibraryIt
void VoxelInstancer::add_layer(int layer_id, int lod_index) { void VoxelInstancer::add_layer(int layer_id, int lod_index) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
ERR_FAIL_COND(lod_index < 0 || lod_index >= MAX_LOD); ERR_FAIL_COND(lod_index < 0 || lod_index >= MAX_LOD);
ERR_FAIL_COND(_layers.has(layer_id)); ERR_FAIL_COND_MSG(_layers.find(layer_id) != _layers.end(), "Trying to add a layer that already exists");
#endif #endif
Lod &lod = _lods[lod_index]; Lod &lod = _lods[lod_index];
@ -682,16 +680,16 @@ void VoxelInstancer::add_layer(int layer_id, int lod_index) {
Layer layer; Layer layer;
layer.lod_index = lod_index; layer.lod_index = lod_index;
_layers.set(layer_id, layer); _layers.insert({ layer_id, layer });
lod.layers.push_back(layer_id); lod.layers.push_back(layer_id);
} }
void VoxelInstancer::remove_layer(int layer_id) { void VoxelInstancer::remove_layer(int layer_id) {
Layer *layer = get_layer(layer_id); Layer &layer = get_layer(layer_id);
// Unregister that layer from the corresponding LOD structure // Unregister that layer from the corresponding LOD structure
Lod &lod = _lods[layer->lod_index]; Lod &lod = _lods[layer.lod_index];
for (size_t i = 0; i < lod.layers.size(); ++i) { for (size_t i = 0; i < lod.layers.size(); ++i) {
if (lod.layers[i] == layer_id) { if (lod.layers[i] == layer_id) {
lod.layers[i] = lod.layers.back(); lod.layers[i] = lod.layers.back();
@ -712,8 +710,8 @@ void VoxelInstancer::remove_block(unsigned int block_index) {
Block *moved_block = _blocks.back(); Block *moved_block = _blocks.back();
Block *block = _blocks[block_index]; Block *block = _blocks[block_index];
{ {
Layer *layer = get_layer(block->layer_id); Layer &layer = get_layer(block->layer_id);
layer->blocks.erase(block->grid_position); layer.blocks.erase(block->grid_position);
} }
_blocks[block_index] = moved_block; _blocks[block_index] = moved_block;
_blocks.pop_back(); _blocks.pop_back();
@ -734,10 +732,10 @@ void VoxelInstancer::remove_block(unsigned int block_index) {
memdelete(block); memdelete(block);
if (block != moved_block) { if (block != moved_block) {
Layer *layer = get_layer(moved_block->layer_id); Layer &layer = get_layer(moved_block->layer_id);
unsigned int *iptr = layer->blocks.getptr(moved_block->grid_position); auto it = layer.blocks.find(moved_block->grid_position);
CRASH_COND(iptr == nullptr); CRASH_COND(it == layer.blocks.end());
*iptr = block_index; it->second = block_index;
} }
} }
@ -776,24 +774,24 @@ void VoxelInstancer::on_mesh_block_exit(Vector3i render_grid_position, unsigned
// If we loaded data there but it was never used, we'll unload it either way // If we loaded data there but it was never used, we'll unload it either way
lod.loaded_instances_data.erase(data_grid_pos); lod.loaded_instances_data.erase(data_grid_pos);
if (lod.modified_blocks.has(data_grid_pos)) { auto modified_block_it = lod.modified_blocks.find(data_grid_pos);
if (modified_block_it != lod.modified_blocks.end()) {
save_block(data_grid_pos, lod_index); save_block(data_grid_pos, lod_index);
lod.modified_blocks.erase(data_grid_pos); lod.modified_blocks.erase(modified_block_it);
} }
} }
} }
} }
// Remove render blocks // Remove render blocks
for (auto it = lod.layers.begin(); it != lod.layers.end(); ++it) { for (auto layer_it = lod.layers.begin(); layer_it != lod.layers.end(); ++layer_it) {
const int layer_id = *it; const int layer_id = *layer_it;
Layer *layer = get_layer(layer_id); Layer &layer = get_layer(layer_id);
CRASH_COND(layer == nullptr);
const unsigned int *block_index_ptr = layer->blocks.getptr(render_grid_position); auto block_it = layer.blocks.find(render_grid_position);
if (block_index_ptr != nullptr) { if (block_it != layer.blocks.end()) {
remove_block(*block_index_ptr); remove_block(block_it->second);
} }
} }
} }
@ -802,8 +800,8 @@ void VoxelInstancer::save_all_modified_blocks() {
for (unsigned int lod_index = 0; lod_index < _lods.size(); ++lod_index) { for (unsigned int lod_index = 0; lod_index < _lods.size(); ++lod_index) {
Lod &lod = _lods[lod_index]; Lod &lod = _lods[lod_index];
const Vector3i *key = nullptr; const Vector3i *key = nullptr;
while ((key = lod.modified_blocks.next(key))) { for (auto it = lod.modified_blocks.begin(); it != lod.modified_blocks.end(); ++it) {
save_block(*key, lod_index); save_block(*it, lod_index);
} }
lod.modified_blocks.clear(); lod.modified_blocks.clear();
} }
@ -837,29 +835,26 @@ VoxelInstancer::SceneInstance VoxelInstancer::create_scene_instance(const VoxelI
return instance; return instance;
} }
int VoxelInstancer::create_block(Layer *layer, uint16_t layer_id, Vector3i grid_position) { int VoxelInstancer::create_block(Layer &layer, uint16_t layer_id, Vector3i grid_position) {
Block *block = memnew(Block); Block *block = memnew(Block);
block->layer_id = layer_id; block->layer_id = layer_id;
block->current_mesh_lod = 0; block->current_mesh_lod = 0;
block->lod_index = layer->lod_index; block->lod_index = layer.lod_index;
block->grid_position = grid_position; block->grid_position = grid_position;
int block_index = _blocks.size(); int block_index = _blocks.size();
_blocks.push_back(block); _blocks.push_back(block);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
CRASH_COND(layer->blocks.has(grid_position)); CRASH_COND(layer.blocks.find(grid_position) != layer.blocks.end());
#endif #endif
layer->blocks.set(grid_position, block_index); layer.blocks.insert({ grid_position, block_index });
return block_index; return block_index;
} }
void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Transform3D> transforms, void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Transform3D> transforms,
Vector3i grid_position, Layer *layer, const VoxelInstanceLibraryItem *item_base, uint16_t layer_id, Vector3i grid_position, Layer &layer, const VoxelInstanceLibraryItem &item_base, uint16_t layer_id,
World3D *world, const Transform3D &block_transform) { World3D &world, const Transform3D &block_transform) {
ZN_PROFILE_SCOPE(); ZN_PROFILE_SCOPE();
CRASH_COND(layer == nullptr);
CRASH_COND(item_base == nullptr);
// Get or create block // Get or create block
Block *block = nullptr; Block *block = nullptr;
if (block_index != -1) { if (block_index != -1) {
@ -870,7 +865,7 @@ void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Tr
} }
// Update multimesh // Update multimesh
const VoxelInstanceLibraryMultiMeshItem *item = Object::cast_to<VoxelInstanceLibraryMultiMeshItem>(item_base); const VoxelInstanceLibraryMultiMeshItem *item = Object::cast_to<VoxelInstanceLibraryMultiMeshItem>(&item_base);
if (item != nullptr) { if (item != nullptr) {
if (transforms.size() == 0) { if (transforms.size() == 0) {
if (block->multimesh_instance.is_valid()) { if (block->multimesh_instance.is_valid()) {
@ -904,7 +899,7 @@ void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Tr
block->multimesh_instance.set_visible(is_visible()); block->multimesh_instance.set_visible(is_visible());
} }
block->multimesh_instance.set_multimesh(multimesh); block->multimesh_instance.set_multimesh(multimesh);
block->multimesh_instance.set_world(world); block->multimesh_instance.set_world(&world);
block->multimesh_instance.set_transform(block_transform); block->multimesh_instance.set_transform(block_transform);
block->multimesh_instance.set_material_override(item->get_material_override()); block->multimesh_instance.set_material_override(item->get_material_override());
block->multimesh_instance.set_cast_shadows_setting(item->get_cast_shadows_setting()); block->multimesh_instance.set_cast_shadows_setting(item->get_cast_shadows_setting());
@ -963,7 +958,7 @@ void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Tr
} }
// Update scene instances // Update scene instances
const VoxelInstanceLibrarySceneItem *scene_item = Object::cast_to<VoxelInstanceLibrarySceneItem>(item_base); const VoxelInstanceLibrarySceneItem *scene_item = Object::cast_to<VoxelInstanceLibrarySceneItem>(&item_base);
if (scene_item != nullptr) { if (scene_item != nullptr) {
ZN_PROFILE_SCOPE_NAMED("Update scene instances"); ZN_PROFILE_SCOPE_NAMED("Update scene instances");
ERR_FAIL_COND(scene_item->get_scene().is_null()); ERR_FAIL_COND(scene_item->get_scene().is_null());
@ -1023,9 +1018,9 @@ void VoxelInstancer::create_render_blocks(Vector3i render_grid_position, int lod
Lod &lod = _lods[lod_index]; Lod &lod = _lods[lod_index];
const Transform3D parent_transform = get_global_transform(); const Transform3D parent_transform = get_global_transform();
Ref<World3D> world_ref = get_world_3d(); Ref<World3D> maybe_world = get_world_3d();
ERR_FAIL_COND(world_ref.is_null()); ERR_FAIL_COND(maybe_world.is_null());
World3D *world = *world_ref; World3D &world = **maybe_world;
const int mesh_block_size = (1 << _parent_mesh_block_size_po2); const int mesh_block_size = (1 << _parent_mesh_block_size_po2);
const int lod_block_size = mesh_block_size << lod_index; const int lod_block_size = mesh_block_size << lod_index;
@ -1041,11 +1036,9 @@ void VoxelInstancer::create_render_blocks(Vector3i render_grid_position, int lod
for (auto layer_it = lod.layers.begin(); layer_it != lod.layers.end(); ++layer_it) { for (auto layer_it = lod.layers.begin(); layer_it != lod.layers.end(); ++layer_it) {
const int layer_id = *layer_it; const int layer_id = *layer_it;
Layer *layer = get_layer(layer_id); Layer &layer = get_layer(layer_id);
CRASH_COND(layer == nullptr);
const unsigned int *render_block_index_ptr = layer->blocks.getptr(render_grid_position); if (layer.blocks.find(render_grid_position) != layer.blocks.end()) {
if (render_block_index_ptr != nullptr) {
// The block was already made? // The block was already made?
continue; continue;
} }
@ -1114,7 +1107,7 @@ void VoxelInstancer::create_render_blocks(Vector3i render_grid_position, int lod
} }
} }
update_block_from_transforms(-1, to_span_const(_transform_cache), render_grid_position, layer, item, layer_id, update_block_from_transforms(-1, to_span_const(_transform_cache), render_grid_position, layer, *item, layer_id,
world, block_transform); world, block_transform);
} }
} }
@ -1149,17 +1142,16 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
continue; continue;
} }
const Layer *layer = get_layer_const(layer_id); const Layer &layer = get_layer_const(layer_id);
CRASH_COND(layer == nullptr);
ERR_FAIL_COND(layer_id < 0); ERR_FAIL_COND(layer_id < 0);
const unsigned int *render_block_index_ptr = layer->blocks.getptr(render_block_pos); const auto render_block_it = layer.blocks.find(render_block_pos);
if (render_block_index_ptr == nullptr) { if (render_block_it == layer.blocks.end()) {
continue; continue;
} }
const unsigned int render_block_index = *render_block_index_ptr; const unsigned int render_block_index = render_block_it->second;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
CRASH_COND(render_block_index >= _blocks.size()); CRASH_COND(render_block_index >= _blocks.size());
@ -1423,20 +1415,20 @@ void VoxelInstancer::on_area_edited(Box3i p_voxel_box) {
const Box3i render_blocks_box = p_voxel_box.downscaled(render_block_size << lod_index); const Box3i render_blocks_box = p_voxel_box.downscaled(render_block_size << lod_index);
const Box3i data_blocks_box = p_voxel_box.downscaled(data_block_size << lod_index); const Box3i data_blocks_box = p_voxel_box.downscaled(data_block_size << lod_index);
for (auto it = lod.layers.begin(); it != lod.layers.end(); ++it) { for (auto layer_it = lod.layers.begin(); layer_it != lod.layers.end(); ++layer_it) {
const Layer *layer = get_layer(*it); const Layer &layer = get_layer(*layer_it);
const std::vector<Block *> &blocks = _blocks; const std::vector<Block *> &blocks = _blocks;
const int block_size_po2 = base_block_size_po2 + layer->lod_index; const int block_size_po2 = base_block_size_po2 + layer.lod_index;
render_blocks_box.for_each_cell([layer, &blocks, voxel_tool, p_voxel_box, parent_transform, block_size_po2, render_blocks_box.for_each_cell([layer, &blocks, voxel_tool, p_voxel_box, parent_transform, block_size_po2,
&lod, data_blocks_box](Vector3i block_pos) { &lod, data_blocks_box](Vector3i block_pos) {
const unsigned int *iptr = layer->blocks.getptr(block_pos); const auto block_it = layer.blocks.find(block_pos);
if (iptr == nullptr) { if (block_it == layer.blocks.end()) {
// No instancing block here // No instancing block here
return; return;
} }
Block *block = blocks[*iptr]; Block *block = blocks[block_it->second];
ERR_FAIL_COND(block == nullptr); ERR_FAIL_COND(block == nullptr);
if (block->scene_instances.size() > 0) { if (block->scene_instances.size() > 0) {
@ -1450,8 +1442,9 @@ void VoxelInstancer::on_area_edited(Box3i p_voxel_box) {
// All instances have to be frozen as edited. // All instances have to be frozen as edited.
// Because even if none of them were removed or added, the ground on which they can spawn has changed, // Because even if none of them were removed or added, the ground on which they can spawn has changed,
// and at the moment we don't want unexpected instances to generate when loading back this area. // and at the moment we don't want unexpected instances to generate when loading back this area.
data_blocks_box.for_each_cell( data_blocks_box.for_each_cell([&lod](Vector3i data_block_pos) { //
[&lod](Vector3i data_block_pos) { lod.modified_blocks.set(data_block_pos, true); }); lod.modified_blocks.insert(data_block_pos);
});
}); });
} }
} }
@ -1491,10 +1484,9 @@ void VoxelInstancer::on_body_removed(
block->bodies.resize(body_count); block->bodies.resize(body_count);
// Mark data block as modified // Mark data block as modified
const Layer *layer = get_layer(block->layer_id); const Layer &layer = get_layer(block->layer_id);
CRASH_COND(layer == nullptr); Lod &lod = _lods[layer.lod_index];
Lod &lod = _lods[layer->lod_index]; lod.modified_blocks.insert(data_block_position);
lod.modified_blocks.set(data_block_position, true);
} }
void VoxelInstancer::on_scene_instance_removed( void VoxelInstancer::on_scene_instance_removed(
@ -1515,10 +1507,9 @@ void VoxelInstancer::on_scene_instance_removed(
block->scene_instances.resize(instance_count); block->scene_instances.resize(instance_count);
// Mark data block as modified // Mark data block as modified
const Layer *layer = get_layer(block->layer_id); const Layer &layer = get_layer(block->layer_id);
CRASH_COND(layer == nullptr); Lod &lod = _lods[layer.lod_index];
Lod &lod = _lods[layer->lod_index]; lod.modified_blocks.insert(data_block_position);
lod.modified_blocks.set(data_block_position, true);
} }
void VoxelInstancer::on_scene_instance_modified(Vector3i data_block_position, unsigned int render_block_index) { void VoxelInstancer::on_scene_instance_modified(Vector3i data_block_position, unsigned int render_block_index) {
@ -1526,10 +1517,9 @@ void VoxelInstancer::on_scene_instance_modified(Vector3i data_block_position, un
CRASH_COND(block == nullptr); CRASH_COND(block == nullptr);
// Mark data block as modified // Mark data block as modified
const Layer *layer = get_layer(block->layer_id); const Layer &layer = get_layer(block->layer_id);
CRASH_COND(layer == nullptr); Lod &lod = _lods[layer.lod_index];
Lod &lod = _lods[layer->lod_index]; lod.modified_blocks.insert(data_block_position);
lod.modified_blocks.set(data_block_position, true);
} }
void VoxelInstancer::set_mesh_block_size_po2(unsigned int p_mesh_block_size_po2) { void VoxelInstancer::set_mesh_block_size_po2(unsigned int p_mesh_block_size_po2) {
@ -1602,22 +1592,20 @@ Node *VoxelInstancer::debug_dump_as_nodes() const {
// For each layer // For each layer
const int *layer_key = nullptr; const int *layer_key = nullptr;
while ((layer_key = _layers.next(layer_key))) { for (auto layer_it = _layers.begin(); layer_it != _layers.end(); ++layer_it) {
const Layer *layer = _layers.getptr(*layer_key); const Layer &layer = layer_it->second;
CRASH_COND(layer == nullptr); const int lod_block_size = mesh_block_size << layer.lod_index;
const int lod_block_size = mesh_block_size << layer->lod_index;
Node3D *layer_node = memnew(Node3D); Node3D *layer_node = memnew(Node3D);
layer_node->set_name(String("Layer{0}").format(varray(*layer_key))); layer_node->set_name(String("Layer{0}").format(varray(*layer_key)));
root->add_child(layer_node); root->add_child(layer_node);
// For each block in layer // For each block in layer
const Vector3i *block_key = nullptr; for (auto block_it = layer.blocks.begin(); block_it != layer.blocks.end(); ++block_it) {
while ((block_key = layer->blocks.next(block_key))) { const unsigned int block_index = block_it->second;
const unsigned int *block_index = layer->blocks.getptr(*block_key); CRASH_COND(block_index >= _blocks.size());
CRASH_COND(block_index == nullptr); const Block *block = _blocks[block_index];
CRASH_COND(*block_index >= _blocks.size()); CRASH_COND(block == nullptr);
const Block *block = _blocks[*block_index];
if (block->multimesh_instance.is_valid()) { if (block->multimesh_instance.is_valid()) {
const Transform3D block_local_transform(Basis(), Vector3(block->grid_position * lod_block_size)); const Transform3D block_local_transform(Basis(), Vector3(block->grid_position * lod_block_size));

View File

@ -19,6 +19,7 @@
//#include <scene/resources/material.h> // Included by node.h lol //#include <scene/resources/material.h> // Included by node.h lol
#include <limits> #include <limits>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
class PhysicsBody3D; class PhysicsBody3D;
@ -103,7 +104,7 @@ private:
void add_layer(int layer_id, int lod_index); void add_layer(int layer_id, int lod_index);
void remove_layer(int layer_id); void remove_layer(int layer_id);
int create_block(Layer *layer, uint16_t layer_id, Vector3i grid_position); int create_block(Layer &layer, uint16_t layer_id, Vector3i grid_position);
void remove_block(unsigned int block_index); void remove_block(unsigned int block_index);
void set_world(World3D *world); void set_world(World3D *world);
void clear_blocks(); void clear_blocks();
@ -111,8 +112,11 @@ private:
void clear_layers(); void clear_layers();
void update_visibility(); void update_visibility();
void save_block(Vector3i data_grid_pos, int lod_index) const; void save_block(Vector3i data_grid_pos, int lod_index) const;
Layer *get_layer(int id);
const Layer *get_layer_const(int id) const; // Get a layer assuming it exists
Layer &get_layer(int id);
const Layer &get_layer_const(int id) const;
void regenerate_layer(uint16_t layer_id, bool regenerate_blocks); void regenerate_layer(uint16_t layer_id, bool regenerate_blocks);
void update_layer_meshes(int layer_id); void update_layer_meshes(int layer_id);
void update_layer_scenes(int layer_id); void update_layer_scenes(int layer_id);
@ -123,6 +127,7 @@ private:
#endif #endif
struct SceneInstance { struct SceneInstance {
// Owned by the scene tree.
VoxelInstanceComponent *component = nullptr; VoxelInstanceComponent *component = nullptr;
Node3D *root = nullptr; Node3D *root = nullptr;
}; };
@ -131,7 +136,7 @@ private:
unsigned int block_index, Transform3D transform, int data_block_size_po2); unsigned int block_index, Transform3D transform, int data_block_size_po2);
void update_block_from_transforms(int block_index, Span<const Transform3D> transforms, Vector3i grid_position, void update_block_from_transforms(int block_index, Span<const Transform3D> transforms, Vector3i grid_position,
Layer *layer, const VoxelInstanceLibraryItem *item_base, uint16_t layer_id, World3D *world, Layer &layer, const VoxelInstanceLibraryItem &item_base, uint16_t layer_id, World3D &world,
const Transform3D &block_transform); const Transform3D &block_transform);
void on_library_item_changed(int item_id, VoxelInstanceLibraryItem::ChangeType change) override; void on_library_item_changed(int item_id, VoxelInstanceLibraryItem::ChangeType change) override;
@ -166,7 +171,7 @@ private:
unsigned int lod_index; unsigned int lod_index;
// Blocks indexed by grid position. // Blocks indexed by grid position.
// Keys follow the mesh block coordinate system. // Keys follow the mesh block coordinate system.
HashMap<Vector3i, unsigned int, Vector3iHasher> blocks; std::unordered_map<Vector3i, unsigned int> blocks;
}; };
struct MeshLodDistances { struct MeshLodDistances {
@ -188,7 +193,7 @@ private:
// Blocks that have have unsaved changes. // Blocks that have have unsaved changes.
// Keys follows the data block coordinate system. // Keys follows the data block coordinate system.
HashMap<Vector3i, bool, Vector3iHasher> modified_blocks; std::unordered_set<Vector3i> modified_blocks;
// This is a temporary place to store loaded instances data while it's not visible yet. // This is a temporary place to store loaded instances data while it's not visible yet.
// These instances are user-authored ones. If a block does not have an entry there, // These instances are user-authored ones. If a block does not have an entry there,
@ -204,7 +209,10 @@ private:
FixedArray<Lod, MAX_LOD> _lods; FixedArray<Lod, MAX_LOD> _lods;
std::vector<Block *> _blocks; // Does not have nulls std::vector<Block *> _blocks; // Does not have nulls
HashMap<int, Layer> _layers; // Each layer corresponds to a library item
// Each layer corresponds to a library item. Addresses of values in the map are expected to be stable.
std::unordered_map<int, Layer> _layers;
Ref<VoxelInstanceLibrary> _library; Ref<VoxelInstanceLibrary> _library;
std::vector<Transform3D> _transform_cache; std::vector<Transform3D> _transform_cache;