Przeglądaj źródła

Merge pull request #79678 from thiagola92/auto_create_tilesets_for_multiple_atlas

Auto create tile for multiple atlases
Rémi Verschelde 2 lat temu
rodzic
commit
a7ded904de

+ 47 - 35
editor/plugins/tiles/tile_set_atlas_source_editor.cpp

@@ -1672,6 +1672,8 @@ void TileSetAtlasSourceEditor::_menu_option(int p_option) {
 			_update_tile_id_label();
 		} break;
 		case ADVANCED_AUTO_CREATE_TILES: {
+			atlases_to_auto_create_tiles.clear();
+			atlases_to_auto_create_tiles.append(tile_set_atlas_source);
 			_auto_create_tiles();
 		} break;
 		case ADVANCED_AUTO_REMOVE_TILES: {
@@ -2096,6 +2098,8 @@ void TileSetAtlasSourceEditor::_tile_proxy_object_changed(String p_what) {
 
 void TileSetAtlasSourceEditor::_atlas_source_proxy_object_changed(String p_what) {
 	if (p_what == "texture" && !atlas_source_proxy_object->get("texture").is_null()) {
+		atlases_to_auto_create_tiles.clear();
+		atlases_to_auto_create_tiles.append(tile_set_atlas_source);
 		confirm_auto_create_tiles->popup_centered();
 	} else if (p_what == "id") {
 		emit_signal(SNAME("source_id_changed"), atlas_source_proxy_object->get_id());
@@ -2242,54 +2246,61 @@ void TileSetAtlasSourceEditor::edit(Ref<TileSet> p_tile_set, TileSetAtlasSource
 	_update_current_tile_data_editor();
 }
 
-void TileSetAtlasSourceEditor::init_source() {
+void TileSetAtlasSourceEditor::init_new_atlases(const Vector<Ref<TileSetAtlasSource>> &p_atlases) {
 	tool_setup_atlas_source_button->set_pressed(true);
+	atlases_to_auto_create_tiles = p_atlases;
 	confirm_auto_create_tiles->popup_centered();
 }
 
 void TileSetAtlasSourceEditor::_auto_create_tiles() {
-	if (!tile_set_atlas_source) {
-		return;
-	}
+	for (Ref<TileSetAtlasSource> &atlas_source : atlases_to_auto_create_tiles) {
+		if (atlas_source.is_valid()) {
+			Ref<Texture2D> texture = atlas_source->get_texture();
+			if (texture.is_valid()) {
+				Vector2i margins = atlas_source->get_margins();
+				Vector2i separation = atlas_source->get_separation();
+				Vector2i texture_region_size = atlas_source->get_texture_region_size();
+				Size2i grid_size = atlas_source->get_atlas_grid_size();
+				EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+				undo_redo->create_action(TTR("Create tiles in non-transparent texture regions"));
+				for (int y = 0; y < grid_size.y; y++) {
+					for (int x = 0; x < grid_size.x; x++) {
+						// Check if we have a tile at the coord.
+						Vector2i coords = Vector2i(x, y);
+						if (atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) {
+							// Check if the texture is empty at the given coords.
+							Rect2i region = Rect2i(margins + (coords * (texture_region_size + separation)), texture_region_size);
+							bool is_opaque = false;
+							for (int region_x = region.get_position().x; region_x < region.get_end().x; region_x++) {
+								for (int region_y = region.get_position().y; region_y < region.get_end().y; region_y++) {
+									if (texture->is_pixel_opaque(region_x, region_y)) {
+										is_opaque = true;
+										break;
+									}
+								}
+								if (is_opaque) {
+									break;
+								}
+							}
 
-	Ref<Texture2D> texture = tile_set_atlas_source->get_texture();
-	if (texture.is_valid()) {
-		Vector2i margins = tile_set_atlas_source->get_margins();
-		Vector2i separation = tile_set_atlas_source->get_separation();
-		Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size();
-		Size2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
-		EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
-		undo_redo->create_action(TTR("Create tiles in non-transparent texture regions"));
-		for (int y = 0; y < grid_size.y; y++) {
-			for (int x = 0; x < grid_size.x; x++) {
-				// Check if we have a tile at the coord
-				Vector2i coords = Vector2i(x, y);
-				if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) {
-					// Check if the texture is empty at the given coords.
-					Rect2i region = Rect2i(margins + (coords * (texture_region_size + separation)), texture_region_size);
-					bool is_opaque = false;
-					for (int region_x = region.get_position().x; region_x < region.get_end().x; region_x++) {
-						for (int region_y = region.get_position().y; region_y < region.get_end().y; region_y++) {
-							if (texture->is_pixel_opaque(region_x, region_y)) {
-								is_opaque = true;
-								break;
+							// If we do have opaque pixels, create a tile.
+							if (is_opaque) {
+								undo_redo->add_do_method(*atlas_source, "create_tile", coords);
+								undo_redo->add_undo_method(*atlas_source, "remove_tile", coords);
 							}
 						}
-						if (is_opaque) {
-							break;
-						}
-					}
-
-					// If we do have opaque pixels, create a tile.
-					if (is_opaque) {
-						undo_redo->add_do_method(tile_set_atlas_source, "create_tile", coords);
-						undo_redo->add_undo_method(tile_set_atlas_source, "remove_tile", coords);
 					}
 				}
+				undo_redo->commit_action();
 			}
 		}
-		undo_redo->commit_action();
 	}
+
+	_cancel_auto_create_tiles();
+}
+
+void TileSetAtlasSourceEditor::_cancel_auto_create_tiles() {
+	atlases_to_auto_create_tiles.clear();
 }
 
 void TileSetAtlasSourceEditor::_auto_remove_tiles() {
@@ -2644,6 +2655,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
 	confirm_auto_create_tiles->set_ok_button_text(TTR("Yes"));
 	confirm_auto_create_tiles->add_cancel_button()->set_text(TTR("No"));
 	confirm_auto_create_tiles->connect("confirmed", callable_mp(this, &TileSetAtlasSourceEditor::_auto_create_tiles));
+	confirm_auto_create_tiles->connect("canceled", callable_mp(this, &TileSetAtlasSourceEditor::_cancel_auto_create_tiles));
 	add_child(confirm_auto_create_tiles);
 
 	// Inspector plugin.

+ 3 - 1
editor/plugins/tiles/tile_set_atlas_source_editor.h

@@ -270,7 +270,9 @@ private:
 	// -- Misc --
 	void _auto_create_tiles();
 	void _auto_remove_tiles();
+	void _cancel_auto_create_tiles();
 	AcceptDialog *confirm_auto_create_tiles = nullptr;
+	Vector<Ref<TileSetAtlasSource>> atlases_to_auto_create_tiles;
 	Vector2i _get_drag_offset_tile_coords(const Vector2i &p_offset) const;
 
 	void _tile_set_changed();
@@ -288,7 +290,7 @@ protected:
 
 public:
 	void edit(Ref<TileSet> p_tile_set, TileSetAtlasSource *p_tile_set_source, int p_source_id);
-	void init_source();
+	void init_new_atlases(const Vector<Ref<TileSetAtlasSource>> &p_atlases);
 
 	TileSetAtlasSourceEditor();
 	~TileSetAtlasSourceEditor();

+ 40 - 53
editor/plugins/tiles/tile_set_editor.cpp

@@ -57,35 +57,9 @@ void TileSetEditor::_drop_data_fw(const Point2 &p_point, const Variant &p_data,
 
 	if (p_from == sources_list) {
 		// Handle dropping a texture in the list of atlas resources.
-		int source_id = TileSet::INVALID_SOURCE;
-		int added = 0;
 		Dictionary d = p_data;
 		Vector<String> files = d["files"];
-		for (int i = 0; i < files.size(); i++) {
-			Ref<Texture2D> resource = ResourceLoader::load(files[i]);
-			if (resource.is_valid()) {
-				// Retrieve the id for the next created source.
-				source_id = tile_set->get_next_source_id();
-
-				// Actually create the new source.
-				Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource);
-				atlas_source->set_texture(resource);
-				EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
-				undo_redo->create_action(TTR("Add a new atlas source"));
-				undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id);
-				undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size());
-				undo_redo->add_undo_method(*tile_set, "remove_source", source_id);
-				undo_redo->commit_action();
-				added += 1;
-			}
-		}
-
-		if (added == 1) {
-			tile_set_atlas_source_editor->init_source();
-		}
-
-		// Update the selected source (thus triggering an update).
-		_update_sources_list(source_id);
+		_load_texture_files(files);
 	}
 }
 
@@ -126,6 +100,43 @@ bool TileSetEditor::_can_drop_data_fw(const Point2 &p_point, const Variant &p_da
 	return false;
 }
 
+void TileSetEditor::_load_texture_files(const Vector<String> &p_paths) {
+	int source_id = TileSet::INVALID_SOURCE;
+	Vector<Ref<TileSetAtlasSource>> atlases;
+
+	for (const String &p_path : p_paths) {
+		Ref<Texture2D> texture = ResourceLoader::load(p_path);
+
+		if (texture.is_null()) {
+			EditorNode::get_singleton()->show_warning(TTR("Invalid texture selected."));
+			continue;
+		}
+
+		// Retrieve the id for the next created source.
+		source_id = tile_set->get_next_source_id();
+
+		// Actually create the new source.
+		Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource);
+		atlas_source->set_texture(texture);
+
+		EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+		undo_redo->create_action(TTR("Add a new atlas source"));
+		undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id);
+		undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size());
+		undo_redo->add_undo_method(*tile_set, "remove_source", source_id);
+		undo_redo->commit_action();
+
+		atlases.append(atlas_source);
+	}
+
+	if (!atlases.is_empty()) {
+		tile_set_atlas_source_editor->init_new_atlases(atlases);
+	}
+
+	// Update the selected source (thus triggering an update).
+	_update_sources_list(source_id);
+}
+
 void TileSetEditor::_update_sources_list(int force_selected_id) {
 	if (tile_set.is_null()) {
 		return;
@@ -226,30 +237,6 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
 	TilesEditorUtils::get_singleton()->set_sources_lists_current(sources_list->get_current());
 }
 
-void TileSetEditor::_texture_file_selected(const String &p_path) {
-	Ref<Texture2D> texture = ResourceLoader::load(p_path);
-	if (texture.is_null()) {
-		EditorNode::get_singleton()->show_warning(TTR("Invalid texture selected."));
-		return;
-	}
-
-	int source_id = tile_set->get_next_source_id();
-
-	Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource);
-	atlas_source->set_texture(texture);
-
-	// Add a new source.
-	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
-	undo_redo->create_action(TTR("Add atlas source"));
-	undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id);
-	undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size());
-	undo_redo->add_undo_method(*tile_set, "remove_source", source_id);
-	undo_redo->commit_action();
-
-	_update_sources_list(source_id);
-	tile_set_atlas_source_editor->init_source();
-}
-
 void TileSetEditor::_source_selected(int p_source_index) {
 	ERR_FAIL_COND(!tile_set.is_valid());
 
@@ -308,8 +295,8 @@ void TileSetEditor::_source_add_id_pressed(int p_id_pressed) {
 			if (!texture_file_dialog) {
 				texture_file_dialog = memnew(EditorFileDialog);
 				add_child(texture_file_dialog);
-				texture_file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
-				texture_file_dialog->connect("file_selected", callable_mp(this, &TileSetEditor::_texture_file_selected));
+				texture_file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
+				texture_file_dialog->connect("files_selected", callable_mp(this, &TileSetEditor::_load_texture_files));
 
 				List<String> extensions;
 				ResourceLoader::get_recognized_extensions_for_type("Texture2D", &extensions);

+ 1 - 1
editor/plugins/tiles/tile_set_editor.h

@@ -68,6 +68,7 @@ private:
 
 	void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
 	bool _can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
+	void _load_texture_files(const Vector<String> &p_paths);
 
 	void _update_sources_list(int force_selected_id = -1);
 
@@ -78,7 +79,6 @@ private:
 	MenuButton *sources_advanced_menu_button = nullptr;
 	ItemList *sources_list = nullptr;
 	Ref<Texture2D> missing_texture_texture;
-	void _texture_file_selected(const String &p_path);
 	void _source_selected(int p_source_index);
 	void _source_delete_pressed();
 	void _source_add_id_pressed(int p_id_pressed);