2
0

resource_importer_scene.cpp 106 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697
  1. /**************************************************************************/
  2. /* resource_importer_scene.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. #include "resource_importer_scene.h"
  31. #include "core/error/error_macros.h"
  32. #include "core/io/resource_saver.h"
  33. #include "editor/editor_node.h"
  34. #include "editor/import/scene_import_settings.h"
  35. #include "scene/3d/area_3d.h"
  36. #include "scene/3d/collision_shape_3d.h"
  37. #include "scene/3d/importer_mesh_instance_3d.h"
  38. #include "scene/3d/mesh_instance_3d.h"
  39. #include "scene/3d/navigation_region_3d.h"
  40. #include "scene/3d/occluder_instance_3d.h"
  41. #include "scene/3d/physics_body_3d.h"
  42. #include "scene/3d/vehicle_body_3d.h"
  43. #include "scene/animation/animation_player.h"
  44. #include "scene/resources/animation.h"
  45. #include "scene/resources/box_shape_3d.h"
  46. #include "scene/resources/importer_mesh.h"
  47. #include "scene/resources/packed_scene.h"
  48. #include "scene/resources/resource_format_text.h"
  49. #include "scene/resources/separation_ray_shape_3d.h"
  50. #include "scene/resources/sphere_shape_3d.h"
  51. #include "scene/resources/surface_tool.h"
  52. #include "scene/resources/world_boundary_shape_3d.h"
  53. uint32_t EditorSceneFormatImporter::get_import_flags() const {
  54. uint32_t ret;
  55. if (GDVIRTUAL_CALL(_get_import_flags, ret)) {
  56. return ret;
  57. }
  58. ERR_FAIL_V(0);
  59. }
  60. void EditorSceneFormatImporter::get_extensions(List<String> *r_extensions) const {
  61. Vector<String> arr;
  62. if (GDVIRTUAL_CALL(_get_extensions, arr)) {
  63. for (int i = 0; i < arr.size(); i++) {
  64. r_extensions->push_back(arr[i]);
  65. }
  66. return;
  67. }
  68. ERR_FAIL();
  69. }
  70. Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) {
  71. Dictionary options_dict;
  72. for (const KeyValue<StringName, Variant> &elem : p_options) {
  73. options_dict[elem.key] = elem.value;
  74. }
  75. Object *ret = nullptr;
  76. if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, options_dict, ret)) {
  77. return Object::cast_to<Node>(ret);
  78. }
  79. ERR_FAIL_V(nullptr);
  80. }
  81. void EditorSceneFormatImporter::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
  82. GDVIRTUAL_CALL(_get_import_options, p_path);
  83. }
  84. Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const HashMap<StringName, Variant> &p_options) {
  85. Variant ret;
  86. GDVIRTUAL_CALL(_get_option_visibility, p_path, p_for_animation, p_option, ret);
  87. return ret;
  88. }
  89. void EditorSceneFormatImporter::_bind_methods() {
  90. GDVIRTUAL_BIND(_get_import_flags);
  91. GDVIRTUAL_BIND(_get_extensions);
  92. GDVIRTUAL_BIND(_import_scene, "path", "flags", "options");
  93. GDVIRTUAL_BIND(_get_import_options, "path");
  94. GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option");
  95. BIND_CONSTANT(IMPORT_SCENE);
  96. BIND_CONSTANT(IMPORT_ANIMATION);
  97. BIND_CONSTANT(IMPORT_FAIL_ON_MISSING_DEPENDENCIES);
  98. BIND_CONSTANT(IMPORT_GENERATE_TANGENT_ARRAYS);
  99. BIND_CONSTANT(IMPORT_USE_NAMED_SKIN_BINDS);
  100. BIND_CONSTANT(IMPORT_DISCARD_MESHES_AND_MATERIALS);
  101. }
  102. /////////////////////////////////
  103. void EditorScenePostImport::_bind_methods() {
  104. GDVIRTUAL_BIND(_post_import, "scene")
  105. ClassDB::bind_method(D_METHOD("get_source_file"), &EditorScenePostImport::get_source_file);
  106. }
  107. Node *EditorScenePostImport::post_import(Node *p_scene) {
  108. Object *ret;
  109. if (GDVIRTUAL_CALL(_post_import, p_scene, ret)) {
  110. return Object::cast_to<Node>(ret);
  111. }
  112. return p_scene;
  113. }
  114. String EditorScenePostImport::get_source_file() const {
  115. return source_file;
  116. }
  117. void EditorScenePostImport::init(const String &p_source_file) {
  118. source_file = p_source_file;
  119. }
  120. EditorScenePostImport::EditorScenePostImport() {
  121. }
  122. ///////////////////////////////////////////////////////
  123. Variant EditorScenePostImportPlugin::get_option_value(const StringName &p_name) const {
  124. ERR_FAIL_COND_V_MSG(current_options == nullptr && current_options_dict == nullptr, Variant(), "get_option_value called from a function where option values are not available.");
  125. ERR_FAIL_COND_V_MSG(current_options && !current_options->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
  126. ERR_FAIL_COND_V_MSG(current_options_dict && !current_options_dict->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
  127. if (current_options && current_options->has(p_name)) {
  128. return (*current_options)[p_name];
  129. }
  130. if (current_options_dict && current_options_dict->has(p_name)) {
  131. return (*current_options_dict)[p_name];
  132. }
  133. return Variant();
  134. }
  135. void EditorScenePostImportPlugin::add_import_option(const String &p_name, Variant p_default_value) {
  136. ERR_FAIL_COND_MSG(current_option_list == nullptr, "add_import_option() can only be called from get_import_options()");
  137. add_import_option_advanced(p_default_value.get_type(), p_name, p_default_value);
  138. }
  139. void EditorScenePostImportPlugin::add_import_option_advanced(Variant::Type p_type, const String &p_name, Variant p_default_value, PropertyHint p_hint, const String &p_hint_string, int p_usage_flags) {
  140. ERR_FAIL_COND_MSG(current_option_list == nullptr, "add_import_option_advanced() can only be called from get_import_options()");
  141. current_option_list->push_back(ResourceImporter::ImportOption(PropertyInfo(p_type, p_name, p_hint, p_hint_string, p_usage_flags), p_default_value));
  142. }
  143. void EditorScenePostImportPlugin::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
  144. current_option_list = r_options;
  145. GDVIRTUAL_CALL(_get_internal_import_options, p_category);
  146. current_option_list = nullptr;
  147. }
  148. Variant EditorScenePostImportPlugin::get_internal_option_visibility(InternalImportCategory p_category, bool p_for_animation, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  149. current_options = &p_options;
  150. Variant ret;
  151. GDVIRTUAL_CALL(_get_internal_option_visibility, p_category, p_for_animation, p_option, ret);
  152. current_options = nullptr;
  153. return ret;
  154. }
  155. Variant EditorScenePostImportPlugin::get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  156. current_options = &p_options;
  157. Variant ret;
  158. GDVIRTUAL_CALL(_get_internal_option_update_view_required, p_category, p_option, ret);
  159. current_options = nullptr;
  160. return ret;
  161. }
  162. void EditorScenePostImportPlugin::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) {
  163. current_options_dict = &p_options;
  164. GDVIRTUAL_CALL(_internal_process, p_category, p_base_scene, p_node, p_resource);
  165. current_options_dict = nullptr;
  166. }
  167. void EditorScenePostImportPlugin::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
  168. current_option_list = r_options;
  169. GDVIRTUAL_CALL(_get_import_options, p_path);
  170. current_option_list = nullptr;
  171. }
  172. Variant EditorScenePostImportPlugin::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  173. current_options = &p_options;
  174. Variant ret;
  175. GDVIRTUAL_CALL(_get_option_visibility, p_path, p_for_animation, p_option, ret);
  176. current_options = nullptr;
  177. return ret;
  178. }
  179. void EditorScenePostImportPlugin::pre_process(Node *p_scene, const HashMap<StringName, Variant> &p_options) {
  180. current_options = &p_options;
  181. GDVIRTUAL_CALL(_pre_process, p_scene);
  182. current_options = nullptr;
  183. }
  184. void EditorScenePostImportPlugin::post_process(Node *p_scene, const HashMap<StringName, Variant> &p_options) {
  185. current_options = &p_options;
  186. GDVIRTUAL_CALL(_post_process, p_scene);
  187. current_options = nullptr;
  188. }
  189. void EditorScenePostImportPlugin::_bind_methods() {
  190. ClassDB::bind_method(D_METHOD("get_option_value", "name"), &EditorScenePostImportPlugin::get_option_value);
  191. ClassDB::bind_method(D_METHOD("add_import_option", "name", "value"), &EditorScenePostImportPlugin::add_import_option);
  192. ClassDB::bind_method(D_METHOD("add_import_option_advanced", "type", "name", "default_value", "hint", "hint_string", "usage_flags"), &EditorScenePostImportPlugin::add_import_option_advanced, DEFVAL(PROPERTY_HINT_NONE), DEFVAL(""), DEFVAL(PROPERTY_USAGE_DEFAULT));
  193. GDVIRTUAL_BIND(_get_internal_import_options, "category");
  194. GDVIRTUAL_BIND(_get_internal_option_visibility, "category", "for_animation", "option");
  195. GDVIRTUAL_BIND(_get_internal_option_update_view_required, "category", "option");
  196. GDVIRTUAL_BIND(_internal_process, "category", "base_node", "node", "resource");
  197. GDVIRTUAL_BIND(_get_import_options, "path");
  198. GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option");
  199. GDVIRTUAL_BIND(_pre_process, "scene");
  200. GDVIRTUAL_BIND(_post_process, "scene");
  201. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_NODE);
  202. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE);
  203. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MESH);
  204. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MATERIAL);
  205. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION);
  206. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE);
  207. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE);
  208. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MAX);
  209. }
  210. /////////////////////////////////////////////////////////
  211. String ResourceImporterScene::get_importer_name() const {
  212. return animation_importer ? "animation_library" : "scene";
  213. }
  214. String ResourceImporterScene::get_visible_name() const {
  215. return animation_importer ? "Animation Library" : "Scene";
  216. }
  217. void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const {
  218. for (Ref<EditorSceneFormatImporter> importer_elem : importers) {
  219. importer_elem->get_extensions(p_extensions);
  220. }
  221. }
  222. String ResourceImporterScene::get_save_extension() const {
  223. return animation_importer ? "res" : "scn";
  224. }
  225. String ResourceImporterScene::get_resource_type() const {
  226. return animation_importer ? "AnimationLibrary" : "PackedScene";
  227. }
  228. int ResourceImporterScene::get_format_version() const {
  229. return 1;
  230. }
  231. bool ResourceImporterScene::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  232. if (animation_importer) {
  233. if (p_option == "animation/import") { // Option ignored, animation always imported.
  234. return false;
  235. }
  236. } else if (p_option.begins_with("animation/")) {
  237. if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
  238. return false;
  239. }
  240. }
  241. if (animation_importer && (p_option.begins_with("nodes/") || p_option.begins_with("meshes/") || p_option.begins_with("skins/"))) {
  242. return false; // Nothing to do here for animations.
  243. }
  244. if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) != 2) {
  245. // Only display the lightmap texel size import option when using the Static Lightmaps light baking mode.
  246. return false;
  247. }
  248. for (int i = 0; i < post_importer_plugins.size(); i++) {
  249. Variant ret = post_importer_plugins.write[i]->get_option_visibility(p_path, animation_importer, p_option, p_options);
  250. if (ret.get_type() == Variant::BOOL) {
  251. return ret;
  252. }
  253. }
  254. for (Ref<EditorSceneFormatImporter> importer : importers) {
  255. Variant ret = importer->get_option_visibility(p_path, animation_importer, p_option, p_options);
  256. if (ret.get_type() == Variant::BOOL) {
  257. return ret;
  258. }
  259. }
  260. return true;
  261. }
  262. int ResourceImporterScene::get_preset_count() const {
  263. return 0;
  264. }
  265. String ResourceImporterScene::get_preset_name(int p_idx) const {
  266. return String();
  267. }
  268. static bool _teststr(const String &p_what, const String &p_str) {
  269. String what = p_what;
  270. //remove trailing spaces and numbers, some apps like blender add ".number" to duplicates so also compensate for this
  271. while (what.length() && (is_digit(what[what.length() - 1]) || what[what.length() - 1] <= 32 || what[what.length() - 1] == '.')) {
  272. what = what.substr(0, what.length() - 1);
  273. }
  274. if (what.findn("$" + p_str) != -1) { //blender and other stuff
  275. return true;
  276. }
  277. if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
  278. return true;
  279. }
  280. if (what.to_lower().ends_with("_" + p_str)) { //collada only supports "_" and "-" besides letters
  281. return true;
  282. }
  283. return false;
  284. }
  285. static String _fixstr(const String &p_what, const String &p_str) {
  286. String what = p_what;
  287. //remove trailing spaces and numbers, some apps like blender add ".number" to duplicates so also compensate for this
  288. while (what.length() && (is_digit(what[what.length() - 1]) || what[what.length() - 1] <= 32 || what[what.length() - 1] == '.')) {
  289. what = what.substr(0, what.length() - 1);
  290. }
  291. String end = p_what.substr(what.length(), p_what.length() - what.length());
  292. if (what.findn("$" + p_str) != -1) { //blender and other stuff
  293. return what.replace("$" + p_str, "") + end;
  294. }
  295. if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
  296. return what.substr(0, what.length() - (p_str.length() + 1)) + end;
  297. }
  298. if (what.to_lower().ends_with("_" + p_str)) { //collada only supports "_" and "-" besides letters
  299. return what.substr(0, what.length() - (p_str.length() + 1)) + end;
  300. }
  301. return what;
  302. }
  303. static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r_shape_list, bool p_convex) {
  304. ERR_FAIL_NULL_MSG(mesh, "Cannot generate shape list with null mesh value");
  305. if (!p_convex) {
  306. Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape();
  307. r_shape_list.push_back(shape);
  308. } else {
  309. Vector<Ref<Shape3D>> cd;
  310. cd.push_back(mesh->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
  311. if (cd.size()) {
  312. for (int i = 0; i < cd.size(); i++) {
  313. r_shape_list.push_back(cd[i]);
  314. }
  315. }
  316. }
  317. }
  318. struct ScalableNodeCollection {
  319. HashSet<Node3D *> node_3ds;
  320. HashSet<Ref<ImporterMesh>> importer_meshes;
  321. HashSet<Ref<Skin>> skins;
  322. HashSet<Ref<Animation>> animations;
  323. };
  324. void _rescale_importer_mesh(Vector3 p_scale, Ref<ImporterMesh> p_mesh, bool is_shadow = false) {
  325. // MESH and SKIN data divide, to compensate for object position multiplying.
  326. const int surf_count = p_mesh->get_surface_count();
  327. const int blendshape_count = p_mesh->get_blend_shape_count();
  328. struct LocalSurfData {
  329. Mesh::PrimitiveType prim = {};
  330. Array arr;
  331. Array bsarr;
  332. Dictionary lods;
  333. String name;
  334. Ref<Material> mat;
  335. int fmt_compress_flags = 0;
  336. };
  337. Vector<LocalSurfData> surf_data_by_mesh;
  338. Vector<String> blendshape_names;
  339. for (int bsidx = 0; bsidx < blendshape_count; bsidx++) {
  340. blendshape_names.append(p_mesh->get_blend_shape_name(bsidx));
  341. }
  342. for (int surf_idx = 0; surf_idx < surf_count; surf_idx++) {
  343. Mesh::PrimitiveType prim = p_mesh->get_surface_primitive_type(surf_idx);
  344. const int fmt_compress_flags = p_mesh->get_surface_format(surf_idx);
  345. Array arr = p_mesh->get_surface_arrays(surf_idx);
  346. String name = p_mesh->get_surface_name(surf_idx);
  347. Dictionary lods;
  348. Ref<Material> mat = p_mesh->get_surface_material(surf_idx);
  349. {
  350. Vector<Vector3> vertex_array = arr[ArrayMesh::ARRAY_VERTEX];
  351. for (int vert_arr_i = 0; vert_arr_i < vertex_array.size(); vert_arr_i++) {
  352. vertex_array.write[vert_arr_i] = vertex_array[vert_arr_i] * p_scale;
  353. }
  354. arr[ArrayMesh::ARRAY_VERTEX] = vertex_array;
  355. }
  356. Array blendshapes;
  357. for (int bsidx = 0; bsidx < blendshape_count; bsidx++) {
  358. Array current_bsarr = p_mesh->get_surface_blend_shape_arrays(surf_idx, bsidx);
  359. Vector<Vector3> current_bs_vertex_array = current_bsarr[ArrayMesh::ARRAY_VERTEX];
  360. int current_bs_vert_arr_len = current_bs_vertex_array.size();
  361. for (int32_t bs_vert_arr_i = 0; bs_vert_arr_i < current_bs_vert_arr_len; bs_vert_arr_i++) {
  362. current_bs_vertex_array.write[bs_vert_arr_i] = current_bs_vertex_array[bs_vert_arr_i] * p_scale;
  363. }
  364. current_bsarr[ArrayMesh::ARRAY_VERTEX] = current_bs_vertex_array;
  365. blendshapes.push_back(current_bsarr);
  366. }
  367. LocalSurfData surf_data_dictionary = LocalSurfData();
  368. surf_data_dictionary.prim = prim;
  369. surf_data_dictionary.arr = arr;
  370. surf_data_dictionary.bsarr = blendshapes;
  371. surf_data_dictionary.lods = lods;
  372. surf_data_dictionary.fmt_compress_flags = fmt_compress_flags;
  373. surf_data_dictionary.name = name;
  374. surf_data_dictionary.mat = mat;
  375. surf_data_by_mesh.push_back(surf_data_dictionary);
  376. }
  377. p_mesh->clear();
  378. for (int bsidx = 0; bsidx < blendshape_count; bsidx++) {
  379. p_mesh->add_blend_shape(blendshape_names[bsidx]);
  380. }
  381. for (int surf_idx = 0; surf_idx < surf_count; surf_idx++) {
  382. const Mesh::PrimitiveType prim = surf_data_by_mesh[surf_idx].prim;
  383. const Array arr = surf_data_by_mesh[surf_idx].arr;
  384. const Array bsarr = surf_data_by_mesh[surf_idx].bsarr;
  385. const Dictionary lods = surf_data_by_mesh[surf_idx].lods;
  386. const int fmt_compress_flags = surf_data_by_mesh[surf_idx].fmt_compress_flags;
  387. const String name = surf_data_by_mesh[surf_idx].name;
  388. const Ref<Material> mat = surf_data_by_mesh[surf_idx].mat;
  389. p_mesh->add_surface(prim, arr, bsarr, lods, mat, name, fmt_compress_flags);
  390. }
  391. if (!is_shadow && p_mesh->get_shadow_mesh() != p_mesh && p_mesh->get_shadow_mesh().is_valid()) {
  392. _rescale_importer_mesh(p_scale, p_mesh->get_shadow_mesh(), true);
  393. }
  394. }
  395. void _rescale_skin(Vector3 p_scale, Ref<Skin> p_skin) {
  396. // MESH and SKIN data divide, to compensate for object position multiplying.
  397. for (int i = 0; i < p_skin->get_bind_count(); i++) {
  398. Transform3D transform = p_skin->get_bind_pose(i);
  399. p_skin->set_bind_pose(i, Transform3D(transform.basis, p_scale * transform.origin));
  400. }
  401. }
  402. void _rescale_animation(Vector3 p_scale, Ref<Animation> p_animation) {
  403. for (int track_idx = 0; track_idx < p_animation->get_track_count(); track_idx++) {
  404. if (p_animation->track_get_type(track_idx) == Animation::TYPE_POSITION_3D) {
  405. for (int key_idx = 0; key_idx < p_animation->track_get_key_count(track_idx); key_idx++) {
  406. Vector3 value = p_animation->track_get_key_value(track_idx, key_idx);
  407. value = p_scale * value;
  408. p_animation->track_set_key_value(track_idx, key_idx, value);
  409. }
  410. }
  411. }
  412. }
  413. void _apply_basis_to_scalable_node_collection(ScalableNodeCollection &p_dictionary, Vector3 p_scale) {
  414. for (Node3D *node_3d : p_dictionary.node_3ds) {
  415. if (node_3d) {
  416. node_3d->set_position(p_scale * node_3d->get_position());
  417. Skeleton3D *skeleton_3d = Object::cast_to<Skeleton3D>(node_3d);
  418. if (skeleton_3d) {
  419. for (int i = 0; i < skeleton_3d->get_bone_count(); i++) {
  420. Transform3D rest = skeleton_3d->get_bone_rest(i);
  421. skeleton_3d->set_bone_rest(i, Transform3D(rest.basis, p_scale * rest.origin));
  422. skeleton_3d->set_bone_pose_position(i, p_scale * rest.origin);
  423. }
  424. }
  425. }
  426. }
  427. for (Ref<ImporterMesh> mesh : p_dictionary.importer_meshes) {
  428. _rescale_importer_mesh(p_scale, mesh, false);
  429. }
  430. for (Ref<Skin> skin : p_dictionary.skins) {
  431. _rescale_skin(p_scale, skin);
  432. }
  433. for (Ref<Animation> animation : p_dictionary.animations) {
  434. _rescale_animation(p_scale, animation);
  435. }
  436. }
  437. void _populate_scalable_nodes_collection(Node *p_node, ScalableNodeCollection &p_dictionary) {
  438. if (!p_node) {
  439. return;
  440. }
  441. Node3D *node_3d = Object::cast_to<Node3D>(p_node);
  442. if (node_3d) {
  443. p_dictionary.node_3ds.insert(node_3d);
  444. ImporterMeshInstance3D *mesh_instance_3d = Object::cast_to<ImporterMeshInstance3D>(p_node);
  445. if (mesh_instance_3d) {
  446. Ref<ImporterMesh> mesh = mesh_instance_3d->get_mesh();
  447. if (mesh.is_valid()) {
  448. p_dictionary.importer_meshes.insert(mesh);
  449. }
  450. Ref<Skin> skin = mesh_instance_3d->get_skin();
  451. if (skin.is_valid()) {
  452. p_dictionary.skins.insert(skin);
  453. }
  454. }
  455. }
  456. AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_node);
  457. if (animation_player) {
  458. List<StringName> animation_list;
  459. animation_player->get_animation_list(&animation_list);
  460. for (const StringName &E : animation_list) {
  461. Ref<Animation> animation = animation_player->get_animation(E);
  462. p_dictionary.animations.insert(animation);
  463. }
  464. }
  465. for (int i = 0; i < p_node->get_child_count(); i++) {
  466. Node *child = p_node->get_child(i);
  467. _populate_scalable_nodes_collection(child, p_dictionary);
  468. }
  469. }
  470. void _apply_permanent_rotation_scale_to_node(Node *p_node) {
  471. Transform3D transform = Object::cast_to<Node3D>(p_node)->get_transform();
  472. ScalableNodeCollection scalable_node_collection;
  473. _populate_scalable_nodes_collection(p_node, scalable_node_collection);
  474. _apply_basis_to_scalable_node_collection(scalable_node_collection, transform.basis.get_scale());
  475. }
  476. Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames) {
  477. // Children first.
  478. for (int i = 0; i < p_node->get_child_count(); i++) {
  479. Node *r = _pre_fix_node(p_node->get_child(i), p_root, r_collision_map, r_occluder_arrays, r_node_renames);
  480. if (!r) {
  481. i--; // Was erased.
  482. }
  483. }
  484. String name = p_node->get_name();
  485. NodePath original_path = p_root->get_path_to(p_node); // Used to detect renames due to import hints.
  486. bool isroot = p_node == p_root;
  487. if (!isroot && _teststr(name, "noimp")) {
  488. p_node->set_owner(nullptr);
  489. memdelete(p_node);
  490. return nullptr;
  491. }
  492. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  493. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  494. Ref<ImporterMesh> m = mi->get_mesh();
  495. if (m.is_valid()) {
  496. for (int i = 0; i < m->get_surface_count(); i++) {
  497. Ref<BaseMaterial3D> mat = m->get_surface_material(i);
  498. if (!mat.is_valid()) {
  499. continue;
  500. }
  501. if (_teststr(mat->get_name(), "alpha")) {
  502. mat->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
  503. mat->set_name(_fixstr(mat->get_name(), "alpha"));
  504. }
  505. if (_teststr(mat->get_name(), "vcol")) {
  506. mat->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  507. mat->set_flag(BaseMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
  508. mat->set_name(_fixstr(mat->get_name(), "vcol"));
  509. }
  510. }
  511. }
  512. }
  513. if (Object::cast_to<AnimationPlayer>(p_node)) {
  514. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  515. // Node paths in animation tracks are relative to the following path (this is used to fix node paths below).
  516. Node *ap_root = ap->get_node(ap->get_root());
  517. NodePath path_prefix = p_root->get_path_to(ap_root);
  518. bool nodes_were_renamed = r_node_renames.size() != 0;
  519. List<StringName> anims;
  520. ap->get_animation_list(&anims);
  521. for (const StringName &E : anims) {
  522. Ref<Animation> anim = ap->get_animation(E);
  523. ERR_CONTINUE(anim.is_null());
  524. // Remove animation tracks referencing non-importable nodes.
  525. for (int i = 0; i < anim->get_track_count(); i++) {
  526. NodePath path = anim->track_get_path(i);
  527. for (int j = 0; j < path.get_name_count(); j++) {
  528. String node = path.get_name(j);
  529. if (_teststr(node, "noimp")) {
  530. anim->remove_track(i);
  531. i--;
  532. break;
  533. }
  534. }
  535. }
  536. // Fix node paths in animations, in case nodes were renamed earlier due to import hints.
  537. if (nodes_were_renamed) {
  538. for (int i = 0; i < anim->get_track_count(); i++) {
  539. NodePath path = anim->track_get_path(i);
  540. // Convert track path to absolute node path without subnames (some manual work because we are not in the scene tree).
  541. Vector<StringName> absolute_path_names = path_prefix.get_names();
  542. absolute_path_names.append_array(path.get_names());
  543. NodePath absolute_path(absolute_path_names, false);
  544. absolute_path.simplify();
  545. // Fix paths to renamed nodes.
  546. for (const Pair<NodePath, Node *> &F : r_node_renames) {
  547. if (F.first == absolute_path) {
  548. NodePath new_path(ap_root->get_path_to(F.second).get_names(), path.get_subnames(), false);
  549. print_verbose(vformat("Fix: Correcting node path in animation track: %s should be %s", path, new_path));
  550. anim->track_set_path(i, new_path);
  551. break; // Only one match is possible.
  552. }
  553. }
  554. }
  555. }
  556. String animname = E;
  557. const int loop_string_count = 3;
  558. static const char *loop_strings[loop_string_count] = { "loop_mode", "loop", "cycle" };
  559. for (int i = 0; i < loop_string_count; i++) {
  560. if (_teststr(animname, loop_strings[i])) {
  561. anim->set_loop_mode(Animation::LOOP_LINEAR);
  562. animname = _fixstr(animname, loop_strings[i]);
  563. Ref<AnimationLibrary> library = ap->get_animation_library(ap->find_animation_library(anim));
  564. library->rename_animation(E, animname);
  565. }
  566. }
  567. }
  568. }
  569. if (_teststr(name, "colonly") || _teststr(name, "convcolonly")) {
  570. if (isroot) {
  571. return p_node;
  572. }
  573. String fixed_name;
  574. if (_teststr(name, "colonly")) {
  575. fixed_name = _fixstr(name, "colonly");
  576. } else if (_teststr(name, "convcolonly")) {
  577. fixed_name = _fixstr(name, "convcolonly");
  578. }
  579. ERR_FAIL_COND_V(fixed_name.is_empty(), nullptr);
  580. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  581. if (mi) {
  582. Ref<ImporterMesh> mesh = mi->get_mesh();
  583. if (mesh.is_valid()) {
  584. Vector<Ref<Shape3D>> shapes;
  585. if (r_collision_map.has(mesh)) {
  586. shapes = r_collision_map[mesh];
  587. } else if (_teststr(name, "colonly")) {
  588. _pre_gen_shape_list(mesh, shapes, false);
  589. r_collision_map[mesh] = shapes;
  590. } else if (_teststr(name, "convcolonly")) {
  591. _pre_gen_shape_list(mesh, shapes, true);
  592. r_collision_map[mesh] = shapes;
  593. }
  594. if (shapes.size()) {
  595. StaticBody3D *col = memnew(StaticBody3D);
  596. col->set_transform(mi->get_transform());
  597. col->set_name(fixed_name);
  598. p_node->replace_by(col);
  599. p_node->set_owner(nullptr);
  600. memdelete(p_node);
  601. p_node = col;
  602. _add_shapes(col, shapes);
  603. }
  604. }
  605. } else if (p_node->has_meta("empty_draw_type")) {
  606. String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
  607. StaticBody3D *sb = memnew(StaticBody3D);
  608. sb->set_name(fixed_name);
  609. Object::cast_to<Node3D>(sb)->set_transform(Object::cast_to<Node3D>(p_node)->get_transform());
  610. p_node->replace_by(sb);
  611. p_node->set_owner(nullptr);
  612. memdelete(p_node);
  613. p_node = sb;
  614. CollisionShape3D *colshape = memnew(CollisionShape3D);
  615. if (empty_draw_type == "CUBE") {
  616. BoxShape3D *boxShape = memnew(BoxShape3D);
  617. boxShape->set_size(Vector3(2, 2, 2));
  618. colshape->set_shape(boxShape);
  619. } else if (empty_draw_type == "SINGLE_ARROW") {
  620. SeparationRayShape3D *rayShape = memnew(SeparationRayShape3D);
  621. rayShape->set_length(1);
  622. colshape->set_shape(rayShape);
  623. Object::cast_to<Node3D>(sb)->rotate_x(Math_PI / 2);
  624. } else if (empty_draw_type == "IMAGE") {
  625. WorldBoundaryShape3D *world_boundary_shape = memnew(WorldBoundaryShape3D);
  626. colshape->set_shape(world_boundary_shape);
  627. } else {
  628. SphereShape3D *sphereShape = memnew(SphereShape3D);
  629. sphereShape->set_radius(1);
  630. colshape->set_shape(sphereShape);
  631. }
  632. sb->add_child(colshape, true);
  633. colshape->set_owner(sb->get_owner());
  634. }
  635. } else if (_teststr(name, "rigid") && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  636. if (isroot) {
  637. return p_node;
  638. }
  639. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  640. Ref<ImporterMesh> mesh = mi->get_mesh();
  641. if (mesh.is_valid()) {
  642. Vector<Ref<Shape3D>> shapes;
  643. if (r_collision_map.has(mesh)) {
  644. shapes = r_collision_map[mesh];
  645. } else {
  646. _pre_gen_shape_list(mesh, shapes, true);
  647. }
  648. RigidBody3D *rigid_body = memnew(RigidBody3D);
  649. rigid_body->set_name(_fixstr(name, "rigid_body"));
  650. p_node->replace_by(rigid_body);
  651. rigid_body->set_transform(mi->get_transform());
  652. p_node = rigid_body;
  653. mi->set_transform(Transform3D());
  654. rigid_body->add_child(mi, true);
  655. mi->set_owner(rigid_body->get_owner());
  656. _add_shapes(rigid_body, shapes);
  657. }
  658. } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  659. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  660. Ref<ImporterMesh> mesh = mi->get_mesh();
  661. if (mesh.is_valid()) {
  662. Vector<Ref<Shape3D>> shapes;
  663. String fixed_name;
  664. if (r_collision_map.has(mesh)) {
  665. shapes = r_collision_map[mesh];
  666. } else if (_teststr(name, "col")) {
  667. _pre_gen_shape_list(mesh, shapes, false);
  668. r_collision_map[mesh] = shapes;
  669. } else if (_teststr(name, "convcol")) {
  670. _pre_gen_shape_list(mesh, shapes, true);
  671. r_collision_map[mesh] = shapes;
  672. }
  673. if (_teststr(name, "col")) {
  674. fixed_name = _fixstr(name, "col");
  675. } else if (_teststr(name, "convcol")) {
  676. fixed_name = _fixstr(name, "convcol");
  677. }
  678. if (!fixed_name.is_empty()) {
  679. if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
  680. mi->set_name(fixed_name);
  681. }
  682. }
  683. if (shapes.size()) {
  684. StaticBody3D *col = memnew(StaticBody3D);
  685. mi->add_child(col, true);
  686. col->set_owner(mi->get_owner());
  687. _add_shapes(col, shapes);
  688. }
  689. }
  690. } else if (_teststr(name, "navmesh") && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  691. if (isroot) {
  692. return p_node;
  693. }
  694. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  695. Ref<ImporterMesh> mesh = mi->get_mesh();
  696. ERR_FAIL_COND_V(mesh.is_null(), nullptr);
  697. NavigationRegion3D *nmi = memnew(NavigationRegion3D);
  698. nmi->set_name(_fixstr(name, "navmesh"));
  699. Ref<NavigationMesh> nmesh = mesh->create_navigation_mesh();
  700. nmi->set_navigation_mesh(nmesh);
  701. Object::cast_to<Node3D>(nmi)->set_transform(mi->get_transform());
  702. p_node->replace_by(nmi);
  703. p_node->set_owner(nullptr);
  704. memdelete(p_node);
  705. p_node = nmi;
  706. } else if (_teststr(name, "occ") || _teststr(name, "occonly")) {
  707. if (isroot) {
  708. return p_node;
  709. }
  710. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  711. if (mi) {
  712. Ref<ImporterMesh> mesh = mi->get_mesh();
  713. if (mesh.is_valid()) {
  714. if (r_occluder_arrays) {
  715. OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second);
  716. }
  717. if (_teststr(name, "occ")) {
  718. String fixed_name = _fixstr(name, "occ");
  719. if (!fixed_name.is_empty()) {
  720. if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
  721. mi->set_name(fixed_name);
  722. }
  723. }
  724. } else {
  725. p_node->set_owner(nullptr);
  726. memdelete(p_node);
  727. p_node = nullptr;
  728. }
  729. }
  730. }
  731. } else if (_teststr(name, "vehicle")) {
  732. if (isroot) {
  733. return p_node;
  734. }
  735. Node *owner = p_node->get_owner();
  736. Node3D *s = Object::cast_to<Node3D>(p_node);
  737. VehicleBody3D *bv = memnew(VehicleBody3D);
  738. String n = _fixstr(p_node->get_name(), "vehicle");
  739. bv->set_name(n);
  740. p_node->replace_by(bv);
  741. p_node->set_name(n);
  742. bv->add_child(p_node);
  743. bv->set_owner(owner);
  744. p_node->set_owner(owner);
  745. bv->set_transform(s->get_transform());
  746. s->set_transform(Transform3D());
  747. p_node = bv;
  748. } else if (_teststr(name, "wheel")) {
  749. if (isroot) {
  750. return p_node;
  751. }
  752. Node *owner = p_node->get_owner();
  753. Node3D *s = Object::cast_to<Node3D>(p_node);
  754. VehicleWheel3D *bv = memnew(VehicleWheel3D);
  755. String n = _fixstr(p_node->get_name(), "wheel");
  756. bv->set_name(n);
  757. p_node->replace_by(bv);
  758. p_node->set_name(n);
  759. bv->add_child(p_node);
  760. bv->set_owner(owner);
  761. p_node->set_owner(owner);
  762. bv->set_transform(s->get_transform());
  763. s->set_transform(Transform3D());
  764. p_node = bv;
  765. } else if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  766. //last attempt, maybe collision inside the mesh data
  767. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  768. Ref<ImporterMesh> mesh = mi->get_mesh();
  769. if (!mesh.is_null()) {
  770. Vector<Ref<Shape3D>> shapes;
  771. if (r_collision_map.has(mesh)) {
  772. shapes = r_collision_map[mesh];
  773. } else if (_teststr(mesh->get_name(), "col")) {
  774. _pre_gen_shape_list(mesh, shapes, false);
  775. r_collision_map[mesh] = shapes;
  776. mesh->set_name(_fixstr(mesh->get_name(), "col"));
  777. } else if (_teststr(mesh->get_name(), "convcol")) {
  778. _pre_gen_shape_list(mesh, shapes, true);
  779. r_collision_map[mesh] = shapes;
  780. mesh->set_name(_fixstr(mesh->get_name(), "convcol"));
  781. } else if (_teststr(mesh->get_name(), "occ")) {
  782. if (r_occluder_arrays) {
  783. OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second);
  784. }
  785. mesh->set_name(_fixstr(mesh->get_name(), "occ"));
  786. }
  787. if (shapes.size()) {
  788. StaticBody3D *col = memnew(StaticBody3D);
  789. p_node->add_child(col, true);
  790. col->set_owner(p_node->get_owner());
  791. _add_shapes(col, shapes);
  792. }
  793. }
  794. }
  795. if (p_node) {
  796. NodePath new_path = p_root->get_path_to(p_node);
  797. if (new_path != original_path) {
  798. print_verbose(vformat("Fix: Renamed %s to %s", original_path, new_path));
  799. r_node_renames.push_back({ original_path, p_node });
  800. }
  801. }
  802. return p_node;
  803. }
  804. Node *ResourceImporterScene::_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps) {
  805. // children first
  806. for (int i = 0; i < p_node->get_child_count(); i++) {
  807. Node *r = _pre_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps);
  808. if (!r) {
  809. i--; //was erased
  810. }
  811. }
  812. String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node));
  813. Dictionary node_settings;
  814. if (p_node_data.has(import_id)) {
  815. node_settings = p_node_data[import_id];
  816. }
  817. {
  818. //make sure this is unique
  819. node_settings = node_settings.duplicate(true);
  820. //fill node settings for this node with default values
  821. List<ImportOption> iopts;
  822. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
  823. for (const ImportOption &E : iopts) {
  824. if (!node_settings.has(E.option.name)) {
  825. node_settings[E.option.name] = E.default_value;
  826. }
  827. }
  828. }
  829. if (Object::cast_to<AnimationPlayer>(p_node)) {
  830. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  831. List<StringName> anims;
  832. ap->get_animation_list(&anims);
  833. for (const StringName &name : anims) {
  834. Ref<Animation> anim = ap->get_animation(name);
  835. Array animation_slices;
  836. if (p_animation_data.has(name)) {
  837. Dictionary anim_settings = p_animation_data[name];
  838. int slices_count = anim_settings["slices/amount"];
  839. for (int i = 0; i < slices_count; i++) {
  840. String slice_name = anim_settings["slice_" + itos(i + 1) + "/name"];
  841. int from_frame = anim_settings["slice_" + itos(i + 1) + "/start_frame"];
  842. int end_frame = anim_settings["slice_" + itos(i + 1) + "/end_frame"];
  843. Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)anim_settings["slice_" + itos(i + 1) + "/loop_mode"]);
  844. bool save_to_file = anim_settings["slice_" + itos(i + 1) + "/save_to_file/enabled"];
  845. bool save_to_path = anim_settings["slice_" + itos(i + 1) + "/save_to_file/path"];
  846. bool save_to_file_keep_custom = anim_settings["slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"];
  847. animation_slices.push_back(slice_name);
  848. animation_slices.push_back(from_frame / p_animation_fps);
  849. animation_slices.push_back(end_frame / p_animation_fps);
  850. animation_slices.push_back(loop_mode);
  851. animation_slices.push_back(save_to_file);
  852. animation_slices.push_back(save_to_path);
  853. animation_slices.push_back(save_to_file_keep_custom);
  854. }
  855. }
  856. if (animation_slices.size() > 0) {
  857. _create_slices(ap, anim, animation_slices, true);
  858. }
  859. }
  860. AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = {
  861. AnimationImportTracks(int(node_settings["import_tracks/position"])),
  862. AnimationImportTracks(int(node_settings["import_tracks/rotation"])),
  863. AnimationImportTracks(int(node_settings["import_tracks/scale"]))
  864. };
  865. if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) {
  866. _optimize_track_usage(ap, import_tracks_mode);
  867. }
  868. }
  869. return p_node;
  870. }
  871. Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps) {
  872. // children first
  873. for (int i = 0; i < p_node->get_child_count(); i++) {
  874. Node *r = _post_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps);
  875. if (!r) {
  876. i--; //was erased
  877. }
  878. }
  879. String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node));
  880. Dictionary node_settings;
  881. if (p_node_data.has(import_id)) {
  882. node_settings = p_node_data[import_id];
  883. }
  884. {
  885. //make sure this is unique
  886. node_settings = node_settings.duplicate(true);
  887. //fill node settings for this node with default values
  888. List<ImportOption> iopts;
  889. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
  890. for (const ImportOption &E : iopts) {
  891. if (!node_settings.has(E.option.name)) {
  892. node_settings[E.option.name] = E.default_value;
  893. }
  894. }
  895. }
  896. if (Object::cast_to<AnimationPlayer>(p_node)) {
  897. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  898. bool use_optimizer = node_settings["optimizer/enabled"];
  899. float anim_optimizer_linerr = node_settings["optimizer/max_velocity_error"];
  900. float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"];
  901. int anim_optimizer_preerr = node_settings["optimizer/max_precision_error"];
  902. if (use_optimizer) {
  903. _optimize_animations(ap, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_preerr);
  904. }
  905. bool use_compression = node_settings["compression/enabled"];
  906. int anim_compression_page_size = node_settings["compression/page_size"];
  907. if (use_compression) {
  908. _compress_animations(ap, anim_compression_page_size);
  909. }
  910. List<StringName> anims;
  911. ap->get_animation_list(&anims);
  912. for (const StringName &name : anims) {
  913. Ref<Animation> anim = ap->get_animation(name);
  914. if (p_animation_data.has(name)) {
  915. Dictionary anim_settings = p_animation_data[name];
  916. {
  917. //fill with default values
  918. List<ImportOption> iopts;
  919. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts);
  920. for (const ImportOption &F : iopts) {
  921. if (!anim_settings.has(F.option.name)) {
  922. anim_settings[F.option.name] = F.default_value;
  923. }
  924. }
  925. }
  926. anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"]));
  927. bool save = anim_settings["save_to_file/enabled"];
  928. String path = anim_settings["save_to_file/path"];
  929. bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"];
  930. Ref<Animation> saved_anim = _save_animation_to_file(anim, save, path, keep_custom);
  931. if (saved_anim != anim) {
  932. Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim));
  933. al->add_animation(name, saved_anim); //replace
  934. }
  935. }
  936. }
  937. }
  938. return p_node;
  939. }
  940. Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps, float p_applied_root_scale) {
  941. // children first
  942. for (int i = 0; i < p_node->get_child_count(); i++) {
  943. Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps, p_applied_root_scale);
  944. if (!r) {
  945. i--; //was erased
  946. }
  947. }
  948. bool isroot = p_node == p_root;
  949. String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node));
  950. Dictionary node_settings;
  951. if (p_node_data.has(import_id)) {
  952. node_settings = p_node_data[import_id];
  953. }
  954. if (!isroot && (node_settings.has("import/skip_import") && bool(node_settings["import/skip_import"]))) {
  955. p_node->set_owner(nullptr);
  956. memdelete(p_node);
  957. return nullptr;
  958. }
  959. {
  960. //make sure this is unique
  961. node_settings = node_settings.duplicate(true);
  962. //fill node settings for this node with default values
  963. List<ImportOption> iopts;
  964. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  965. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, &iopts);
  966. } else if (Object::cast_to<AnimationPlayer>(p_node)) {
  967. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
  968. } else if (Object::cast_to<Skeleton3D>(p_node)) {
  969. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE, &iopts);
  970. } else {
  971. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_NODE, &iopts);
  972. }
  973. for (const ImportOption &E : iopts) {
  974. if (!node_settings.has(E.option.name)) {
  975. node_settings[E.option.name] = E.default_value;
  976. }
  977. }
  978. }
  979. {
  980. ObjectID node_id = p_node->get_instance_id();
  981. for (int i = 0; i < post_importer_plugins.size(); i++) {
  982. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  983. if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
  984. break;
  985. }
  986. }
  987. }
  988. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  989. ObjectID node_id = p_node->get_instance_id();
  990. for (int i = 0; i < post_importer_plugins.size(); i++) {
  991. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  992. if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
  993. break;
  994. }
  995. }
  996. }
  997. if (Object::cast_to<Skeleton3D>(p_node)) {
  998. ObjectID node_id = p_node->get_instance_id();
  999. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1000. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  1001. if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
  1002. break;
  1003. }
  1004. }
  1005. }
  1006. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1007. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1008. Ref<ImporterMesh> m = mi->get_mesh();
  1009. if (m.is_valid()) {
  1010. if (!r_scanned_meshes.has(m)) {
  1011. for (int i = 0; i < m->get_surface_count(); i++) {
  1012. Ref<Material> mat = m->get_surface_material(i);
  1013. if (mat.is_valid()) {
  1014. String mat_id = mat->get_meta("import_id", mat->get_name());
  1015. if (!mat_id.is_empty() && p_material_data.has(mat_id)) {
  1016. Dictionary matdata = p_material_data[mat_id];
  1017. {
  1018. //fill node settings for this node with default values
  1019. List<ImportOption> iopts;
  1020. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MATERIAL, &iopts);
  1021. for (const ImportOption &E : iopts) {
  1022. if (!matdata.has(E.option.name)) {
  1023. matdata[E.option.name] = E.default_value;
  1024. }
  1025. }
  1026. }
  1027. for (int j = 0; j < post_importer_plugins.size(); j++) {
  1028. post_importer_plugins.write[j]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL, p_root, p_node, mat, matdata);
  1029. }
  1030. if (matdata.has("use_external/enabled") && bool(matdata["use_external/enabled"]) && matdata.has("use_external/path")) {
  1031. String path = matdata["use_external/path"];
  1032. Ref<Material> external_mat = ResourceLoader::load(path);
  1033. if (external_mat.is_valid()) {
  1034. m->set_surface_material(i, external_mat);
  1035. }
  1036. }
  1037. }
  1038. }
  1039. }
  1040. r_scanned_meshes.insert(m);
  1041. }
  1042. if (node_settings.has("generate/physics")) {
  1043. int mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_DISABLED;
  1044. const bool generate_collider = node_settings["generate/physics"];
  1045. if (generate_collider) {
  1046. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_MESH_AND_STATIC_COLLIDER;
  1047. if (node_settings.has("physics/body_type")) {
  1048. const BodyType body_type = (BodyType)node_settings["physics/body_type"].operator int();
  1049. switch (body_type) {
  1050. case BODY_TYPE_STATIC:
  1051. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_MESH_AND_STATIC_COLLIDER;
  1052. break;
  1053. case BODY_TYPE_DYNAMIC:
  1054. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_RIGID_BODY_AND_MESH;
  1055. break;
  1056. case BODY_TYPE_AREA:
  1057. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_AREA_ONLY;
  1058. break;
  1059. }
  1060. }
  1061. }
  1062. if (mesh_physics_mode != MeshPhysicsMode::MESH_PHYSICS_DISABLED) {
  1063. Vector<Ref<Shape3D>> shapes;
  1064. if (collision_map.has(m)) {
  1065. shapes = collision_map[m];
  1066. } else {
  1067. shapes = get_collision_shapes(
  1068. m,
  1069. node_settings,
  1070. p_applied_root_scale);
  1071. }
  1072. if (shapes.size()) {
  1073. CollisionObject3D *base = nullptr;
  1074. switch (mesh_physics_mode) {
  1075. case MESH_PHYSICS_MESH_AND_STATIC_COLLIDER: {
  1076. StaticBody3D *col = memnew(StaticBody3D);
  1077. p_node->add_child(col, true);
  1078. col->set_owner(p_node->get_owner());
  1079. col->set_transform(get_collision_shapes_transform(node_settings));
  1080. col->set_position(p_applied_root_scale * col->get_position());
  1081. base = col;
  1082. } break;
  1083. case MESH_PHYSICS_RIGID_BODY_AND_MESH: {
  1084. RigidBody3D *rigid_body = memnew(RigidBody3D);
  1085. rigid_body->set_name(p_node->get_name());
  1086. p_node->replace_by(rigid_body);
  1087. rigid_body->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
  1088. rigid_body->set_position(p_applied_root_scale * rigid_body->get_position());
  1089. p_node = rigid_body;
  1090. mi->set_transform(Transform3D());
  1091. rigid_body->add_child(mi, true);
  1092. mi->set_owner(rigid_body->get_owner());
  1093. base = rigid_body;
  1094. } break;
  1095. case MESH_PHYSICS_STATIC_COLLIDER_ONLY: {
  1096. StaticBody3D *col = memnew(StaticBody3D);
  1097. col->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
  1098. col->set_position(p_applied_root_scale * col->get_position());
  1099. col->set_name(p_node->get_name());
  1100. p_node->replace_by(col);
  1101. p_node->set_owner(nullptr);
  1102. memdelete(p_node);
  1103. p_node = col;
  1104. base = col;
  1105. } break;
  1106. case MESH_PHYSICS_AREA_ONLY: {
  1107. Area3D *area = memnew(Area3D);
  1108. area->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
  1109. area->set_position(p_applied_root_scale * area->get_position());
  1110. area->set_name(p_node->get_name());
  1111. p_node->replace_by(area);
  1112. p_node->set_owner(nullptr);
  1113. memdelete(p_node);
  1114. p_node = area;
  1115. base = area;
  1116. } break;
  1117. }
  1118. for (const Ref<Shape3D> &E : shapes) {
  1119. CollisionShape3D *cshape = memnew(CollisionShape3D);
  1120. cshape->set_shape(E);
  1121. base->add_child(cshape, true);
  1122. cshape->set_owner(base->get_owner());
  1123. }
  1124. }
  1125. }
  1126. }
  1127. }
  1128. }
  1129. //navmesh (node may have changed type above)
  1130. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1131. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1132. Ref<ImporterMesh> m = mi->get_mesh();
  1133. if (m.is_valid()) {
  1134. if (node_settings.has("generate/navmesh")) {
  1135. int navmesh_mode = node_settings["generate/navmesh"];
  1136. if (navmesh_mode != NAVMESH_DISABLED) {
  1137. NavigationRegion3D *nmi = memnew(NavigationRegion3D);
  1138. Ref<NavigationMesh> nmesh = m->create_navigation_mesh();
  1139. nmi->set_navigation_mesh(nmesh);
  1140. if (navmesh_mode == NAVMESH_NAVMESH_ONLY) {
  1141. nmi->set_transform(mi->get_transform());
  1142. p_node->replace_by(nmi);
  1143. p_node->set_owner(nullptr);
  1144. memdelete(p_node);
  1145. p_node = nmi;
  1146. } else {
  1147. mi->add_child(nmi, true);
  1148. nmi->set_owner(mi->get_owner());
  1149. }
  1150. }
  1151. }
  1152. }
  1153. }
  1154. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1155. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1156. Ref<ImporterMesh> m = mi->get_mesh();
  1157. if (m.is_valid()) {
  1158. if (node_settings.has("generate/occluder")) {
  1159. int occluder_mode = node_settings["generate/occluder"];
  1160. if (occluder_mode != OCCLUDER_DISABLED) {
  1161. float simplification_dist = 0.0f;
  1162. if (node_settings.has("occluder/simplification_distance")) {
  1163. simplification_dist = node_settings["occluder/simplification_distance"];
  1164. }
  1165. OccluderInstance3D::bake_single_node(mi, simplification_dist, r_occluder_arrays.first, r_occluder_arrays.second);
  1166. if (occluder_mode == OCCLUDER_OCCLUDER_ONLY) {
  1167. p_node->set_owner(nullptr);
  1168. memdelete(p_node);
  1169. p_node = nullptr;
  1170. }
  1171. }
  1172. }
  1173. }
  1174. }
  1175. if (Object::cast_to<AnimationPlayer>(p_node)) {
  1176. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  1177. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1178. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  1179. }
  1180. if (post_importer_plugins.size()) {
  1181. List<StringName> anims;
  1182. ap->get_animation_list(&anims);
  1183. for (const StringName &name : anims) {
  1184. if (p_animation_data.has(name)) {
  1185. Ref<Animation> anim = ap->get_animation(name);
  1186. Dictionary anim_settings = p_animation_data[name];
  1187. {
  1188. //fill with default values
  1189. List<ImportOption> iopts;
  1190. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts);
  1191. for (const ImportOption &F : iopts) {
  1192. if (!anim_settings.has(F.option.name)) {
  1193. anim_settings[F.option.name] = F.default_value;
  1194. }
  1195. }
  1196. }
  1197. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1198. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION, p_root, p_node, anim, anim_settings);
  1199. }
  1200. }
  1201. }
  1202. }
  1203. }
  1204. return p_node;
  1205. }
  1206. Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks) {
  1207. if (!p_save_to_file || !p_save_to_path.is_resource_file()) {
  1208. return anim;
  1209. }
  1210. if (FileAccess::exists(p_save_to_path) && p_keep_custom_tracks) {
  1211. // Copy custom animation tracks from previously imported files.
  1212. Ref<Animation> old_anim = ResourceLoader::load(p_save_to_path, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE);
  1213. if (old_anim.is_valid()) {
  1214. for (int i = 0; i < old_anim->get_track_count(); i++) {
  1215. if (!old_anim->track_is_imported(i)) {
  1216. old_anim->copy_track(i, anim);
  1217. }
  1218. }
  1219. anim->set_loop_mode(old_anim->get_loop_mode());
  1220. }
  1221. }
  1222. if (ResourceCache::has(p_save_to_path)) {
  1223. Ref<Animation> old_anim = ResourceCache::get_ref(p_save_to_path);
  1224. if (old_anim.is_valid()) {
  1225. old_anim->copy_from(anim);
  1226. anim = old_anim;
  1227. }
  1228. }
  1229. anim->set_path(p_save_to_path, true); // Set path to save externally.
  1230. Error err = ResourceSaver::save(anim, p_save_to_path, ResourceSaver::FLAG_CHANGE_PATH);
  1231. ERR_FAIL_COND_V_MSG(err != OK, anim, "Saving of animation failed: " + p_save_to_path);
  1232. return anim;
  1233. }
  1234. void ResourceImporterScene::_create_slices(AnimationPlayer *ap, Ref<Animation> anim, const Array &p_slices, bool p_bake_all) {
  1235. Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim));
  1236. for (int i = 0; i < p_slices.size(); i += 7) {
  1237. String name = p_slices[i];
  1238. float from = p_slices[i + 1];
  1239. float to = p_slices[i + 2];
  1240. Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)p_slices[i + 3]);
  1241. bool save_to_file = p_slices[i + 4];
  1242. String save_to_path = p_slices[i + 5];
  1243. bool keep_current = p_slices[i + 6];
  1244. if (from >= to) {
  1245. continue;
  1246. }
  1247. Ref<Animation> new_anim = memnew(Animation);
  1248. for (int j = 0; j < anim->get_track_count(); j++) {
  1249. List<float> keys;
  1250. int kc = anim->track_get_key_count(j);
  1251. int dtrack = -1;
  1252. for (int k = 0; k < kc; k++) {
  1253. float kt = anim->track_get_key_time(j, k);
  1254. if (kt >= from && kt < to) {
  1255. //found a key within range, so create track
  1256. if (dtrack == -1) {
  1257. new_anim->add_track(anim->track_get_type(j));
  1258. dtrack = new_anim->get_track_count() - 1;
  1259. new_anim->track_set_path(dtrack, anim->track_get_path(j));
  1260. if (kt > (from + 0.01) && k > 0) {
  1261. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1262. Vector3 p;
  1263. anim->position_track_interpolate(j, from, &p);
  1264. new_anim->position_track_insert_key(dtrack, 0, p);
  1265. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1266. Quaternion r;
  1267. anim->rotation_track_interpolate(j, from, &r);
  1268. new_anim->rotation_track_insert_key(dtrack, 0, r);
  1269. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1270. Vector3 s;
  1271. anim->scale_track_interpolate(j, from, &s);
  1272. new_anim->scale_track_insert_key(dtrack, 0, s);
  1273. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1274. Variant var = anim->value_track_interpolate(j, from);
  1275. new_anim->track_insert_key(dtrack, 0, var);
  1276. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1277. float interp;
  1278. anim->blend_shape_track_interpolate(j, from, &interp);
  1279. new_anim->blend_shape_track_insert_key(dtrack, 0, interp);
  1280. }
  1281. }
  1282. }
  1283. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1284. Vector3 p;
  1285. anim->position_track_get_key(j, k, &p);
  1286. new_anim->position_track_insert_key(dtrack, kt - from, p);
  1287. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1288. Quaternion r;
  1289. anim->rotation_track_get_key(j, k, &r);
  1290. new_anim->rotation_track_insert_key(dtrack, kt - from, r);
  1291. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1292. Vector3 s;
  1293. anim->scale_track_get_key(j, k, &s);
  1294. new_anim->scale_track_insert_key(dtrack, kt - from, s);
  1295. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1296. Variant var = anim->track_get_key_value(j, k);
  1297. new_anim->track_insert_key(dtrack, kt - from, var);
  1298. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1299. float interp;
  1300. anim->blend_shape_track_get_key(j, k, &interp);
  1301. new_anim->blend_shape_track_insert_key(dtrack, kt - from, interp);
  1302. }
  1303. }
  1304. if (dtrack != -1 && kt >= to) {
  1305. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1306. Vector3 p;
  1307. anim->position_track_interpolate(j, to, &p);
  1308. new_anim->position_track_insert_key(dtrack, to - from, p);
  1309. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1310. Quaternion r;
  1311. anim->rotation_track_interpolate(j, to, &r);
  1312. new_anim->rotation_track_insert_key(dtrack, to - from, r);
  1313. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1314. Vector3 s;
  1315. anim->scale_track_interpolate(j, to, &s);
  1316. new_anim->scale_track_insert_key(dtrack, to - from, s);
  1317. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1318. Variant var = anim->value_track_interpolate(j, to);
  1319. new_anim->track_insert_key(dtrack, to - from, var);
  1320. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1321. float interp;
  1322. anim->blend_shape_track_interpolate(j, to, &interp);
  1323. new_anim->blend_shape_track_insert_key(dtrack, to - from, interp);
  1324. }
  1325. }
  1326. }
  1327. if (dtrack == -1 && p_bake_all) {
  1328. new_anim->add_track(anim->track_get_type(j));
  1329. dtrack = new_anim->get_track_count() - 1;
  1330. new_anim->track_set_path(dtrack, anim->track_get_path(j));
  1331. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1332. Vector3 p;
  1333. anim->position_track_interpolate(j, from, &p);
  1334. new_anim->position_track_insert_key(dtrack, 0, p);
  1335. anim->position_track_interpolate(j, to, &p);
  1336. new_anim->position_track_insert_key(dtrack, to - from, p);
  1337. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1338. Quaternion r;
  1339. anim->rotation_track_interpolate(j, from, &r);
  1340. new_anim->rotation_track_insert_key(dtrack, 0, r);
  1341. anim->rotation_track_interpolate(j, to, &r);
  1342. new_anim->rotation_track_insert_key(dtrack, to - from, r);
  1343. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1344. Vector3 s;
  1345. anim->scale_track_interpolate(j, from, &s);
  1346. new_anim->scale_track_insert_key(dtrack, 0, s);
  1347. anim->scale_track_interpolate(j, to, &s);
  1348. new_anim->scale_track_insert_key(dtrack, to - from, s);
  1349. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1350. Variant var = anim->value_track_interpolate(j, from);
  1351. new_anim->track_insert_key(dtrack, 0, var);
  1352. Variant to_var = anim->value_track_interpolate(j, to);
  1353. new_anim->track_insert_key(dtrack, to - from, to_var);
  1354. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1355. float interp;
  1356. anim->blend_shape_track_interpolate(j, from, &interp);
  1357. new_anim->blend_shape_track_insert_key(dtrack, 0, interp);
  1358. anim->blend_shape_track_interpolate(j, to, &interp);
  1359. new_anim->blend_shape_track_insert_key(dtrack, to - from, interp);
  1360. }
  1361. }
  1362. }
  1363. new_anim->set_loop_mode(loop_mode);
  1364. new_anim->set_length(to - from);
  1365. al->add_animation(name, new_anim);
  1366. Ref<Animation> saved_anim = _save_animation_to_file(new_anim, save_to_file, save_to_path, keep_current);
  1367. if (saved_anim != new_anim) {
  1368. al->add_animation(name, saved_anim);
  1369. }
  1370. }
  1371. al->remove_animation(ap->find_animation(anim)); // Remove original animation (no longer needed).
  1372. }
  1373. void ResourceImporterScene::_optimize_animations(AnimationPlayer *anim, float p_max_vel_error, float p_max_ang_error, int p_prc_error) {
  1374. List<StringName> anim_names;
  1375. anim->get_animation_list(&anim_names);
  1376. for (const StringName &E : anim_names) {
  1377. Ref<Animation> a = anim->get_animation(E);
  1378. a->optimize(p_max_vel_error, p_max_ang_error, p_prc_error);
  1379. }
  1380. }
  1381. void ResourceImporterScene::_compress_animations(AnimationPlayer *anim, int p_page_size_kb) {
  1382. List<StringName> anim_names;
  1383. anim->get_animation_list(&anim_names);
  1384. for (const StringName &E : anim_names) {
  1385. Ref<Animation> a = anim->get_animation(E);
  1386. a->compress(p_page_size_kb * 1024);
  1387. }
  1388. }
  1389. void ResourceImporterScene::get_internal_import_options(InternalImportCategory p_category, List<ImportOption> *r_options) const {
  1390. switch (p_category) {
  1391. case INTERNAL_IMPORT_CATEGORY_NODE: {
  1392. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1393. } break;
  1394. case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
  1395. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1396. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate/physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1397. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/navmesh", PROPERTY_HINT_ENUM, "Disabled,Mesh + NavMesh,NavMesh Only"), 0));
  1398. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/body_type", PROPERTY_HINT_ENUM, "Static,Dynamic,Area"), 0));
  1399. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/shape_type", PROPERTY_HINT_ENUM, "Decompose Convex,Simple Convex,Trimesh,Box,Sphere,Cylinder,Capsule", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
  1400. // Decomposition
  1401. Mesh::ConvexDecompositionSettings decomposition_default;
  1402. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/advanced", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1403. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/precision", PROPERTY_HINT_RANGE, "1,10,1"), 5));
  1404. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/max_concavity", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_concavity));
  1405. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/symmetry_planes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.symmetry_planes_clipping_bias));
  1406. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/revolution_axes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.revolution_axes_clipping_bias));
  1407. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/min_volume_per_convex_hull", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.min_volume_per_convex_hull));
  1408. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/resolution", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.resolution));
  1409. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_num_vertices_per_convex_hull", PROPERTY_HINT_RANGE, "5,512,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_num_vertices_per_convex_hull));
  1410. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.plane_downsampling));
  1411. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/convexhull_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.convexhull_downsampling));
  1412. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/normalize_mesh", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.normalize_mesh));
  1413. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), static_cast<int>(decomposition_default.mode)));
  1414. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/convexhull_approximation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.convexhull_approximation));
  1415. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_convex_hulls", PROPERTY_HINT_RANGE, "1,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_convex_hulls));
  1416. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/project_hull_vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.project_hull_vertices));
  1417. // Primitives: Box, Sphere, Cylinder, Capsule.
  1418. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3(2.0, 2.0, 2.0)));
  1419. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/height", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1.0));
  1420. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/radius", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1.0));
  1421. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3()));
  1422. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3()));
  1423. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/occluder", PROPERTY_HINT_ENUM, "Disabled,Mesh + Occluder,Occluder Only", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
  1424. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "occluder/simplification_distance", PROPERTY_HINT_RANGE, "0.0,2.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0.1f));
  1425. } break;
  1426. case INTERNAL_IMPORT_CATEGORY_MESH: {
  1427. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1428. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), ""));
  1429. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/make_streamable"), ""));
  1430. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/shadow_meshes", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
  1431. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lightmap_uv", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
  1432. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lods", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
  1433. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_split_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 25.0f));
  1434. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_merge_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 60.0f));
  1435. } break;
  1436. case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
  1437. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "use_external/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1438. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "use_external/path", PROPERTY_HINT_FILE, "*.material,*.res,*.tres"), ""));
  1439. } break;
  1440. case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
  1441. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "settings/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
  1442. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1443. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), ""));
  1444. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/keep_custom_tracks"), ""));
  1445. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
  1446. for (int i = 0; i < 256; i++) {
  1447. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/name"), ""));
  1448. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/start_frame"), 0));
  1449. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/end_frame"), 0));
  1450. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
  1451. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1452. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, ".res,*.tres"), ""));
  1453. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false));
  1454. }
  1455. } break;
  1456. case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
  1457. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1458. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
  1459. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_velocity_error", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.01));
  1460. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_angular_error", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.01));
  1461. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "optimizer/max_precision_error", PROPERTY_HINT_NONE, "1,6,1"), 3));
  1462. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compression/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1463. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compression/page_size", PROPERTY_HINT_RANGE, "4,512,1,suffix:kb"), 8));
  1464. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/position", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
  1465. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/rotation", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
  1466. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/scale", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
  1467. } break;
  1468. case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
  1469. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1470. r_options->push_back(ImportOption(PropertyInfo(Variant::OBJECT, "retarget/bone_map", PROPERTY_HINT_RESOURCE_TYPE, "BoneMap", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Variant()));
  1471. } break;
  1472. default: {
  1473. }
  1474. }
  1475. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1476. post_importer_plugins.write[i]->get_internal_import_options(EditorScenePostImportPlugin::InternalImportCategory(p_category), r_options);
  1477. }
  1478. }
  1479. bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  1480. if (p_options.has("import/skip_import") && p_option != "import/skip_import" && bool(p_options["import/skip_import"])) {
  1481. return false; //if skip import
  1482. }
  1483. switch (p_category) {
  1484. case INTERNAL_IMPORT_CATEGORY_NODE: {
  1485. } break;
  1486. case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
  1487. const bool generate_physics =
  1488. p_options.has("generate/physics") &&
  1489. p_options["generate/physics"].operator bool();
  1490. if (
  1491. p_option == "physics/body_type" ||
  1492. p_option == "physics/shape_type") {
  1493. // Show if need to generate collisions.
  1494. return generate_physics;
  1495. }
  1496. if (p_option.find("decomposition/") >= 0) {
  1497. // Show if need to generate collisions.
  1498. if (generate_physics &&
  1499. // Show if convex is enabled.
  1500. p_options["physics/shape_type"] == Variant(SHAPE_TYPE_DECOMPOSE_CONVEX)) {
  1501. if (p_option == "decomposition/advanced") {
  1502. return true;
  1503. }
  1504. const bool decomposition_advanced =
  1505. p_options.has("decomposition/advanced") &&
  1506. p_options["decomposition/advanced"].operator bool();
  1507. if (p_option == "decomposition/precision") {
  1508. return !decomposition_advanced;
  1509. } else {
  1510. return decomposition_advanced;
  1511. }
  1512. }
  1513. return false;
  1514. }
  1515. if (p_option == "primitive/position" || p_option == "primitive/rotation") {
  1516. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1517. return generate_physics &&
  1518. physics_shape >= SHAPE_TYPE_BOX;
  1519. }
  1520. if (p_option == "primitive/size") {
  1521. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1522. return generate_physics &&
  1523. physics_shape == SHAPE_TYPE_BOX;
  1524. }
  1525. if (p_option == "primitive/radius") {
  1526. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1527. return generate_physics &&
  1528. (physics_shape == SHAPE_TYPE_SPHERE ||
  1529. physics_shape == SHAPE_TYPE_CYLINDER ||
  1530. physics_shape == SHAPE_TYPE_CAPSULE);
  1531. }
  1532. if (p_option == "primitive/height") {
  1533. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1534. return generate_physics &&
  1535. (physics_shape == SHAPE_TYPE_CYLINDER ||
  1536. physics_shape == SHAPE_TYPE_CAPSULE);
  1537. }
  1538. if (p_option == "occluder/simplification_distance") {
  1539. // Show only if occluder generation is enabled
  1540. return p_options.has("generate/occluder") && p_options["generate/occluder"].operator signed int() != OCCLUDER_DISABLED;
  1541. }
  1542. } break;
  1543. case INTERNAL_IMPORT_CATEGORY_MESH: {
  1544. if (p_option == "save_to_file/path" || p_option == "save_to_file/make_streamable") {
  1545. return p_options["save_to_file/enabled"];
  1546. }
  1547. } break;
  1548. case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
  1549. if (p_option == "use_external/path") {
  1550. return p_options["use_external/enabled"];
  1551. }
  1552. } break;
  1553. case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
  1554. if (p_option == "save_to_file/path" || p_option == "save_to_file/keep_custom_tracks") {
  1555. return p_options["save_to_file/enabled"];
  1556. }
  1557. if (p_option.begins_with("slice_")) {
  1558. int max_slice = p_options["slices/amount"];
  1559. int slice = p_option.get_slice("_", 1).to_int() - 1;
  1560. if (slice >= max_slice) {
  1561. return false;
  1562. }
  1563. }
  1564. } break;
  1565. case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
  1566. if (p_option.begins_with("optimizer/") && p_option != "optimizer/enabled" && !bool(p_options["optimizer/enabled"])) {
  1567. return false;
  1568. }
  1569. if (p_option.begins_with("compression/") && p_option != "compression/enabled" && !bool(p_options["compression/enabled"])) {
  1570. return false;
  1571. }
  1572. } break;
  1573. case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
  1574. const bool use_retarget = p_options["retarget/bone_map"].get_validated_object() != nullptr;
  1575. if (p_option != "retarget/bone_map" && p_option.begins_with("retarget/")) {
  1576. return use_retarget;
  1577. }
  1578. } break;
  1579. default: {
  1580. }
  1581. }
  1582. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1583. Variant ret = post_importer_plugins.write[i]->get_internal_option_visibility(EditorScenePostImportPlugin::InternalImportCategory(p_category), animation_importer, p_option, p_options);
  1584. if (ret.get_type() == Variant::BOOL) {
  1585. return ret;
  1586. }
  1587. }
  1588. return true;
  1589. }
  1590. bool ResourceImporterScene::get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  1591. switch (p_category) {
  1592. case INTERNAL_IMPORT_CATEGORY_NODE: {
  1593. } break;
  1594. case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
  1595. if (
  1596. p_option == "generate/physics" ||
  1597. p_option == "physics/shape_type" ||
  1598. p_option.find("decomposition/") >= 0 ||
  1599. p_option.find("primitive/") >= 0) {
  1600. return true;
  1601. }
  1602. } break;
  1603. case INTERNAL_IMPORT_CATEGORY_MESH: {
  1604. } break;
  1605. case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
  1606. } break;
  1607. case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
  1608. } break;
  1609. case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
  1610. } break;
  1611. case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
  1612. } break;
  1613. default: {
  1614. }
  1615. }
  1616. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1617. Variant ret = post_importer_plugins.write[i]->get_internal_option_update_view_required(EditorScenePostImportPlugin::InternalImportCategory(p_category), p_option, p_options);
  1618. if (ret.get_type() == Variant::BOOL) {
  1619. return ret;
  1620. }
  1621. }
  1622. return false;
  1623. }
  1624. void ResourceImporterScene::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
  1625. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "Node3D"));
  1626. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), "Scene Root"));
  1627. List<String> script_extentions;
  1628. ResourceLoader::get_recognized_extensions_for_type("Script", &script_extentions);
  1629. String script_ext_hint;
  1630. for (const String &E : script_extentions) {
  1631. if (!script_ext_hint.is_empty()) {
  1632. script_ext_hint += ",";
  1633. }
  1634. script_ext_hint += "*." + E;
  1635. }
  1636. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "nodes/apply_root_scale"), true));
  1637. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "nodes/root_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001"), 1.0));
  1638. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
  1639. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true));
  1640. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true));
  1641. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI),Static Lightmaps (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI only)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
  1642. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.2));
  1643. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true));
  1644. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
  1645. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30));
  1646. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), false));
  1647. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/remove_immutable_tracks"), true));
  1648. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
  1649. r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary()));
  1650. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1651. post_importer_plugins.write[i]->get_import_options(p_path, r_options);
  1652. }
  1653. for (Ref<EditorSceneFormatImporter> importer_elem : importers) {
  1654. importer_elem->get_import_options(p_path, r_options);
  1655. }
  1656. }
  1657. void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) {
  1658. if (p_node != p_new_owner && p_node->get_owner() == p_scene) {
  1659. p_node->set_owner(p_new_owner);
  1660. }
  1661. for (int i = 0; i < p_node->get_child_count(); i++) {
  1662. Node *n = p_node->get_child(i);
  1663. _replace_owner(n, p_scene, p_new_owner);
  1664. }
  1665. }
  1666. Array ResourceImporterScene::_get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node) {
  1667. Array skin_pose_transform_array;
  1668. const Ref<Skin> skin = p_src_mesh_node->get_skin();
  1669. if (skin.is_valid()) {
  1670. NodePath skeleton_path = p_src_mesh_node->get_skeleton_path();
  1671. const Node *node = p_src_mesh_node->get_node_or_null(skeleton_path);
  1672. const Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
  1673. if (skeleton) {
  1674. int bind_count = skin->get_bind_count();
  1675. for (int i = 0; i < bind_count; i++) {
  1676. Transform3D bind_pose = skin->get_bind_pose(i);
  1677. String bind_name = skin->get_bind_name(i);
  1678. int bone_idx = bind_name.is_empty() ? skin->get_bind_bone(i) : skeleton->find_bone(bind_name);
  1679. ERR_FAIL_COND_V(bone_idx >= skeleton->get_bone_count(), Array());
  1680. Transform3D bp_global_rest;
  1681. if (bone_idx >= 0) {
  1682. bp_global_rest = skeleton->get_bone_global_pose(bone_idx);
  1683. } else {
  1684. bp_global_rest = skeleton->get_bone_global_pose(i);
  1685. }
  1686. skin_pose_transform_array.push_back(bp_global_rest * bind_pose);
  1687. }
  1688. }
  1689. }
  1690. return skin_pose_transform_array;
  1691. }
  1692. void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches) {
  1693. ImporterMeshInstance3D *src_mesh_node = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1694. if (src_mesh_node) {
  1695. //is mesh
  1696. MeshInstance3D *mesh_node = memnew(MeshInstance3D);
  1697. mesh_node->set_name(src_mesh_node->get_name());
  1698. mesh_node->set_transform(src_mesh_node->get_transform());
  1699. mesh_node->set_skin(src_mesh_node->get_skin());
  1700. mesh_node->set_skeleton_path(src_mesh_node->get_skeleton_path());
  1701. if (src_mesh_node->get_mesh().is_valid()) {
  1702. Ref<ArrayMesh> mesh;
  1703. if (!src_mesh_node->get_mesh()->has_mesh()) {
  1704. //do mesh processing
  1705. bool generate_lods = p_generate_lods;
  1706. float split_angle = 25.0f;
  1707. float merge_angle = 60.0f;
  1708. bool create_shadow_meshes = p_create_shadow_meshes;
  1709. bool bake_lightmaps = p_light_bake_mode == LIGHT_BAKE_STATIC_LIGHTMAPS;
  1710. String save_to_file;
  1711. String mesh_id = src_mesh_node->get_mesh()->get_meta("import_id", src_mesh_node->get_mesh()->get_name());
  1712. if (!mesh_id.is_empty() && p_mesh_data.has(mesh_id)) {
  1713. Dictionary mesh_settings = p_mesh_data[mesh_id];
  1714. {
  1715. //fill node settings for this node with default values
  1716. List<ImportOption> iopts;
  1717. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MESH, &iopts);
  1718. for (const ImportOption &E : iopts) {
  1719. if (!mesh_settings.has(E.option.name)) {
  1720. mesh_settings[E.option.name] = E.default_value;
  1721. }
  1722. }
  1723. }
  1724. if (mesh_settings.has("generate/shadow_meshes")) {
  1725. int shadow_meshes = mesh_settings["generate/shadow_meshes"];
  1726. if (shadow_meshes == MESH_OVERRIDE_ENABLE) {
  1727. create_shadow_meshes = true;
  1728. } else if (shadow_meshes == MESH_OVERRIDE_DISABLE) {
  1729. create_shadow_meshes = false;
  1730. }
  1731. }
  1732. if (mesh_settings.has("generate/lightmap_uv")) {
  1733. int lightmap_uv = mesh_settings["generate/lightmap_uv"];
  1734. if (lightmap_uv == MESH_OVERRIDE_ENABLE) {
  1735. bake_lightmaps = true;
  1736. } else if (lightmap_uv == MESH_OVERRIDE_DISABLE) {
  1737. bake_lightmaps = false;
  1738. }
  1739. }
  1740. if (mesh_settings.has("generate/lods")) {
  1741. int lods = mesh_settings["generate/lods"];
  1742. if (lods == MESH_OVERRIDE_ENABLE) {
  1743. generate_lods = true;
  1744. } else if (lods == MESH_OVERRIDE_DISABLE) {
  1745. generate_lods = false;
  1746. }
  1747. }
  1748. if (mesh_settings.has("lods/normal_split_angle")) {
  1749. split_angle = mesh_settings["lods/normal_split_angle"];
  1750. }
  1751. if (mesh_settings.has("lods/normal_merge_angle")) {
  1752. merge_angle = mesh_settings["lods/normal_merge_angle"];
  1753. }
  1754. if (mesh_settings.has("save_to_file/enabled") && bool(mesh_settings["save_to_file/enabled"]) && mesh_settings.has("save_to_file/path")) {
  1755. save_to_file = mesh_settings["save_to_file/path"];
  1756. if (!save_to_file.is_resource_file()) {
  1757. save_to_file = "";
  1758. }
  1759. }
  1760. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1761. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH, nullptr, src_mesh_node, src_mesh_node->get_mesh(), mesh_settings);
  1762. }
  1763. }
  1764. if (bake_lightmaps) {
  1765. Transform3D xf;
  1766. Node3D *n = src_mesh_node;
  1767. while (n) {
  1768. xf = n->get_transform() * xf;
  1769. n = n->get_parent_node_3d();
  1770. }
  1771. Vector<uint8_t> lightmap_cache;
  1772. src_mesh_node->get_mesh()->lightmap_unwrap_cached(xf, p_lightmap_texel_size, p_src_lightmap_cache, lightmap_cache);
  1773. if (!lightmap_cache.is_empty()) {
  1774. if (r_lightmap_caches.is_empty()) {
  1775. r_lightmap_caches.push_back(lightmap_cache);
  1776. } else {
  1777. String new_md5 = String::md5(lightmap_cache.ptr()); // MD5 is stored at the beginning of the cache data
  1778. for (int i = 0; i < r_lightmap_caches.size(); i++) {
  1779. String md5 = String::md5(r_lightmap_caches[i].ptr());
  1780. if (new_md5 < md5) {
  1781. r_lightmap_caches.insert(i, lightmap_cache);
  1782. break;
  1783. }
  1784. if (new_md5 == md5) {
  1785. break;
  1786. }
  1787. }
  1788. }
  1789. }
  1790. }
  1791. if (generate_lods) {
  1792. Array skin_pose_transform_array = _get_skinned_pose_transforms(src_mesh_node);
  1793. src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle, skin_pose_transform_array);
  1794. }
  1795. if (create_shadow_meshes) {
  1796. src_mesh_node->get_mesh()->create_shadow_mesh();
  1797. }
  1798. if (!save_to_file.is_empty()) {
  1799. Ref<Mesh> existing = ResourceCache::get_ref(save_to_file);
  1800. if (existing.is_valid()) {
  1801. //if somehow an existing one is useful, create
  1802. existing->reset_state();
  1803. }
  1804. mesh = src_mesh_node->get_mesh()->get_mesh(existing);
  1805. ResourceSaver::save(mesh, save_to_file); //override
  1806. mesh->set_path(save_to_file, true); //takeover existing, if needed
  1807. } else {
  1808. mesh = src_mesh_node->get_mesh()->get_mesh();
  1809. }
  1810. } else {
  1811. mesh = src_mesh_node->get_mesh()->get_mesh();
  1812. }
  1813. if (mesh.is_valid()) {
  1814. mesh_node->set_mesh(mesh);
  1815. for (int i = 0; i < mesh->get_surface_count(); i++) {
  1816. mesh_node->set_surface_override_material(i, src_mesh_node->get_surface_material(i));
  1817. }
  1818. }
  1819. }
  1820. switch (p_light_bake_mode) {
  1821. case LIGHT_BAKE_DISABLED: {
  1822. mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_DISABLED);
  1823. } break;
  1824. case LIGHT_BAKE_DYNAMIC: {
  1825. mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_DYNAMIC);
  1826. } break;
  1827. case LIGHT_BAKE_STATIC:
  1828. case LIGHT_BAKE_STATIC_LIGHTMAPS: {
  1829. mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_STATIC);
  1830. } break;
  1831. }
  1832. p_node->replace_by(mesh_node);
  1833. p_node->set_owner(nullptr);
  1834. memdelete(p_node);
  1835. p_node = mesh_node;
  1836. }
  1837. for (int i = 0; i < p_node->get_child_count(); i++) {
  1838. _generate_meshes(p_node->get_child(i), p_mesh_data, p_generate_lods, p_create_shadow_meshes, p_light_bake_mode, p_lightmap_texel_size, p_src_lightmap_cache, r_lightmap_caches);
  1839. }
  1840. }
  1841. void ResourceImporterScene::_add_shapes(Node *p_node, const Vector<Ref<Shape3D>> &p_shapes) {
  1842. for (const Ref<Shape3D> &E : p_shapes) {
  1843. CollisionShape3D *cshape = memnew(CollisionShape3D);
  1844. cshape->set_shape(E);
  1845. p_node->add_child(cshape, true);
  1846. cshape->set_owner(p_node->get_owner());
  1847. }
  1848. }
  1849. void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, AnimationImportTracks *p_track_actions) {
  1850. List<StringName> anims;
  1851. p_player->get_animation_list(&anims);
  1852. Node *parent = p_player->get_parent();
  1853. ERR_FAIL_COND(parent == nullptr);
  1854. HashMap<NodePath, uint32_t> used_tracks[TRACK_CHANNEL_MAX];
  1855. bool tracks_to_add = false;
  1856. static const Animation::TrackType track_types[TRACK_CHANNEL_MAX] = { Animation::TYPE_POSITION_3D, Animation::TYPE_ROTATION_3D, Animation::TYPE_SCALE_3D, Animation::TYPE_BLEND_SHAPE };
  1857. for (const StringName &I : anims) {
  1858. Ref<Animation> anim = p_player->get_animation(I);
  1859. for (int i = 0; i < anim->get_track_count(); i++) {
  1860. for (int j = 0; j < TRACK_CHANNEL_MAX; j++) {
  1861. if (anim->track_get_type(i) != track_types[j]) {
  1862. continue;
  1863. }
  1864. switch (p_track_actions[j]) {
  1865. case ANIMATION_IMPORT_TRACKS_IF_PRESENT: {
  1866. // Do Nothing.
  1867. } break;
  1868. case ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL: {
  1869. used_tracks[j].insert(anim->track_get_path(i), 0);
  1870. tracks_to_add = true;
  1871. } break;
  1872. case ANIMATION_IMPORT_TRACKS_NEVER: {
  1873. anim->remove_track(i);
  1874. i--;
  1875. } break;
  1876. }
  1877. }
  1878. }
  1879. }
  1880. if (!tracks_to_add) {
  1881. return;
  1882. }
  1883. uint32_t pass = 0;
  1884. for (const StringName &I : anims) {
  1885. Ref<Animation> anim = p_player->get_animation(I);
  1886. for (int j = 0; j < TRACK_CHANNEL_MAX; j++) {
  1887. if (p_track_actions[j] != ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  1888. continue;
  1889. }
  1890. pass++;
  1891. for (int i = 0; i < anim->get_track_count(); i++) {
  1892. if (anim->track_get_type(i) != track_types[j]) {
  1893. continue;
  1894. }
  1895. NodePath path = anim->track_get_path(i);
  1896. ERR_CONTINUE(!used_tracks[j].has(path)); // Should never happen.
  1897. used_tracks[j][path] = pass;
  1898. }
  1899. for (const KeyValue<NodePath, uint32_t> &J : used_tracks[j]) {
  1900. if (J.value == pass) {
  1901. continue;
  1902. }
  1903. NodePath path = J.key;
  1904. Node *n = parent->get_node(path);
  1905. if (j == TRACK_CHANNEL_BLEND_SHAPE) {
  1906. MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n);
  1907. if (mi && path.get_subname_count() > 0) {
  1908. StringName bs = path.get_subname(0);
  1909. bool valid;
  1910. float value = mi->get(bs, &valid);
  1911. if (valid) {
  1912. int track_idx = anim->add_track(track_types[j]);
  1913. anim->track_set_path(track_idx, path);
  1914. anim->track_set_imported(track_idx, true);
  1915. anim->blend_shape_track_insert_key(track_idx, 0, value);
  1916. }
  1917. }
  1918. } else {
  1919. Skeleton3D *skel = Object::cast_to<Skeleton3D>(n);
  1920. Node3D *n3d = Object::cast_to<Node3D>(n);
  1921. Vector3 loc;
  1922. Quaternion rot;
  1923. Vector3 scale;
  1924. if (skel && path.get_subname_count() > 0) {
  1925. StringName bone = path.get_subname(0);
  1926. int bone_idx = skel->find_bone(bone);
  1927. if (bone_idx == -1) {
  1928. continue;
  1929. }
  1930. // Note that this is using get_bone_pose to update the bone pose cache.
  1931. _ALLOW_DISCARD_ skel->get_bone_pose(bone_idx);
  1932. loc = skel->get_bone_pose_position(bone_idx);
  1933. rot = skel->get_bone_pose_rotation(bone_idx);
  1934. scale = skel->get_bone_pose_scale(bone_idx);
  1935. } else if (n3d) {
  1936. loc = n3d->get_position();
  1937. rot = n3d->get_transform().basis.get_rotation_quaternion();
  1938. scale = n3d->get_scale();
  1939. } else {
  1940. continue;
  1941. }
  1942. // Ensure insertion keeps tracks together and ordered by type (loc/rot/scale)
  1943. int insert_at_pos = -1;
  1944. for (int k = 0; k < anim->get_track_count(); k++) {
  1945. NodePath tpath = anim->track_get_path(k);
  1946. if (path == tpath) {
  1947. Animation::TrackType ttype = anim->track_get_type(k);
  1948. if (insert_at_pos == -1) {
  1949. // First insert, determine whether replacing or kicking back
  1950. if (track_types[j] < ttype) {
  1951. insert_at_pos = k;
  1952. break; // No point in continuing.
  1953. } else {
  1954. insert_at_pos = k + 1;
  1955. }
  1956. } else if (ttype < track_types[j]) {
  1957. // Kick back.
  1958. insert_at_pos = k + 1;
  1959. }
  1960. } else if (insert_at_pos >= 0) {
  1961. break;
  1962. }
  1963. }
  1964. int track_idx = anim->add_track(track_types[j], insert_at_pos);
  1965. anim->track_set_path(track_idx, path);
  1966. anim->track_set_imported(track_idx, true);
  1967. switch (j) {
  1968. case TRACK_CHANNEL_POSITION: {
  1969. anim->position_track_insert_key(track_idx, 0, loc);
  1970. } break;
  1971. case TRACK_CHANNEL_ROTATION: {
  1972. anim->rotation_track_insert_key(track_idx, 0, rot);
  1973. } break;
  1974. case TRACK_CHANNEL_SCALE: {
  1975. anim->scale_track_insert_key(track_idx, 0, scale);
  1976. } break;
  1977. default: {
  1978. }
  1979. }
  1980. }
  1981. }
  1982. }
  1983. }
  1984. }
  1985. Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashMap<StringName, Variant> &p_options) {
  1986. Ref<EditorSceneFormatImporter> importer;
  1987. String ext = p_source_file.get_extension().to_lower();
  1988. // TRANSLATORS: This is an editor progress label.
  1989. EditorProgress progress("pre-import", TTR("Pre-Import Scene"), 0);
  1990. progress.step(TTR("Importing Scene..."), 0);
  1991. for (Ref<EditorSceneFormatImporter> importer_elem : importers) {
  1992. List<String> extensions;
  1993. importer_elem->get_extensions(&extensions);
  1994. for (const String &F : extensions) {
  1995. if (F.to_lower() == ext) {
  1996. importer = importer_elem;
  1997. break;
  1998. }
  1999. }
  2000. if (importer.is_valid()) {
  2001. break;
  2002. }
  2003. }
  2004. ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
  2005. Error err = OK;
  2006. HashMap<StringName, Variant> options_dupe = p_options;
  2007. // By default, the GLTF importer will extract embedded images into files on disk
  2008. // However, we do not want the advanced settings dialog to be able to write files on disk.
  2009. // To avoid this and also avoid compressing to basis every time, we are using the uncompressed option.
  2010. options_dupe["gltf/embedded_image_handling"] = 3; // Embed as Uncompressed defined in GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_UNCOMPRESSED
  2011. Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, options_dupe, nullptr, &err);
  2012. if (!scene || err != OK) {
  2013. return nullptr;
  2014. }
  2015. HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
  2016. List<Pair<NodePath, Node *>> node_renames;
  2017. _pre_fix_node(scene, scene, collision_map, nullptr, node_renames);
  2018. return scene;
  2019. }
  2020. Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
  2021. const String &src_path = p_source_file;
  2022. Ref<EditorSceneFormatImporter> importer;
  2023. String ext = src_path.get_extension().to_lower();
  2024. EditorProgress progress("import", TTR("Import Scene"), 104);
  2025. progress.step(TTR("Importing Scene..."), 0);
  2026. for (Ref<EditorSceneFormatImporter> importer_elem : importers) {
  2027. List<String> extensions;
  2028. importer_elem->get_extensions(&extensions);
  2029. for (const String &F : extensions) {
  2030. if (F.to_lower() == ext) {
  2031. importer = importer_elem;
  2032. break;
  2033. }
  2034. }
  2035. if (importer.is_valid()) {
  2036. break;
  2037. }
  2038. }
  2039. ERR_FAIL_COND_V(!importer.is_valid(), ERR_FILE_UNRECOGNIZED);
  2040. int import_flags = 0;
  2041. if (animation_importer) {
  2042. import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
  2043. import_flags |= EditorSceneFormatImporter::IMPORT_DISCARD_MESHES_AND_MATERIALS;
  2044. } else {
  2045. if (bool(p_options["animation/import"])) {
  2046. import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
  2047. }
  2048. }
  2049. if (bool(p_options["skins/use_named_skins"])) {
  2050. import_flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
  2051. }
  2052. bool ensure_tangents = p_options["meshes/ensure_tangents"];
  2053. if (ensure_tangents) {
  2054. import_flags |= EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
  2055. }
  2056. Error err = OK;
  2057. List<String> missing_deps; // for now, not much will be done with this
  2058. Node *scene = importer->import_scene(src_path, import_flags, p_options, &missing_deps, &err);
  2059. if (!scene || err != OK) {
  2060. return err;
  2061. }
  2062. bool apply_root = true;
  2063. if (p_options.has("nodes/apply_root_scale")) {
  2064. apply_root = p_options["nodes/apply_root_scale"];
  2065. }
  2066. real_t root_scale = 1;
  2067. if (p_options.has("nodes/root_scale")) {
  2068. root_scale = p_options["nodes/root_scale"];
  2069. }
  2070. if (Object::cast_to<Node3D>(scene)) {
  2071. Object::cast_to<Node3D>(scene)->scale(Vector3(root_scale, root_scale, root_scale));
  2072. }
  2073. if (apply_root) {
  2074. _apply_permanent_rotation_scale_to_node(scene);
  2075. Object::cast_to<Node3D>(scene)->scale(Vector3(root_scale, root_scale, root_scale).inverse());
  2076. }
  2077. Dictionary subresources = p_options["_subresources"];
  2078. Dictionary node_data;
  2079. if (subresources.has("nodes")) {
  2080. node_data = subresources["nodes"];
  2081. }
  2082. Dictionary material_data;
  2083. if (subresources.has("materials")) {
  2084. material_data = subresources["materials"];
  2085. }
  2086. Dictionary animation_data;
  2087. if (subresources.has("animations")) {
  2088. animation_data = subresources["animations"];
  2089. }
  2090. HashSet<Ref<ImporterMesh>> scanned_meshes;
  2091. HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
  2092. Pair<PackedVector3Array, PackedInt32Array> occluder_arrays;
  2093. List<Pair<NodePath, Node *>> node_renames;
  2094. _pre_fix_node(scene, scene, collision_map, &occluder_arrays, node_renames);
  2095. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2096. post_importer_plugins.write[i]->pre_process(scene, p_options);
  2097. }
  2098. float fps = 30;
  2099. if (p_options.has(SNAME("animation/fps"))) {
  2100. fps = (float)p_options[SNAME("animation/fps")];
  2101. }
  2102. _pre_fix_animations(scene, scene, node_data, animation_data, fps);
  2103. _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps, apply_root ? root_scale : 1.0);
  2104. _post_fix_animations(scene, scene, node_data, animation_data, fps);
  2105. String root_type = p_options["nodes/root_type"];
  2106. root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class.
  2107. Ref<Script> root_script = nullptr;
  2108. if (ScriptServer::is_global_class(root_type)) {
  2109. root_script = ResourceLoader::load(ScriptServer::get_global_class_path(root_type));
  2110. root_type = ScriptServer::get_global_class_base(root_type);
  2111. }
  2112. if (root_type != "Node3D") {
  2113. Node *base_node = Object::cast_to<Node>(ClassDB::instantiate(root_type));
  2114. if (base_node) {
  2115. scene->replace_by(base_node);
  2116. scene->set_owner(nullptr);
  2117. memdelete(scene);
  2118. scene = base_node;
  2119. }
  2120. }
  2121. if (root_script.is_valid()) {
  2122. scene->set_script(Variant(root_script));
  2123. }
  2124. if (p_options["nodes/root_name"] != "Scene Root") {
  2125. scene->set_name(p_options["nodes/root_name"]);
  2126. } else {
  2127. scene->set_name(p_save_path.get_file().get_basename());
  2128. }
  2129. if (!occluder_arrays.first.is_empty() && !occluder_arrays.second.is_empty()) {
  2130. Ref<ArrayOccluder3D> occ = memnew(ArrayOccluder3D);
  2131. occ->set_arrays(occluder_arrays.first, occluder_arrays.second);
  2132. OccluderInstance3D *occluder_instance = memnew(OccluderInstance3D);
  2133. occluder_instance->set_occluder(occ);
  2134. scene->add_child(occluder_instance, true);
  2135. occluder_instance->set_owner(scene);
  2136. }
  2137. bool gen_lods = bool(p_options["meshes/generate_lods"]);
  2138. bool create_shadow_meshes = bool(p_options["meshes/create_shadow_meshes"]);
  2139. int light_bake_mode = p_options["meshes/light_baking"];
  2140. float texel_size = p_options["meshes/lightmap_texel_size"];
  2141. float lightmap_texel_size = MAX(0.001, texel_size);
  2142. Vector<uint8_t> src_lightmap_cache;
  2143. Vector<Vector<uint8_t>> mesh_lightmap_caches;
  2144. {
  2145. src_lightmap_cache = FileAccess::get_file_as_bytes(p_source_file + ".unwrap_cache", &err);
  2146. if (err != OK) {
  2147. src_lightmap_cache.clear();
  2148. }
  2149. }
  2150. Dictionary mesh_data;
  2151. if (subresources.has("meshes")) {
  2152. mesh_data = subresources["meshes"];
  2153. }
  2154. _generate_meshes(scene, mesh_data, gen_lods, create_shadow_meshes, LightBakeMode(light_bake_mode), lightmap_texel_size, src_lightmap_cache, mesh_lightmap_caches);
  2155. if (mesh_lightmap_caches.size()) {
  2156. Ref<FileAccess> f = FileAccess::open(p_source_file + ".unwrap_cache", FileAccess::WRITE);
  2157. if (f.is_valid()) {
  2158. f->store_32(mesh_lightmap_caches.size());
  2159. for (int i = 0; i < mesh_lightmap_caches.size(); i++) {
  2160. String md5 = String::md5(mesh_lightmap_caches[i].ptr());
  2161. f->store_buffer(mesh_lightmap_caches[i].ptr(), mesh_lightmap_caches[i].size());
  2162. }
  2163. }
  2164. }
  2165. err = OK;
  2166. progress.step(TTR("Running Custom Script..."), 2);
  2167. String post_import_script_path = p_options["import_script/path"];
  2168. Ref<EditorScenePostImport> post_import_script;
  2169. if (!post_import_script_path.is_empty()) {
  2170. Ref<Script> scr = ResourceLoader::load(post_import_script_path);
  2171. if (!scr.is_valid()) {
  2172. EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path);
  2173. } else {
  2174. post_import_script = Ref<EditorScenePostImport>(memnew(EditorScenePostImport));
  2175. post_import_script->set_script(scr);
  2176. if (!post_import_script->get_script_instance()) {
  2177. EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):") + " " + post_import_script_path);
  2178. post_import_script.unref();
  2179. return ERR_CANT_CREATE;
  2180. }
  2181. }
  2182. }
  2183. if (post_import_script.is_valid()) {
  2184. post_import_script->init(p_source_file);
  2185. scene = post_import_script->post_import(scene);
  2186. if (!scene) {
  2187. EditorNode::add_io_error(
  2188. TTR("Error running post-import script:") + " " + post_import_script_path + "\n" +
  2189. TTR("Did you return a Node-derived object in the `_post_import()` method?"));
  2190. return err;
  2191. }
  2192. }
  2193. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2194. post_importer_plugins.write[i]->post_process(scene, p_options);
  2195. }
  2196. progress.step(TTR("Saving..."), 104);
  2197. if (animation_importer) {
  2198. Ref<AnimationLibrary> library;
  2199. for (int i = 0; i < scene->get_child_count(); i++) {
  2200. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(scene->get_child(i));
  2201. if (ap) {
  2202. List<StringName> libs;
  2203. ap->get_animation_library_list(&libs);
  2204. if (libs.size()) {
  2205. library = ap->get_animation_library(libs.front()->get());
  2206. break;
  2207. }
  2208. }
  2209. }
  2210. if (!library.is_valid()) {
  2211. library.instantiate(); // Will be empty
  2212. }
  2213. print_verbose("Saving animation to: " + p_save_path + ".scn");
  2214. err = ResourceSaver::save(library, p_save_path + ".res"); //do not take over, let the changed files reload themselves
  2215. ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save animation to file '" + p_save_path + ".res'.");
  2216. } else {
  2217. Ref<PackedScene> packer = memnew(PackedScene);
  2218. packer->pack(scene);
  2219. print_verbose("Saving scene to: " + p_save_path + ".scn");
  2220. err = ResourceSaver::save(packer, p_save_path + ".scn"); //do not take over, let the changed files reload themselves
  2221. ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save scene to file '" + p_save_path + ".scn'.");
  2222. }
  2223. memdelete(scene);
  2224. //this is not the time to reimport, wait until import process is done, import file is saved, etc.
  2225. //EditorNode::get_singleton()->reload_scene(p_source_file);
  2226. return OK;
  2227. }
  2228. ResourceImporterScene *ResourceImporterScene::scene_singleton = nullptr;
  2229. ResourceImporterScene *ResourceImporterScene::animation_singleton = nullptr;
  2230. Vector<Ref<EditorSceneFormatImporter>> ResourceImporterScene::importers;
  2231. Vector<Ref<EditorScenePostImportPlugin>> ResourceImporterScene::post_importer_plugins;
  2232. bool ResourceImporterScene::ResourceImporterScene::has_advanced_options() const {
  2233. return true;
  2234. }
  2235. void ResourceImporterScene::ResourceImporterScene::show_advanced_options(const String &p_path) {
  2236. SceneImportSettings::get_singleton()->open_settings(p_path, animation_importer);
  2237. }
  2238. ResourceImporterScene::ResourceImporterScene(bool p_animation_import) {
  2239. if (p_animation_import) {
  2240. animation_singleton = this;
  2241. } else {
  2242. scene_singleton = this;
  2243. }
  2244. animation_importer = p_animation_import;
  2245. }
  2246. void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority) {
  2247. ERR_FAIL_COND(p_importer.is_null());
  2248. if (p_first_priority) {
  2249. importers.insert(0, p_importer);
  2250. } else {
  2251. importers.push_back(p_importer);
  2252. }
  2253. }
  2254. void ResourceImporterScene::remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) {
  2255. post_importer_plugins.erase(p_plugin);
  2256. }
  2257. void ResourceImporterScene::add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) {
  2258. ERR_FAIL_COND(p_plugin.is_null());
  2259. if (p_first_priority) {
  2260. post_importer_plugins.insert(0, p_plugin);
  2261. } else {
  2262. post_importer_plugins.push_back(p_plugin);
  2263. }
  2264. }
  2265. void ResourceImporterScene::remove_importer(Ref<EditorSceneFormatImporter> p_importer) {
  2266. importers.erase(p_importer);
  2267. }
  2268. void ResourceImporterScene::clean_up_importer_plugins() {
  2269. importers.clear();
  2270. post_importer_plugins.clear();
  2271. }
  2272. ///////////////////////////////////////
  2273. uint32_t EditorSceneFormatImporterESCN::get_import_flags() const {
  2274. return IMPORT_SCENE;
  2275. }
  2276. void EditorSceneFormatImporterESCN::get_extensions(List<String> *r_extensions) const {
  2277. r_extensions->push_back("escn");
  2278. }
  2279. Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) {
  2280. Error error;
  2281. Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
  2282. ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");
  2283. Node *scene = ps->instantiate();
  2284. TypedArray<Node> nodes = scene->find_children("*", "MeshInstance3D");
  2285. for (int32_t node_i = 0; node_i < nodes.size(); node_i++) {
  2286. MeshInstance3D *mesh_3d = cast_to<MeshInstance3D>(nodes[node_i]);
  2287. Ref<ImporterMesh> mesh;
  2288. mesh.instantiate();
  2289. // Ignore the aabb, it will be recomputed.
  2290. ImporterMeshInstance3D *importer_mesh_3d = memnew(ImporterMeshInstance3D);
  2291. importer_mesh_3d->set_name(mesh_3d->get_name());
  2292. importer_mesh_3d->set_transform(mesh_3d->get_relative_transform(mesh_3d->get_parent()));
  2293. importer_mesh_3d->set_skin(mesh_3d->get_skin());
  2294. importer_mesh_3d->set_skeleton_path(mesh_3d->get_skeleton_path());
  2295. Ref<ArrayMesh> array_mesh_3d_mesh = mesh_3d->get_mesh();
  2296. if (array_mesh_3d_mesh.is_valid()) {
  2297. // For the MeshInstance3D nodes, we need to convert the ArrayMesh to an ImporterMesh specially.
  2298. mesh->set_name(array_mesh_3d_mesh->get_name());
  2299. for (int32_t blend_i = 0; blend_i < array_mesh_3d_mesh->get_blend_shape_count(); blend_i++) {
  2300. mesh->add_blend_shape(array_mesh_3d_mesh->get_blend_shape_name(blend_i));
  2301. }
  2302. for (int32_t surface_i = 0; surface_i < array_mesh_3d_mesh->get_surface_count(); surface_i++) {
  2303. mesh->add_surface(array_mesh_3d_mesh->surface_get_primitive_type(surface_i),
  2304. array_mesh_3d_mesh->surface_get_arrays(surface_i),
  2305. array_mesh_3d_mesh->surface_get_blend_shape_arrays(surface_i),
  2306. array_mesh_3d_mesh->surface_get_lods(surface_i),
  2307. array_mesh_3d_mesh->surface_get_material(surface_i),
  2308. array_mesh_3d_mesh->surface_get_name(surface_i),
  2309. array_mesh_3d_mesh->surface_get_format(surface_i));
  2310. }
  2311. mesh->set_blend_shape_mode(array_mesh_3d_mesh->get_blend_shape_mode());
  2312. importer_mesh_3d->set_mesh(mesh);
  2313. mesh_3d->replace_by(importer_mesh_3d);
  2314. continue;
  2315. }
  2316. Ref<Mesh> mesh_3d_mesh = mesh_3d->get_mesh();
  2317. if (mesh_3d_mesh.is_valid()) {
  2318. // For the MeshInstance3D nodes, we need to convert the Mesh to an ImporterMesh specially.
  2319. mesh->set_name(mesh_3d_mesh->get_name());
  2320. for (int32_t surface_i = 0; surface_i < mesh_3d_mesh->get_surface_count(); surface_i++) {
  2321. mesh->add_surface(mesh_3d_mesh->surface_get_primitive_type(surface_i),
  2322. mesh_3d_mesh->surface_get_arrays(surface_i),
  2323. Array(),
  2324. mesh_3d_mesh->surface_get_lods(surface_i),
  2325. mesh_3d_mesh->surface_get_material(surface_i),
  2326. mesh_3d_mesh->surface_get_material(surface_i).is_valid() ? mesh_3d_mesh->surface_get_material(surface_i)->get_name() : String(),
  2327. mesh_3d_mesh->surface_get_format(surface_i));
  2328. }
  2329. importer_mesh_3d->set_mesh(mesh);
  2330. mesh_3d->replace_by(importer_mesh_3d);
  2331. continue;
  2332. }
  2333. }
  2334. ERR_FAIL_COND_V(!scene, nullptr);
  2335. return scene;
  2336. }