diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index cf13068efa7a..d913d0b3b1f9 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -28,6 +28,12 @@
Clears all baked meshes. See [method make_baked_meshes].
+
+
+
+ Clears cells that do not exist in the grid map.
+
+
diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp
index 2956cb12abc8..0089a1dbd335 100644
--- a/modules/gridmap/editor/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp
@@ -185,6 +185,12 @@ void GridMapEditor::_menu_option(int p_option) {
_fill_selection();
} break;
+ case MENU_OPTION_CLEAR_ALL_CELLS: {
+ _clear_all_cells();
+ } break;
+ case MENU_OPTION_FIX_INVALID_CELLS: {
+ _fix_invalid_cells();
+ } break;
case MENU_OPTION_GRIDMAP_SETTINGS: {
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50) * EDSCALE);
} break;
@@ -502,6 +508,24 @@ void GridMapEditor::_fill_selection() {
undo_redo->commit_action();
}
+void GridMapEditor::_clear_all_cells() {
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Clear All Cells"));
+ undo_redo->add_undo_method(node, "set", "data", node->get("data"));
+ node->clear();
+ undo_redo->add_do_method(node, "set", "data", node->get("data"));
+ undo_redo->commit_action();
+}
+
+void GridMapEditor::_fix_invalid_cells() {
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Fix Invalid Cells"));
+ undo_redo->add_undo_method(node, "set", "data", node->get("data"));
+ node->fix_invalid_cells();
+ undo_redo->add_do_method(node, "set", "data", node->get("data"));
+ undo_redo->commit_action();
+}
+
void GridMapEditor::_clear_clipboard_data() {
for (const ClipboardItem &E : clipboard_items) {
if (E.instance.is_null()) {
@@ -1323,6 +1347,9 @@ GridMapEditor::GridMapEditor() {
options->get_popup()->add_check_shortcut(ED_GET_SHORTCUT("grid_map/keep_selected"), MENU_OPTION_PASTE_SELECTS);
options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_PASTE_SELECTS), true);
options->get_popup()->add_separator();
+ options->get_popup()->add_item(TTR("Clear All Cells"), MENU_OPTION_CLEAR_ALL_CELLS);
+ options->get_popup()->add_item(TTR("Fix Invalid Cells"), MENU_OPTION_FIX_INVALID_CELLS);
+ options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Settings..."), MENU_OPTION_GRIDMAP_SETTINGS);
settings_dialog = memnew(ConfirmationDialog);
diff --git a/modules/gridmap/editor/grid_map_editor_plugin.h b/modules/gridmap/editor/grid_map_editor_plugin.h
index 71407132e2bd..1f55e196e750 100644
--- a/modules/gridmap/editor/grid_map_editor_plugin.h
+++ b/modules/gridmap/editor/grid_map_editor_plugin.h
@@ -197,6 +197,8 @@ class GridMapEditor : public VBoxContainer {
MENU_OPTION_SELECTION_CUT,
MENU_OPTION_SELECTION_CLEAR,
MENU_OPTION_SELECTION_FILL,
+ MENU_OPTION_CLEAR_ALL_CELLS,
+ MENU_OPTION_FIX_INVALID_CELLS,
MENU_OPTION_GRIDMAP_SETTINGS
};
@@ -247,6 +249,8 @@ class GridMapEditor : public VBoxContainer {
void _delete_selection();
void _fill_selection();
+ void _clear_all_cells();
+ void _fix_invalid_cells();
bool do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click);
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 9329849964f8..a188e2bad860 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -280,16 +280,19 @@ RID GridMap::get_navigation_map() const {
#endif // NAVIGATION_3D_DISABLED
void GridMap::set_mesh_library(const Ref &p_mesh_library) {
- if (mesh_library.is_valid()) {
- mesh_library->disconnect_changed(callable_mp(this, &GridMap::_recreate_octant_data));
- }
- mesh_library = p_mesh_library;
- if (mesh_library.is_valid()) {
- mesh_library->connect_changed(callable_mp(this, &GridMap::_recreate_octant_data));
- }
+ if (mesh_library != p_mesh_library) {
+ if (mesh_library.is_valid()) {
+ mesh_library->disconnect_changed(callable_mp(this, &GridMap::_recreate_octant_data));
+ }
- _recreate_octant_data();
- emit_signal(CoreStringName(changed));
+ mesh_library = p_mesh_library;
+ if (mesh_library.is_valid()) {
+ mesh_library->connect_changed(callable_mp(this, &GridMap::_recreate_octant_data));
+ }
+
+ _recreate_octant_data();
+ emit_signal(CoreStringName(changed));
+ }
}
Ref GridMap::get_mesh_library() const {
@@ -1130,6 +1133,16 @@ void GridMap::clear() {
clear_baked_meshes();
}
+void GridMap::fix_invalid_cells() {
+ ERR_FAIL_COND_MSG(mesh_library.is_null(), "Cannot fix invalid cells if MeshLibrary is not open.");
+
+ for (HashMap::Iterator I = cell_map.begin(); I; ++I) {
+ if (!mesh_library.is_valid() || !mesh_library->has_item(I->value.item)) {
+ set_cell_item(I->key, INVALID_CELL_ITEM);
+ }
+ }
+}
+
#ifndef DISABLE_DEPRECATED
void GridMap::resource_changed(const Ref &p_res) {
}
@@ -1222,6 +1235,7 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_center_z"), &GridMap::get_center_z);
ClassDB::bind_method(D_METHOD("clear"), &GridMap::clear);
+ ClassDB::bind_method(D_METHOD("fix_invalid_cells"), &GridMap::fix_invalid_cells);
ClassDB::bind_method(D_METHOD("get_used_cells"), &GridMap::get_used_cells);
ClassDB::bind_method(D_METHOD("get_used_cells_by_item", "item"), &GridMap::get_used_cells_by_item);
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index c5730a5e1cde..fcd485f9a5a8 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -307,6 +307,7 @@ class GridMap : public Node3D {
void make_baked_meshes(bool p_gen_lightmap_uv = false, float p_lightmap_uv_texel_size = 0.1);
void clear();
+ void fix_invalid_cells();
Array get_bake_meshes();
RID get_bake_mesh_instance(int p_idx);