فهرست منبع

Merge pull request #59810 from reduz/fbx-import-dialog

Add a dialog for customizing FBX import
Rémi Verschelde 2 سال پیش
والد
کامیت
02f24eb3f2

+ 14 - 1
editor/editor_node.cpp

@@ -96,6 +96,7 @@
 #include "editor/export/editor_export.h"
 #include "editor/export/editor_export.h"
 #include "editor/export/export_template_manager.h"
 #include "editor/export/export_template_manager.h"
 #include "editor/export/project_export.h"
 #include "editor/export/project_export.h"
+#include "editor/fbx_importer_manager.h"
 #include "editor/filesystem_dock.h"
 #include "editor/filesystem_dock.h"
 #include "editor/history_dock.h"
 #include "editor/history_dock.h"
 #include "editor/import/audio_stream_import_settings.h"
 #include "editor/import/audio_stream_import_settings.h"
@@ -2981,7 +2982,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
 		} break;
 		} break;
 		case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
 		case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
 			export_template_manager->popup_manager();
 			export_template_manager->popup_manager();
-
+		} break;
+		case SETTINGS_MANAGE_FBX_IMPORTER: {
+#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
+			fbx_importer_manager->show_dialog();
+#endif
 		} break;
 		} break;
 		case SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE: {
 		case SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE: {
 			custom_build_manage_templates->hide();
 			custom_build_manage_templates->hide();
@@ -6624,6 +6629,11 @@ EditorNode::EditorNode() {
 	gui_base->add_child(about);
 	gui_base->add_child(about);
 	feature_profile_manager->connect("current_feature_profile_changed", callable_mp(this, &EditorNode::_feature_profile_changed));
 	feature_profile_manager->connect("current_feature_profile_changed", callable_mp(this, &EditorNode::_feature_profile_changed));
 
 
+#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
+	fbx_importer_manager = memnew(FBXImporterManager);
+	gui_base->add_child(fbx_importer_manager);
+#endif
+
 	warning = memnew(AcceptDialog);
 	warning = memnew(AcceptDialog);
 	warning->add_button(TTR("Copy Text"), true, "copy");
 	warning->add_button(TTR("Copy Text"), true, "copy");
 	gui_base->add_child(warning);
 	gui_base->add_child(warning);
@@ -6796,6 +6806,9 @@ EditorNode::EditorNode() {
 #ifndef ANDROID_ENABLED
 #ifndef ANDROID_ENABLED
 	settings_menu->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
 	settings_menu->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
 #endif
 #endif
+#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED)
+	settings_menu->add_item(TTR("Configure FBX Importer..."), SETTINGS_MANAGE_FBX_IMPORTER);
+#endif
 
 
 	help_menu = memnew(PopupMenu);
 	help_menu = memnew(PopupMenu);
 	help_menu->set_name(TTR("Help"));
 	help_menu->set_name(TTR("Help"));

+ 4 - 0
editor/editor_node.h

@@ -77,6 +77,7 @@ class EditorSettingsDialog;
 class EditorToaster;
 class EditorToaster;
 class EditorUndoRedoManager;
 class EditorUndoRedoManager;
 class ExportTemplateManager;
 class ExportTemplateManager;
+class FBXImporterManager;
 class FileDialog;
 class FileDialog;
 class FileSystemDock;
 class FileSystemDock;
 class HistoryDock;
 class HistoryDock;
@@ -209,6 +210,7 @@ private:
 		SETTINGS_EDITOR_DATA_FOLDER,
 		SETTINGS_EDITOR_DATA_FOLDER,
 		SETTINGS_EDITOR_CONFIG_FOLDER,
 		SETTINGS_EDITOR_CONFIG_FOLDER,
 		SETTINGS_MANAGE_EXPORT_TEMPLATES,
 		SETTINGS_MANAGE_EXPORT_TEMPLATES,
+		SETTINGS_MANAGE_FBX_IMPORTER,
 		SETTINGS_MANAGE_FEATURE_PROFILES,
 		SETTINGS_MANAGE_FEATURE_PROFILES,
 		SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE,
 		SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE,
 		SETTINGS_PICK_MAIN_SCENE,
 		SETTINGS_PICK_MAIN_SCENE,
@@ -285,6 +287,8 @@ private:
 	ProjectExportDialog *project_export = nullptr;
 	ProjectExportDialog *project_export = nullptr;
 	ProjectSettingsEditor *project_settings_editor = nullptr;
 	ProjectSettingsEditor *project_settings_editor = nullptr;
 
 
+	FBXImporterManager *fbx_importer_manager = nullptr;
+
 	Vector<EditorPlugin *> editor_plugins;
 	Vector<EditorPlugin *> editor_plugins;
 	bool _initializing_plugins = false;
 	bool _initializing_plugins = false;
 	HashMap<String, EditorPlugin *> addon_name_to_plugin;
 	HashMap<String, EditorPlugin *> addon_name_to_plugin;

+ 158 - 0
editor/fbx_importer_manager.cpp

@@ -0,0 +1,158 @@
+/*************************************************************************/
+/*  fbx_importer_manager.cpp                                             */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "fbx_importer_manager.h"
+
+#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
+#include "scene/gui/link_button.h"
+
+void FBXImporterManager::_notification(int p_what) {
+	switch (p_what) {
+		case NOTIFICATION_READY: {
+			connect("confirmed", callable_mp(this, &FBXImporterManager::_path_confirmed));
+		} break;
+	}
+}
+
+void FBXImporterManager::show_dialog(bool p_exclusive) {
+	String fbx2gltf_path = EDITOR_GET("filesystem/import/fbx/fbx2gltf_path");
+	fbx_path->set_text(fbx2gltf_path);
+	_validate_path(fbx2gltf_path);
+
+	set_flag(Window::FLAG_BORDERLESS, p_exclusive); // Avoid closing accidentally .
+	set_close_on_escape(!p_exclusive);
+
+	popup_centered();
+}
+
+void FBXImporterManager::_validate_path(const String &p_path) {
+	String error;
+	bool success = false;
+
+	if (p_path == "") {
+		error = TTR("Path to FBX2glTF executable is empty.");
+	} else if (!FileAccess::exists(p_path)) {
+		error = TTR("Path to FBX2glTF executable is invalid.");
+	} else {
+		List<String> args;
+		args.push_back("--version");
+		int exitcode;
+		Error err = OS::get_singleton()->execute(p_path, args, nullptr, &exitcode);
+
+		if (err == OK && exitcode == 0) {
+			success = true;
+		} else {
+			error = TTR("Error executing this file (wrong version or architecture).");
+		}
+	}
+
+	if (success) {
+		path_status->set_text(TTR("FBX2glTF executable is valid."));
+		path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("success_color"), SNAME("Editor")));
+		get_ok_button()->set_disabled(false);
+	} else {
+		path_status->set_text(error);
+		path_status->add_theme_color_override("font_color", path_status->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+		get_ok_button()->set_disabled(true);
+	}
+}
+
+void FBXImporterManager::_select_file(const String &p_path) {
+	fbx_path->set_text(p_path);
+	_validate_path(p_path);
+}
+
+void FBXImporterManager::_path_confirmed() {
+	String path = fbx_path->get_text();
+	EditorSettings::get_singleton()->set("filesystem/import/fbx/fbx2gltf_path", path);
+	EditorSettings::get_singleton()->save();
+}
+
+void FBXImporterManager::_browse_install() {
+	if (fbx_path->get_text() != String()) {
+		browse_dialog->set_current_file(fbx_path->get_text());
+	}
+
+	browse_dialog->popup_centered_ratio();
+}
+
+FBXImporterManager *FBXImporterManager::singleton = nullptr;
+
+FBXImporterManager::FBXImporterManager() {
+	singleton = this;
+
+	set_title(TTR("Configure FBX Importer"));
+
+	VBoxContainer *vb = memnew(VBoxContainer);
+	vb->add_child(memnew(Label(TTR("FBX2glTF is required for importing FBX files.\nPlease download it and provide a valid path to the binary:"))));
+	LinkButton *lb = memnew(LinkButton);
+	lb->set_text(TTR("Click this link to download FBX2glTF"));
+	lb->set_uri("https://godotengine.org/fbx-import");
+	vb->add_child(lb);
+
+	HBoxContainer *hb = memnew(HBoxContainer);
+
+	fbx_path = memnew(LineEdit);
+	fbx_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+	hb->add_child(fbx_path);
+	fbx_path_browse = memnew(Button);
+	hb->add_child(fbx_path_browse);
+	fbx_path_browse->set_text(TTR("Browse"));
+	fbx_path_browse->connect("pressed", callable_mp(this, &FBXImporterManager::_browse_install));
+	hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+	hb->set_custom_minimum_size(Size2(400 * EDSCALE, 0));
+
+	vb->add_child(hb);
+
+	path_status = memnew(Label);
+	vb->add_child(path_status);
+
+	add_child(vb);
+
+	fbx_path->connect("text_changed", callable_mp(this, &FBXImporterManager::_validate_path));
+
+	get_ok_button()->set_text(TTR("Confirm Path"));
+
+	browse_dialog = memnew(EditorFileDialog);
+	browse_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+	browse_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
+#if defined(X11_ENABLED)
+	browse_dialog->add_filter("FBX2glTF-linux-x86_64");
+#elif defined(OSX_ENABLED)
+	browse_dialog->add_filter("FBX2glTF-macos-x86_64");
+#elif defined(WINDOWS_ENABLED)
+	browse_dialog->add_filter("FBX2glTF-windows-x86_64");
+#endif
+
+	browse_dialog->connect("file_selected", callable_mp(this, &FBXImporterManager::_select_file));
+
+	add_child(browse_dialog);
+}

+ 66 - 0
editor/fbx_importer_manager.h

@@ -0,0 +1,66 @@
+/*************************************************************************/
+/*  fbx_importer_manager.h                                               */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef FBX_IMPORTER_MANAGER_H
+#define FBX_IMPORTER_MANAGER_H
+
+#include "editor/editor_file_dialog.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/line_edit.h"
+
+class FBXImporterManager : public ConfirmationDialog {
+	GDCLASS(FBXImporterManager, ConfirmationDialog)
+
+	Label *message = nullptr;
+	LineEdit *fbx_path = nullptr;
+	Button *fbx_path_browse = nullptr;
+	EditorFileDialog *browse_dialog = nullptr;
+	Label *path_status = nullptr;
+
+	void _validate_path(const String &p_path);
+	void _select_file(const String &p_path);
+	void _path_confirmed();
+	void _browse_install();
+	void _link_clicked();
+
+	static FBXImporterManager *singleton;
+
+protected:
+	void _notification(int p_what);
+
+public:
+	static FBXImporterManager *get_singleton() { return singleton; }
+
+	void show_dialog(bool p_exclusive = false);
+
+	FBXImporterManager();
+};
+
+#endif // FBX_IMPORTER_MANAGER_H

+ 27 - 0
modules/gltf/editor/editor_scene_importer_fbx.cpp

@@ -36,6 +36,7 @@
 
 
 #include "core/config/project_settings.h"
 #include "core/config/project_settings.h"
 #include "editor/editor_settings.h"
 #include "editor/editor_settings.h"
+#include "main/main.h"
 
 
 uint32_t EditorSceneFormatImporterFBX::get_import_flags() const {
 uint32_t EditorSceneFormatImporterFBX::get_import_flags() const {
 	return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION;
 	return ImportFlags::IMPORT_SCENE | ImportFlags::IMPORT_ANIMATION;
@@ -111,4 +112,30 @@ void EditorSceneFormatImporterFBX::get_import_options(const String &p_path,
 		List<ResourceImporter::ImportOption> *r_options) {
 		List<ResourceImporter::ImportOption> *r_options) {
 }
 }
 
 
+bool EditorFileSystemImportFormatSupportQueryFBX::is_active() const {
+	String fbx2gltf_path = EDITOR_GET("filesystem/import/fbx/fbx2gltf_path");
+	return !FileAccess::exists(fbx2gltf_path);
+}
+
+Vector<String> EditorFileSystemImportFormatSupportQueryFBX::get_file_extensions() const {
+	Vector<String> ret;
+	ret.push_back("fbx");
+	return ret;
+}
+
+bool EditorFileSystemImportFormatSupportQueryFBX::query() {
+	FBXImporterManager::get_singleton()->show_dialog(true);
+
+	while (true) {
+		OS::get_singleton()->delay_usec(1);
+		DisplayServer::get_singleton()->process_events();
+		Main::iteration();
+		if (!FBXImporterManager::get_singleton()->is_visible()) {
+			break;
+		}
+	}
+
+	return false;
+}
+
 #endif // TOOLS_ENABLED
 #endif // TOOLS_ENABLED

+ 11 - 0
modules/gltf/editor/editor_scene_importer_fbx.h

@@ -33,6 +33,8 @@
 
 
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 
 
+#include "editor/editor_file_system.h"
+#include "editor/fbx_importer_manager.h"
 #include "editor/import/resource_importer_scene.h"
 #include "editor/import/resource_importer_scene.h"
 
 
 class Animation;
 class Animation;
@@ -53,6 +55,15 @@ public:
 			const HashMap<StringName, Variant> &p_options) override;
 			const HashMap<StringName, Variant> &p_options) override;
 };
 };
 
 
+class EditorFileSystemImportFormatSupportQueryFBX : public EditorFileSystemImportFormatSupportQuery {
+	GDCLASS(EditorFileSystemImportFormatSupportQueryFBX, EditorFileSystemImportFormatSupportQuery);
+
+public:
+	virtual bool is_active() const override;
+	virtual Vector<String> get_file_extensions() const override;
+	virtual bool query() override;
+};
+
 #endif // TOOLS_ENABLED
 #endif // TOOLS_ENABLED
 
 
 #endif // EDITOR_SCENE_IMPORTER_FBX_H
 #endif // EDITOR_SCENE_IMPORTER_FBX_H

+ 7 - 10
modules/gltf/register_types.cpp

@@ -80,16 +80,13 @@ static void _editor_init() {
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,
 			"filesystem/import/fbx/fbx2gltf_path", PROPERTY_HINT_GLOBAL_FILE));
 			"filesystem/import/fbx/fbx2gltf_path", PROPERTY_HINT_GLOBAL_FILE));
 	if (fbx_enabled) {
 	if (fbx_enabled) {
-		Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
-		if (fbx2gltf_path.is_empty()) {
-			WARN_PRINT("FBX file import is enabled in the project settings, but no FBX2glTF path is configured in the editor settings. FBX files will not be imported.");
-		} else if (!da->file_exists(fbx2gltf_path)) {
-			WARN_PRINT("FBX file import is enabled, but the FBX2glTF path doesn't point to an accessible file. FBX files will not be imported.");
-		} else {
-			Ref<EditorSceneFormatImporterFBX> importer;
-			importer.instantiate();
-			ResourceImporterScene::add_importer(importer);
-		}
+		Ref<EditorSceneFormatImporterFBX> importer;
+		importer.instantiate();
+		ResourceImporterScene::get_scene_singleton()->add_importer(importer);
+
+		Ref<EditorFileSystemImportFormatSupportQueryFBX> fbx_import_query;
+		fbx_import_query.instantiate();
+		EditorFileSystem::get_singleton()->add_import_format_support_query(fbx_import_query);
 	}
 	}
 }
 }
 #endif // TOOLS_ENABLED
 #endif // TOOLS_ENABLED