| 1 | /**************************************************************************/ |
| 2 | /* fbx_importer_manager.cpp */ |
| 3 | /**************************************************************************/ |
| 4 | /* This file is part of: */ |
| 5 | /* GODOT ENGINE */ |
| 6 | /* https://godotengine.org */ |
| 7 | /**************************************************************************/ |
| 8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
| 9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
| 10 | /* */ |
| 11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
| 12 | /* a copy of this software and associated documentation files (the */ |
| 13 | /* "Software"), to deal in the Software without restriction, including */ |
| 14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
| 15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
| 16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
| 17 | /* the following conditions: */ |
| 18 | /* */ |
| 19 | /* The above copyright notice and this permission notice shall be */ |
| 20 | /* included in all copies or substantial portions of the Software. */ |
| 21 | /* */ |
| 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
| 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
| 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
| 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
| 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
| 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
| 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
| 29 | /**************************************************************************/ |
| 30 | |
| 31 | #include "fbx_importer_manager.h" |
| 32 | |
| 33 | #include "core/config/project_settings.h" |
| 34 | #include "editor/editor_node.h" |
| 35 | #include "editor/editor_scale.h" |
| 36 | #include "editor/editor_settings.h" |
| 37 | #include "editor/editor_string_names.h" |
| 38 | #include "scene/gui/link_button.h" |
| 39 | |
| 40 | void FBXImporterManager::_notification(int p_what) { |
| 41 | switch (p_what) { |
| 42 | case NOTIFICATION_READY: { |
| 43 | connect("confirmed" , callable_mp(this, &FBXImporterManager::_path_confirmed)); |
| 44 | } break; |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | void FBXImporterManager::show_dialog(bool p_exclusive) { |
| 49 | String fbx2gltf_path = EDITOR_GET("filesystem/import/fbx/fbx2gltf_path" ); |
| 50 | fbx_path->set_text(fbx2gltf_path); |
| 51 | _validate_path(fbx2gltf_path); |
| 52 | |
| 53 | // If exclusive, we're importing a FBX file, there's no exit. |
| 54 | is_importing = p_exclusive; |
| 55 | set_flag(Window::FLAG_BORDERLESS, p_exclusive); // Avoid closing accidentally. |
| 56 | set_close_on_escape(!p_exclusive); |
| 57 | |
| 58 | if (is_importing) { |
| 59 | get_cancel_button()->set_text(TTR("Disable FBX & Restart" )); |
| 60 | get_cancel_button()->set_tooltip_text(TTR("Canceling this dialog will disable the FBX importer.\nYou can re-enable it in the Project Settings under Filesystem > Import > FBX > Enabled.\n\nThe editor will restart as importers are registered when the editor starts." )); |
| 61 | } else { |
| 62 | get_cancel_button()->set_text(TTR("Cancel" )); |
| 63 | get_cancel_button()->set_tooltip_text("" ); |
| 64 | } |
| 65 | |
| 66 | popup_centered(); |
| 67 | } |
| 68 | |
| 69 | void FBXImporterManager::_validate_path(const String &p_path) { |
| 70 | String error; |
| 71 | bool success = false; |
| 72 | |
| 73 | if (p_path == "" ) { |
| 74 | error = TTR("Path to FBX2glTF executable is empty." ); |
| 75 | } else if (!FileAccess::exists(p_path)) { |
| 76 | error = TTR("Path to FBX2glTF executable is invalid." ); |
| 77 | } else { |
| 78 | List<String> args; |
| 79 | args.push_back("--version" ); |
| 80 | int exitcode; |
| 81 | Error err = OS::get_singleton()->execute(p_path, args, nullptr, &exitcode); |
| 82 | |
| 83 | if (err == OK && exitcode == 0) { |
| 84 | success = true; |
| 85 | } else { |
| 86 | error = TTR("Error executing this file (wrong version or architecture)." ); |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | if (success) { |
| 91 | path_status->set_text(TTR("FBX2glTF executable is valid." )); |
| 92 | path_status->add_theme_color_override("font_color" , path_status->get_theme_color(SNAME("success_color" ), EditorStringName(Editor))); |
| 93 | get_ok_button()->set_disabled(false); |
| 94 | } else { |
| 95 | path_status->set_text(error); |
| 96 | path_status->add_theme_color_override("font_color" , path_status->get_theme_color(SNAME("error_color" ), EditorStringName(Editor))); |
| 97 | get_ok_button()->set_disabled(true); |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | void FBXImporterManager::_select_file(const String &p_path) { |
| 102 | fbx_path->set_text(p_path); |
| 103 | _validate_path(p_path); |
| 104 | } |
| 105 | |
| 106 | void FBXImporterManager::_path_confirmed() { |
| 107 | String path = fbx_path->get_text(); |
| 108 | EditorSettings::get_singleton()->set("filesystem/import/fbx/fbx2gltf_path" , path); |
| 109 | EditorSettings::get_singleton()->save(); |
| 110 | } |
| 111 | |
| 112 | void FBXImporterManager::_cancel_setup() { |
| 113 | if (!is_importing) { |
| 114 | return; // No worry. |
| 115 | } |
| 116 | // No escape. |
| 117 | ProjectSettings::get_singleton()->set("filesystem/import/fbx/enabled" , false); |
| 118 | ProjectSettings::get_singleton()->save(); |
| 119 | EditorNode::get_singleton()->save_all_scenes(); |
| 120 | EditorNode::get_singleton()->restart_editor(); |
| 121 | } |
| 122 | |
| 123 | void FBXImporterManager::_browse_install() { |
| 124 | if (fbx_path->get_text() != String()) { |
| 125 | browse_dialog->set_current_file(fbx_path->get_text()); |
| 126 | } |
| 127 | |
| 128 | browse_dialog->popup_centered_ratio(); |
| 129 | } |
| 130 | |
| 131 | FBXImporterManager *FBXImporterManager::singleton = nullptr; |
| 132 | |
| 133 | FBXImporterManager::FBXImporterManager() { |
| 134 | singleton = this; |
| 135 | |
| 136 | set_title(TTR("Configure FBX Importer" )); |
| 137 | |
| 138 | VBoxContainer *vb = memnew(VBoxContainer); |
| 139 | vb->add_child(memnew(Label(TTR("FBX2glTF is required for importing FBX files.\nPlease download it and provide a valid path to the binary:" )))); |
| 140 | LinkButton *lb = memnew(LinkButton); |
| 141 | lb->set_text(TTR("Click this link to download FBX2glTF" )); |
| 142 | lb->set_uri("https://godotengine.org/fbx-import" ); |
| 143 | vb->add_child(lb); |
| 144 | |
| 145 | HBoxContainer *hb = memnew(HBoxContainer); |
| 146 | |
| 147 | fbx_path = memnew(LineEdit); |
| 148 | fbx_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); |
| 149 | hb->add_child(fbx_path); |
| 150 | fbx_path_browse = memnew(Button); |
| 151 | hb->add_child(fbx_path_browse); |
| 152 | fbx_path_browse->set_text(TTR("Browse" )); |
| 153 | fbx_path_browse->connect("pressed" , callable_mp(this, &FBXImporterManager::_browse_install)); |
| 154 | hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); |
| 155 | hb->set_custom_minimum_size(Size2(400 * EDSCALE, 0)); |
| 156 | |
| 157 | vb->add_child(hb); |
| 158 | |
| 159 | path_status = memnew(Label); |
| 160 | vb->add_child(path_status); |
| 161 | |
| 162 | add_child(vb); |
| 163 | |
| 164 | fbx_path->connect("text_changed" , callable_mp(this, &FBXImporterManager::_validate_path)); |
| 165 | |
| 166 | get_ok_button()->set_text(TTR("Confirm Path" )); |
| 167 | get_cancel_button()->connect("pressed" , callable_mp(this, &FBXImporterManager::_cancel_setup)); |
| 168 | |
| 169 | browse_dialog = memnew(EditorFileDialog); |
| 170 | browse_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); |
| 171 | browse_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); |
| 172 | #ifdef WINDOWS_ENABLED |
| 173 | browse_dialog->add_filter("*.exe" ); |
| 174 | #endif |
| 175 | |
| 176 | browse_dialog->connect("file_selected" , callable_mp(this, &FBXImporterManager::_select_file)); |
| 177 | |
| 178 | add_child(browse_dialog); |
| 179 | } |
| 180 | |