Add a dialog for customizing FBX import

* If FBX files are found, a dialog will pop up asking to configure FBX2glTF.
* Dialog can also be accessed by going Editor -> Configure FBX Import.
* The dialog also shows a link to click to download the converter, which
  should contain instructions.
This commit is contained in:
reduz 2022-04-02 13:43:15 +02:00 committed by Rémi Verschelde
parent 0bb94df247
commit e93d991329
No known key found for this signature in database
GPG key ID: C3336907360768E1
7 changed files with 287 additions and 11 deletions

View file

@ -96,6 +96,7 @@
#include "editor/export/editor_export.h"
#include "editor/export/export_template_manager.h"
#include "editor/export/project_export.h"
#include "editor/fbx_importer_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/history_dock.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;
case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
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;
case SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE: {
custom_build_manage_templates->hide();
@ -6624,6 +6629,11 @@ EditorNode::EditorNode() {
gui_base->add_child(about);
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->add_button(TTR("Copy Text"), true, "copy");
gui_base->add_child(warning);
@ -6796,6 +6806,9 @@ EditorNode::EditorNode() {
#ifndef ANDROID_ENABLED
settings_menu->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
#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->set_name(TTR("Help"));

View file

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

View file

@ -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);
}

View file

@ -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

View file

@ -36,6 +36,7 @@
#include "core/config/project_settings.h"
#include "editor/editor_settings.h"
#include "main/main.h"
uint32_t EditorSceneFormatImporterFBX::get_import_flags() const {
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) {
}
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

View file

@ -33,6 +33,8 @@
#ifdef TOOLS_ENABLED
#include "editor/editor_file_system.h"
#include "editor/fbx_importer_manager.h"
#include "editor/import/resource_importer_scene.h"
class Animation;
@ -53,6 +55,15 @@ public:
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 // EDITOR_SCENE_IMPORTER_FBX_H

View file

@ -80,16 +80,13 @@ static void _editor_init() {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,
"filesystem/import/fbx/fbx2gltf_path", PROPERTY_HINT_GLOBAL_FILE));
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