diff --git a/terrain/voxel_block.cpp b/terrain/voxel_block.cpp index ef56c4ec..6d25ed3f 100644 --- a/terrain/voxel_block.cpp +++ b/terrain/voxel_block.cpp @@ -147,15 +147,30 @@ void VoxelBlock::set_world(World *world) { } void VoxelBlock::set_visible(bool visible) { + if (_visible && visible) { + return; + } + _visible = visible; + _set_visible(_visible && _parent_visible); +} + +bool VoxelBlock::is_visible() const { + return _visible; +} + +void VoxelBlock::_set_visible(bool visible) { if (_mesh_instance.is_valid()) { _mesh_instance.set_visible(visible); } if (_static_body.is_valid()) { _static_body.set_shape_enabled(0, visible); } - _visible = visible; } -bool VoxelBlock::is_visible() const { - return _visible; +void VoxelBlock::set_parent_visible(bool parent_visible) { + if (_parent_visible && parent_visible) { + return; + } + _parent_visible = parent_visible; + _set_visible(_visible && _parent_visible); } diff --git a/terrain/voxel_block.h b/terrain/voxel_block.h index 4048e2d0..256a55d3 100644 --- a/terrain/voxel_block.h +++ b/terrain/voxel_block.h @@ -39,6 +39,8 @@ public: void set_visible(bool visible); bool is_visible() const; + void set_parent_visible(bool parent_visible); + inline bool is_mesh_update_scheduled() { return _mesh_state == MESH_UPDATE_NOT_SENT || _mesh_state == MESH_UPDATE_SENT; } @@ -46,6 +48,8 @@ public: private: VoxelBlock(); + void _set_visible(bool visible); + Vector3i _position_in_voxels; DirectMeshInstance _mesh_instance; @@ -53,6 +57,7 @@ private: int _mesh_update_count = 0; bool _visible = true; + bool _parent_visible = true; MeshState _mesh_state = MESH_NEVER_UPDATED; // The mesh might be null, but we don't know if it's actually empty or if it's loading. diff --git a/terrain/voxel_lod_terrain.cpp b/terrain/voxel_lod_terrain.cpp index 134db67e..537a29d6 100644 --- a/terrain/voxel_lod_terrain.cpp +++ b/terrain/voxel_lod_terrain.cpp @@ -418,12 +418,12 @@ void VoxelLodTerrain::_notification(int p_what) { } }; - struct SetVisibilityAction { + struct SetParentVisibilityAction { bool visible; - SetVisibilityAction(bool v) : + SetParentVisibilityAction(bool v) : visible(v) {} void operator()(VoxelBlock *block) { - block->set_visible(visible); + block->set_parent_visible(visible); } }; @@ -456,8 +456,7 @@ void VoxelLodTerrain::_notification(int p_what) { } break; case NOTIFICATION_VISIBILITY_CHANGED: { - // TODO This is wrong, some blocks NEED to remain hidden - SetVisibilityAction sva(is_visible()); + SetParentVisibilityAction sva(is_visible()); for_all_blocks(sva); } break; @@ -934,6 +933,7 @@ void VoxelLodTerrain::_process() { //print_line(String("Adding block {0} at lod {1}").format(varray(eo.block_position.to_vec3(), eo.lod))); // The block will be made visible and meshed only by LodOctree block->set_visible(false); + block->set_parent_visible(is_visible()); } } diff --git a/terrain/voxel_terrain.cpp b/terrain/voxel_terrain.cpp index f57eac82..b5cf02aa 100644 --- a/terrain/voxel_terrain.cpp +++ b/terrain/voxel_terrain.cpp @@ -607,12 +607,12 @@ void VoxelTerrain::_notification(int p_what) { } }; - struct SetVisibilityAction { + struct SetParentVisibilityAction { bool visible; - SetVisibilityAction(bool v) : + SetParentVisibilityAction(bool v) : visible(v) {} void operator()(VoxelBlock *block) { - block->set_visible(visible); + block->set_parent_visible(visible); } }; @@ -646,7 +646,7 @@ void VoxelTerrain::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: ERR_FAIL_COND(_map.is_null()); - _map->for_all_blocks(SetVisibilityAction(is_visible())); + _map->for_all_blocks(SetParentVisibilityAction(is_visible())); break; // TODO Listen for transform changes @@ -1062,6 +1062,7 @@ void VoxelTerrain::_process() { } block->set_mesh(mesh, this, _generate_collisions, collidable_surface, get_tree()->is_debugging_collisions_hint()); + block->set_parent_visible(is_visible()); } shift_up(_blocks_pending_main_thread_update, queue_index);