resource_importer_scene.cpp 138 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420
  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/dir_access.h"
  33. #include "core/io/resource_saver.h"
  34. #include "core/object/script_language.h"
  35. #include "editor/editor_interface.h"
  36. #include "editor/editor_node.h"
  37. #include "editor/editor_settings.h"
  38. #include "editor/import/3d/scene_import_settings.h"
  39. #include "scene/3d/importer_mesh_instance_3d.h"
  40. #include "scene/3d/mesh_instance_3d.h"
  41. #include "scene/3d/navigation/navigation_region_3d.h"
  42. #include "scene/3d/occluder_instance_3d.h"
  43. #include "scene/3d/physics/area_3d.h"
  44. #include "scene/3d/physics/collision_shape_3d.h"
  45. #include "scene/3d/physics/static_body_3d.h"
  46. #include "scene/3d/physics/vehicle_body_3d.h"
  47. #include "scene/animation/animation_player.h"
  48. #include "scene/resources/3d/box_shape_3d.h"
  49. #include "scene/resources/3d/importer_mesh.h"
  50. #include "scene/resources/3d/separation_ray_shape_3d.h"
  51. #include "scene/resources/3d/sphere_shape_3d.h"
  52. #include "scene/resources/3d/world_boundary_shape_3d.h"
  53. #include "scene/resources/animation.h"
  54. #include "scene/resources/bone_map.h"
  55. #include "scene/resources/packed_scene.h"
  56. #include "scene/resources/resource_format_text.h"
  57. void EditorSceneFormatImporter::get_extensions(List<String> *r_extensions) const {
  58. Vector<String> arr;
  59. if (GDVIRTUAL_CALL(_get_extensions, arr)) {
  60. for (int i = 0; i < arr.size(); i++) {
  61. r_extensions->push_back(arr[i]);
  62. }
  63. return;
  64. }
  65. ERR_FAIL();
  66. }
  67. 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) {
  68. Dictionary options_dict;
  69. for (const KeyValue<StringName, Variant> &elem : p_options) {
  70. options_dict[elem.key] = elem.value;
  71. }
  72. Object *ret = nullptr;
  73. if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, options_dict, ret)) {
  74. return Object::cast_to<Node>(ret);
  75. }
  76. ERR_FAIL_V(nullptr);
  77. }
  78. void EditorSceneFormatImporter::add_import_option(const String &p_name, const Variant &p_default_value) {
  79. ERR_FAIL_NULL_MSG(current_option_list, "add_import_option() can only be called from get_import_options().");
  80. add_import_option_advanced(p_default_value.get_type(), p_name, p_default_value);
  81. }
  82. void EditorSceneFormatImporter::add_import_option_advanced(Variant::Type p_type, const String &p_name, const Variant &p_default_value, PropertyHint p_hint, const String &p_hint_string, int p_usage_flags) {
  83. ERR_FAIL_NULL_MSG(current_option_list, "add_import_option_advanced() can only be called from get_import_options().");
  84. current_option_list->push_back(ResourceImporter::ImportOption(PropertyInfo(p_type, p_name, p_hint, p_hint_string, p_usage_flags), p_default_value));
  85. }
  86. void EditorSceneFormatImporter::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
  87. current_option_list = r_options;
  88. GDVIRTUAL_CALL(_get_import_options, p_path);
  89. current_option_list = nullptr;
  90. }
  91. Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, const String &p_scene_import_type, const String &p_option, const HashMap<StringName, Variant> &p_options) {
  92. Variant ret;
  93. // For compatibility with the old API, pass the import type as a boolean.
  94. GDVIRTUAL_CALL(_get_option_visibility, p_path, p_scene_import_type == "AnimationLibrary", p_option, ret);
  95. return ret;
  96. }
  97. void EditorSceneFormatImporter::_bind_methods() {
  98. ClassDB::bind_method(D_METHOD("add_import_option", "name", "value"), &EditorSceneFormatImporter::add_import_option);
  99. ClassDB::bind_method(D_METHOD("add_import_option_advanced", "type", "name", "default_value", "hint", "hint_string", "usage_flags"), &EditorSceneFormatImporter::add_import_option_advanced, DEFVAL(PROPERTY_HINT_NONE), DEFVAL(""), DEFVAL(PROPERTY_USAGE_DEFAULT));
  100. GDVIRTUAL_BIND(_get_extensions);
  101. GDVIRTUAL_BIND(_import_scene, "path", "flags", "options");
  102. GDVIRTUAL_BIND(_get_import_options, "path");
  103. GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option");
  104. BIND_CONSTANT(IMPORT_SCENE);
  105. BIND_CONSTANT(IMPORT_ANIMATION);
  106. BIND_CONSTANT(IMPORT_FAIL_ON_MISSING_DEPENDENCIES);
  107. BIND_CONSTANT(IMPORT_GENERATE_TANGENT_ARRAYS);
  108. BIND_CONSTANT(IMPORT_USE_NAMED_SKIN_BINDS);
  109. BIND_CONSTANT(IMPORT_DISCARD_MESHES_AND_MATERIALS);
  110. BIND_CONSTANT(IMPORT_FORCE_DISABLE_MESH_COMPRESSION);
  111. }
  112. /////////////////////////////////
  113. void EditorScenePostImport::_bind_methods() {
  114. GDVIRTUAL_BIND(_post_import, "scene")
  115. ClassDB::bind_method(D_METHOD("get_source_file"), &EditorScenePostImport::get_source_file);
  116. }
  117. Node *EditorScenePostImport::post_import(Node *p_scene) {
  118. Object *ret;
  119. if (GDVIRTUAL_CALL(_post_import, p_scene, ret)) {
  120. return Object::cast_to<Node>(ret);
  121. }
  122. return p_scene;
  123. }
  124. String EditorScenePostImport::get_source_file() const {
  125. return source_file;
  126. }
  127. void EditorScenePostImport::init(const String &p_source_file) {
  128. source_file = p_source_file;
  129. }
  130. ///////////////////////////////////////////////////////
  131. Variant EditorScenePostImportPlugin::get_option_value(const StringName &p_name) const {
  132. 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.");
  133. ERR_FAIL_COND_V_MSG(current_options && !current_options->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
  134. 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));
  135. if (current_options && current_options->has(p_name)) {
  136. return (*current_options)[p_name];
  137. }
  138. if (current_options_dict && current_options_dict->has(p_name)) {
  139. return (*current_options_dict)[p_name];
  140. }
  141. return Variant();
  142. }
  143. void EditorScenePostImportPlugin::add_import_option(const String &p_name, const Variant &p_default_value) {
  144. ERR_FAIL_NULL_MSG(current_option_list, "add_import_option() can only be called from get_import_options().");
  145. add_import_option_advanced(p_default_value.get_type(), p_name, p_default_value);
  146. }
  147. void EditorScenePostImportPlugin::add_import_option_advanced(Variant::Type p_type, const String &p_name, const Variant &p_default_value, PropertyHint p_hint, const String &p_hint_string, int p_usage_flags) {
  148. ERR_FAIL_NULL_MSG(current_option_list, "add_import_option_advanced() can only be called from get_import_options().");
  149. current_option_list->push_back(ResourceImporter::ImportOption(PropertyInfo(p_type, p_name, p_hint, p_hint_string, p_usage_flags), p_default_value));
  150. }
  151. void EditorScenePostImportPlugin::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
  152. current_option_list = r_options;
  153. GDVIRTUAL_CALL(_get_internal_import_options, p_category);
  154. current_option_list = nullptr;
  155. }
  156. Variant EditorScenePostImportPlugin::get_internal_option_visibility(InternalImportCategory p_category, const String &p_scene_import_type, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  157. current_options = &p_options;
  158. Variant ret;
  159. // For compatibility with the old API, pass the import type as a boolean.
  160. GDVIRTUAL_CALL(_get_internal_option_visibility, p_category, p_scene_import_type == "AnimationLibrary", p_option, ret);
  161. current_options = nullptr;
  162. return ret;
  163. }
  164. Variant EditorScenePostImportPlugin::get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  165. current_options = &p_options;
  166. Variant ret;
  167. GDVIRTUAL_CALL(_get_internal_option_update_view_required, p_category, p_option, ret);
  168. current_options = nullptr;
  169. return ret;
  170. }
  171. void EditorScenePostImportPlugin::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) {
  172. current_options_dict = &p_options;
  173. GDVIRTUAL_CALL(_internal_process, p_category, p_base_scene, p_node, p_resource);
  174. current_options_dict = nullptr;
  175. }
  176. void EditorScenePostImportPlugin::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
  177. current_option_list = r_options;
  178. GDVIRTUAL_CALL(_get_import_options, p_path);
  179. current_option_list = nullptr;
  180. }
  181. Variant EditorScenePostImportPlugin::get_option_visibility(const String &p_path, const String &p_scene_import_type, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  182. current_options = &p_options;
  183. Variant ret;
  184. GDVIRTUAL_CALL(_get_option_visibility, p_path, p_scene_import_type == "AnimationLibrary", p_option, ret);
  185. current_options = nullptr;
  186. return ret;
  187. }
  188. void EditorScenePostImportPlugin::pre_process(Node *p_scene, const HashMap<StringName, Variant> &p_options) {
  189. current_options = &p_options;
  190. GDVIRTUAL_CALL(_pre_process, p_scene);
  191. current_options = nullptr;
  192. }
  193. void EditorScenePostImportPlugin::post_process(Node *p_scene, const HashMap<StringName, Variant> &p_options) {
  194. current_options = &p_options;
  195. GDVIRTUAL_CALL(_post_process, p_scene);
  196. current_options = nullptr;
  197. }
  198. void EditorScenePostImportPlugin::_bind_methods() {
  199. ClassDB::bind_method(D_METHOD("get_option_value", "name"), &EditorScenePostImportPlugin::get_option_value);
  200. ClassDB::bind_method(D_METHOD("add_import_option", "name", "value"), &EditorScenePostImportPlugin::add_import_option);
  201. 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));
  202. GDVIRTUAL_BIND(_get_internal_import_options, "category");
  203. GDVIRTUAL_BIND(_get_internal_option_visibility, "category", "for_animation", "option");
  204. GDVIRTUAL_BIND(_get_internal_option_update_view_required, "category", "option");
  205. GDVIRTUAL_BIND(_internal_process, "category", "base_node", "node", "resource");
  206. GDVIRTUAL_BIND(_get_import_options, "path");
  207. GDVIRTUAL_BIND(_get_option_visibility, "path", "for_animation", "option");
  208. GDVIRTUAL_BIND(_pre_process, "scene");
  209. GDVIRTUAL_BIND(_post_process, "scene");
  210. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_NODE);
  211. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE);
  212. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MESH);
  213. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MATERIAL);
  214. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION);
  215. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE);
  216. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE);
  217. BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MAX);
  218. }
  219. /////////////////////////////////////////////////////////
  220. String ResourceImporterScene::get_importer_name() const {
  221. // For compatibility with 4.2 and earlier we need to keep the "scene" and "animation_library" names.
  222. // However this is arbitrary so for new import types we can use any string.
  223. if (_scene_import_type == "PackedScene") {
  224. return "scene";
  225. } else if (_scene_import_type == "AnimationLibrary") {
  226. return "animation_library";
  227. }
  228. return _scene_import_type;
  229. }
  230. String ResourceImporterScene::get_visible_name() const {
  231. // This is displayed on the UI. Friendly names here are nice but not vital, so fall back to the type.
  232. if (_scene_import_type == "PackedScene") {
  233. return "Scene";
  234. }
  235. return _scene_import_type.capitalize();
  236. }
  237. void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const {
  238. get_scene_importer_extensions(p_extensions);
  239. }
  240. String ResourceImporterScene::get_save_extension() const {
  241. if (_scene_import_type == "PackedScene") {
  242. return "scn";
  243. }
  244. return "res";
  245. }
  246. String ResourceImporterScene::get_resource_type() const {
  247. return _scene_import_type;
  248. }
  249. int ResourceImporterScene::get_format_version() const {
  250. return 1;
  251. }
  252. bool ResourceImporterScene::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  253. if (_scene_import_type == "PackedScene") {
  254. if (p_option.begins_with("animation/")) {
  255. if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
  256. return false;
  257. }
  258. }
  259. } else if (_scene_import_type == "AnimationLibrary") {
  260. if (p_option == "animation/import") { // Option ignored, animation always imported.
  261. return false;
  262. }
  263. if (p_option == "nodes/root_type" || p_option == "nodes/root_name" || p_option.begins_with("meshes/") || p_option.begins_with("skins/")) {
  264. return false; // Nothing to do here for animations.
  265. }
  266. }
  267. if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) != 2) {
  268. // Only display the lightmap texel size import option when using the Static Lightmaps light baking mode.
  269. return false;
  270. }
  271. for (int i = 0; i < post_importer_plugins.size(); i++) {
  272. Variant ret = post_importer_plugins.write[i]->get_option_visibility(p_path, _scene_import_type, p_option, p_options);
  273. if (ret.get_type() == Variant::BOOL) {
  274. if (!ret) {
  275. return false;
  276. }
  277. }
  278. }
  279. for (Ref<EditorSceneFormatImporter> importer : scene_importers) {
  280. Variant ret = importer->get_option_visibility(p_path, _scene_import_type, p_option, p_options);
  281. if (ret.get_type() == Variant::BOOL) {
  282. if (!ret) {
  283. return false;
  284. }
  285. }
  286. }
  287. return true;
  288. }
  289. int ResourceImporterScene::get_preset_count() const {
  290. return 0;
  291. }
  292. String ResourceImporterScene::get_preset_name(int p_idx) const {
  293. return String();
  294. }
  295. void ResourceImporterScene::_pre_fix_global(Node *p_scene, const HashMap<StringName, Variant> &p_options) const {
  296. if (p_options.has("animation/import_rest_as_RESET") && (bool)p_options["animation/import_rest_as_RESET"]) {
  297. TypedArray<Node> anim_players = p_scene->find_children("*", "AnimationPlayer");
  298. if (anim_players.is_empty()) {
  299. AnimationPlayer *anim_player = memnew(AnimationPlayer);
  300. anim_player->set_name("AnimationPlayer");
  301. p_scene->add_child(anim_player);
  302. anim_player->set_owner(p_scene);
  303. anim_players.append(anim_player);
  304. }
  305. Ref<Animation> reset_anim;
  306. for (int i = 0; i < anim_players.size(); i++) {
  307. AnimationPlayer *player = cast_to<AnimationPlayer>(anim_players[i]);
  308. if (player->has_animation(SceneStringName(RESET))) {
  309. reset_anim = player->get_animation(SceneStringName(RESET));
  310. break;
  311. }
  312. }
  313. if (reset_anim.is_null()) {
  314. AnimationPlayer *anim_player = cast_to<AnimationPlayer>(anim_players[0]);
  315. reset_anim.instantiate();
  316. Ref<AnimationLibrary> anim_library;
  317. if (anim_player->has_animation_library(StringName())) {
  318. anim_library = anim_player->get_animation_library(StringName());
  319. } else {
  320. anim_library.instantiate();
  321. anim_player->add_animation_library(StringName(), anim_library);
  322. }
  323. anim_library->add_animation(SceneStringName(RESET), reset_anim);
  324. }
  325. TypedArray<Node> skeletons = p_scene->find_children("*", "Skeleton3D");
  326. for (int i = 0; i < skeletons.size(); i++) {
  327. Skeleton3D *skeleton = cast_to<Skeleton3D>(skeletons[i]);
  328. NodePath skeleton_path = p_scene->get_path_to(skeleton);
  329. HashSet<NodePath> existing_pos_tracks;
  330. HashSet<NodePath> existing_rot_tracks;
  331. for (int trk_i = 0; trk_i < reset_anim->get_track_count(); trk_i++) {
  332. NodePath np = reset_anim->track_get_path(trk_i);
  333. if (reset_anim->track_get_type(trk_i) == Animation::TYPE_POSITION_3D) {
  334. existing_pos_tracks.insert(np);
  335. }
  336. if (reset_anim->track_get_type(trk_i) == Animation::TYPE_ROTATION_3D) {
  337. existing_rot_tracks.insert(np);
  338. }
  339. }
  340. for (int bone_i = 0; bone_i < skeleton->get_bone_count(); bone_i++) {
  341. NodePath bone_path(skeleton_path.get_names(), Vector<StringName>{ skeleton->get_bone_name(bone_i) }, false);
  342. if (!existing_pos_tracks.has(bone_path)) {
  343. int pos_t = reset_anim->add_track(Animation::TYPE_POSITION_3D);
  344. reset_anim->track_set_path(pos_t, bone_path);
  345. reset_anim->position_track_insert_key(pos_t, 0.0, skeleton->get_bone_rest(bone_i).origin);
  346. reset_anim->track_set_imported(pos_t, true);
  347. }
  348. if (!existing_rot_tracks.has(bone_path)) {
  349. int rot_t = reset_anim->add_track(Animation::TYPE_ROTATION_3D);
  350. reset_anim->track_set_path(rot_t, bone_path);
  351. reset_anim->rotation_track_insert_key(rot_t, 0.0, skeleton->get_bone_rest(bone_i).basis.get_rotation_quaternion());
  352. reset_anim->track_set_imported(rot_t, true);
  353. }
  354. }
  355. }
  356. }
  357. }
  358. static bool _teststr(const String &p_what, const String &p_str) {
  359. String what = p_what;
  360. // Remove trailing spaces and numbers, some apps like blender add ".number" to duplicates
  361. // (dot is replaced with _ as invalid character) so also compensate for this.
  362. while (what.length() && (is_digit(what[what.length() - 1]) || what[what.length() - 1] <= 32 || what[what.length() - 1] == '_')) {
  363. what = what.substr(0, what.length() - 1);
  364. }
  365. if (what.containsn("$" + p_str)) { // Blender and other stuff.
  366. return true;
  367. }
  368. if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
  369. return true;
  370. }
  371. if (what.to_lower().ends_with("_" + p_str)) { //collada only supports "_" and "-" besides letters
  372. return true;
  373. }
  374. return false;
  375. }
  376. static String _fixstr(const String &p_what, const String &p_str) {
  377. String what = p_what;
  378. // Remove trailing spaces and numbers, some apps like blender add ".number" to duplicates
  379. // (dot is replaced with _ as invalid character) so also compensate for this.
  380. while (what.length() && (is_digit(what[what.length() - 1]) || what[what.length() - 1] <= 32 || what[what.length() - 1] == '_')) {
  381. what = what.substr(0, what.length() - 1);
  382. }
  383. String end = p_what.substr(what.length());
  384. if (what.containsn("$" + p_str)) { // Blender and other stuff.
  385. return what.replace("$" + p_str, "") + end;
  386. }
  387. if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
  388. return what.substr(0, what.length() - (p_str.length() + 1)) + end;
  389. }
  390. if (what.to_lower().ends_with("_" + p_str)) { //collada only supports "_" and "-" besides letters
  391. return what.substr(0, what.length() - (p_str.length() + 1)) + end;
  392. }
  393. return what;
  394. }
  395. static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r_shape_list, bool p_convex) {
  396. ERR_FAIL_COND_MSG(mesh.is_null(), "Cannot generate shape list with null mesh value.");
  397. if (!p_convex) {
  398. Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape();
  399. r_shape_list.push_back(shape);
  400. } else {
  401. Vector<Ref<Shape3D>> cd;
  402. cd.push_back(mesh->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
  403. if (cd.size()) {
  404. for (int i = 0; i < cd.size(); i++) {
  405. r_shape_list.push_back(cd[i]);
  406. }
  407. }
  408. }
  409. }
  410. struct ScalableNodeCollection {
  411. HashSet<Node3D *> node_3ds;
  412. HashSet<Ref<ImporterMesh>> importer_meshes;
  413. HashSet<Ref<Skin>> skins;
  414. HashSet<Ref<Animation>> animations;
  415. };
  416. void _rescale_importer_mesh(Vector3 p_scale, Ref<ImporterMesh> p_mesh, bool is_shadow = false) {
  417. // MESH and SKIN data divide, to compensate for object position multiplying.
  418. const int surf_count = p_mesh->get_surface_count();
  419. const int blendshape_count = p_mesh->get_blend_shape_count();
  420. struct LocalSurfData {
  421. Mesh::PrimitiveType prim = {};
  422. Array arr;
  423. Array bsarr;
  424. Dictionary lods;
  425. String name;
  426. Ref<Material> mat;
  427. uint64_t fmt_compress_flags = 0;
  428. };
  429. Vector<LocalSurfData> surf_data_by_mesh;
  430. Vector<String> blendshape_names;
  431. for (int bsidx = 0; bsidx < blendshape_count; bsidx++) {
  432. blendshape_names.append(p_mesh->get_blend_shape_name(bsidx));
  433. }
  434. for (int surf_idx = 0; surf_idx < surf_count; surf_idx++) {
  435. Mesh::PrimitiveType prim = p_mesh->get_surface_primitive_type(surf_idx);
  436. const uint64_t fmt_compress_flags = p_mesh->get_surface_format(surf_idx);
  437. Array arr = p_mesh->get_surface_arrays(surf_idx);
  438. String name = p_mesh->get_surface_name(surf_idx);
  439. Dictionary lods;
  440. Ref<Material> mat = p_mesh->get_surface_material(surf_idx);
  441. {
  442. Vector<Vector3> vertex_array = arr[ArrayMesh::ARRAY_VERTEX];
  443. for (int vert_arr_i = 0; vert_arr_i < vertex_array.size(); vert_arr_i++) {
  444. vertex_array.write[vert_arr_i] = vertex_array[vert_arr_i] * p_scale;
  445. }
  446. arr[ArrayMesh::ARRAY_VERTEX] = vertex_array;
  447. }
  448. Array blendshapes;
  449. for (int bsidx = 0; bsidx < blendshape_count; bsidx++) {
  450. Array current_bsarr = p_mesh->get_surface_blend_shape_arrays(surf_idx, bsidx);
  451. Vector<Vector3> current_bs_vertex_array = current_bsarr[ArrayMesh::ARRAY_VERTEX];
  452. int current_bs_vert_arr_len = current_bs_vertex_array.size();
  453. for (int32_t bs_vert_arr_i = 0; bs_vert_arr_i < current_bs_vert_arr_len; bs_vert_arr_i++) {
  454. current_bs_vertex_array.write[bs_vert_arr_i] = current_bs_vertex_array[bs_vert_arr_i] * p_scale;
  455. }
  456. current_bsarr[ArrayMesh::ARRAY_VERTEX] = current_bs_vertex_array;
  457. blendshapes.push_back(current_bsarr);
  458. }
  459. LocalSurfData surf_data_dictionary = LocalSurfData();
  460. surf_data_dictionary.prim = prim;
  461. surf_data_dictionary.arr = arr;
  462. surf_data_dictionary.bsarr = blendshapes;
  463. surf_data_dictionary.lods = lods;
  464. surf_data_dictionary.fmt_compress_flags = fmt_compress_flags;
  465. surf_data_dictionary.name = name;
  466. surf_data_dictionary.mat = mat;
  467. surf_data_by_mesh.push_back(surf_data_dictionary);
  468. }
  469. p_mesh->clear();
  470. for (int bsidx = 0; bsidx < blendshape_count; bsidx++) {
  471. p_mesh->add_blend_shape(blendshape_names[bsidx]);
  472. }
  473. for (int surf_idx = 0; surf_idx < surf_count; surf_idx++) {
  474. const Mesh::PrimitiveType prim = surf_data_by_mesh[surf_idx].prim;
  475. const Array arr = surf_data_by_mesh[surf_idx].arr;
  476. const Array bsarr = surf_data_by_mesh[surf_idx].bsarr;
  477. const Dictionary lods = surf_data_by_mesh[surf_idx].lods;
  478. const uint64_t fmt_compress_flags = surf_data_by_mesh[surf_idx].fmt_compress_flags;
  479. const String name = surf_data_by_mesh[surf_idx].name;
  480. const Ref<Material> mat = surf_data_by_mesh[surf_idx].mat;
  481. p_mesh->add_surface(prim, arr, bsarr, lods, mat, name, fmt_compress_flags);
  482. }
  483. if (!is_shadow && p_mesh->get_shadow_mesh() != p_mesh && p_mesh->get_shadow_mesh().is_valid()) {
  484. _rescale_importer_mesh(p_scale, p_mesh->get_shadow_mesh(), true);
  485. }
  486. }
  487. void _rescale_skin(Vector3 p_scale, Ref<Skin> p_skin) {
  488. // MESH and SKIN data divide, to compensate for object position multiplying.
  489. for (int i = 0; i < p_skin->get_bind_count(); i++) {
  490. Transform3D transform = p_skin->get_bind_pose(i);
  491. p_skin->set_bind_pose(i, Transform3D(transform.basis, p_scale * transform.origin));
  492. }
  493. }
  494. void _rescale_animation(Vector3 p_scale, Ref<Animation> p_animation) {
  495. for (int track_idx = 0; track_idx < p_animation->get_track_count(); track_idx++) {
  496. if (p_animation->track_get_type(track_idx) == Animation::TYPE_POSITION_3D) {
  497. for (int key_idx = 0; key_idx < p_animation->track_get_key_count(track_idx); key_idx++) {
  498. Vector3 value = p_animation->track_get_key_value(track_idx, key_idx);
  499. value = p_scale * value;
  500. p_animation->track_set_key_value(track_idx, key_idx, value);
  501. }
  502. }
  503. }
  504. }
  505. void _apply_scale_to_scalable_node_collection(ScalableNodeCollection &p_collection, Vector3 p_scale) {
  506. for (Node3D *node_3d : p_collection.node_3ds) {
  507. node_3d->set_position(p_scale * node_3d->get_position());
  508. Skeleton3D *skeleton_3d = Object::cast_to<Skeleton3D>(node_3d);
  509. if (skeleton_3d) {
  510. for (int i = 0; i < skeleton_3d->get_bone_count(); i++) {
  511. Transform3D rest = skeleton_3d->get_bone_rest(i);
  512. Vector3 position = skeleton_3d->get_bone_pose_position(i);
  513. skeleton_3d->set_bone_rest(i, Transform3D(rest.basis, p_scale * rest.origin));
  514. skeleton_3d->set_bone_pose_position(i, p_scale * position);
  515. }
  516. }
  517. }
  518. for (Ref<ImporterMesh> mesh : p_collection.importer_meshes) {
  519. _rescale_importer_mesh(p_scale, mesh, false);
  520. }
  521. for (Ref<Skin> skin : p_collection.skins) {
  522. _rescale_skin(p_scale, skin);
  523. }
  524. for (Ref<Animation> animation : p_collection.animations) {
  525. _rescale_animation(p_scale, animation);
  526. }
  527. }
  528. void _populate_scalable_nodes_collection(Node *p_node, ScalableNodeCollection &p_collection) {
  529. if (!p_node) {
  530. return;
  531. }
  532. Node3D *node_3d = Object::cast_to<Node3D>(p_node);
  533. if (node_3d) {
  534. p_collection.node_3ds.insert(node_3d);
  535. ImporterMeshInstance3D *mesh_instance_3d = Object::cast_to<ImporterMeshInstance3D>(p_node);
  536. if (mesh_instance_3d) {
  537. Ref<ImporterMesh> mesh = mesh_instance_3d->get_mesh();
  538. if (mesh.is_valid()) {
  539. p_collection.importer_meshes.insert(mesh);
  540. }
  541. Ref<Skin> skin = mesh_instance_3d->get_skin();
  542. if (skin.is_valid()) {
  543. p_collection.skins.insert(skin);
  544. }
  545. }
  546. }
  547. AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_node);
  548. if (animation_player) {
  549. List<StringName> animation_list;
  550. animation_player->get_animation_list(&animation_list);
  551. for (const StringName &E : animation_list) {
  552. Ref<Animation> animation = animation_player->get_animation(E);
  553. p_collection.animations.insert(animation);
  554. }
  555. }
  556. for (int i = 0; i < p_node->get_child_count(); i++) {
  557. Node *child = p_node->get_child(i);
  558. _populate_scalable_nodes_collection(child, p_collection);
  559. }
  560. }
  561. void _apply_permanent_scale_to_descendants(Node *p_root_node, Vector3 p_scale) {
  562. ScalableNodeCollection scalable_node_collection;
  563. _populate_scalable_nodes_collection(p_root_node, scalable_node_collection);
  564. _apply_scale_to_scalable_node_collection(scalable_node_collection, p_scale);
  565. }
  566. 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, const HashMap<StringName, Variant> &p_options) {
  567. // Children first.
  568. for (int i = 0; i < p_node->get_child_count(); i++) {
  569. Node *r = _pre_fix_node(p_node->get_child(i), p_root, r_collision_map, r_occluder_arrays, r_node_renames, p_options);
  570. if (!r) {
  571. i--; // Was erased.
  572. }
  573. }
  574. String name = p_node->get_name();
  575. NodePath original_path = p_root->get_path_to(p_node); // Used to detect renames due to import hints.
  576. Ref<Resource> original_meta = memnew(Resource); // Create temp resource to hold original meta
  577. original_meta->merge_meta_from(p_node);
  578. bool isroot = p_node == p_root;
  579. if (!isroot && _teststr(name, "noimp")) {
  580. p_node->set_owner(nullptr);
  581. memdelete(p_node);
  582. return nullptr;
  583. }
  584. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  585. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  586. Ref<ImporterMesh> m = mi->get_mesh();
  587. if (m.is_valid()) {
  588. for (int i = 0; i < m->get_surface_count(); i++) {
  589. Ref<BaseMaterial3D> mat = m->get_surface_material(i);
  590. if (mat.is_null()) {
  591. continue;
  592. }
  593. if (_teststr(mat->get_name(), "alpha")) {
  594. mat->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
  595. mat->set_name(_fixstr(mat->get_name(), "alpha"));
  596. }
  597. if (_teststr(mat->get_name(), "vcol")) {
  598. mat->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  599. mat->set_flag(BaseMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
  600. mat->set_name(_fixstr(mat->get_name(), "vcol"));
  601. }
  602. }
  603. }
  604. }
  605. if (Object::cast_to<AnimationPlayer>(p_node)) {
  606. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  607. // Node paths in animation tracks are relative to the following path (this is used to fix node paths below).
  608. Node *ap_root = ap->get_node(ap->get_root_node());
  609. NodePath path_prefix = p_root->get_path_to(ap_root);
  610. bool nodes_were_renamed = r_node_renames.size() != 0;
  611. List<StringName> anims;
  612. ap->get_animation_list(&anims);
  613. for (const StringName &E : anims) {
  614. Ref<Animation> anim = ap->get_animation(E);
  615. ERR_CONTINUE(anim.is_null());
  616. // Remove animation tracks referencing non-importable nodes.
  617. for (int i = 0; i < anim->get_track_count(); i++) {
  618. NodePath path = anim->track_get_path(i);
  619. for (int j = 0; j < path.get_name_count(); j++) {
  620. String node = path.get_name(j);
  621. if (_teststr(node, "noimp")) {
  622. anim->remove_track(i);
  623. i--;
  624. break;
  625. }
  626. }
  627. }
  628. // Fix node paths in animations, in case nodes were renamed earlier due to import hints.
  629. if (nodes_were_renamed) {
  630. for (int i = 0; i < anim->get_track_count(); i++) {
  631. NodePath path = anim->track_get_path(i);
  632. // Convert track path to absolute node path without subnames (some manual work because we are not in the scene tree).
  633. Vector<StringName> absolute_path_names = path_prefix.get_names();
  634. absolute_path_names.append_array(path.get_names());
  635. NodePath absolute_path(absolute_path_names, false);
  636. absolute_path.simplify();
  637. // Fix paths to renamed nodes.
  638. for (const Pair<NodePath, Node *> &F : r_node_renames) {
  639. if (F.first == absolute_path) {
  640. NodePath new_path(ap_root->get_path_to(F.second).get_names(), path.get_subnames(), false);
  641. print_verbose(vformat("Fix: Correcting node path in animation track: %s should be %s", path, new_path));
  642. anim->track_set_path(i, new_path);
  643. break; // Only one match is possible.
  644. }
  645. }
  646. }
  647. }
  648. String animname = E;
  649. const int loop_string_count = 3;
  650. static const char *loop_strings[loop_string_count] = { "loop_mode", "loop", "cycle" };
  651. for (int i = 0; i < loop_string_count; i++) {
  652. if (_teststr(animname, loop_strings[i])) {
  653. anim->set_loop_mode(Animation::LOOP_LINEAR);
  654. animname = _fixstr(animname, loop_strings[i]);
  655. Ref<AnimationLibrary> library = ap->get_animation_library(ap->find_animation_library(anim));
  656. library->rename_animation(E, animname);
  657. }
  658. }
  659. }
  660. }
  661. bool use_node_type_suffixes = true;
  662. if (p_options.has("nodes/use_node_type_suffixes")) {
  663. use_node_type_suffixes = p_options["nodes/use_node_type_suffixes"];
  664. }
  665. if (!use_node_type_suffixes) {
  666. return p_node;
  667. }
  668. if (_teststr(name, "colonly") || _teststr(name, "convcolonly")) {
  669. if (isroot) {
  670. return p_node;
  671. }
  672. String fixed_name;
  673. if (_teststr(name, "colonly")) {
  674. fixed_name = _fixstr(name, "colonly");
  675. } else if (_teststr(name, "convcolonly")) {
  676. fixed_name = _fixstr(name, "convcolonly");
  677. }
  678. if (fixed_name.is_empty()) {
  679. p_node->set_owner(nullptr);
  680. memdelete(p_node);
  681. ERR_FAIL_V_MSG(nullptr, vformat("Skipped node `%s` because its name is empty after removing the suffix.", name));
  682. }
  683. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  684. if (mi) {
  685. Ref<ImporterMesh> mesh = mi->get_mesh();
  686. if (mesh.is_valid()) {
  687. Vector<Ref<Shape3D>> shapes;
  688. if (r_collision_map.has(mesh)) {
  689. shapes = r_collision_map[mesh];
  690. } else if (_teststr(name, "colonly")) {
  691. _pre_gen_shape_list(mesh, shapes, false);
  692. r_collision_map[mesh] = shapes;
  693. } else if (_teststr(name, "convcolonly")) {
  694. _pre_gen_shape_list(mesh, shapes, true);
  695. r_collision_map[mesh] = shapes;
  696. }
  697. if (shapes.size()) {
  698. StaticBody3D *col = memnew(StaticBody3D);
  699. col->set_transform(mi->get_transform());
  700. col->set_name(fixed_name);
  701. _copy_meta(p_node, col);
  702. p_node->replace_by(col);
  703. p_node->set_owner(nullptr);
  704. memdelete(p_node);
  705. p_node = col;
  706. _add_shapes(col, shapes);
  707. }
  708. }
  709. } else if (p_node->has_meta("empty_draw_type")) {
  710. String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
  711. StaticBody3D *sb = memnew(StaticBody3D);
  712. sb->set_name(fixed_name);
  713. Object::cast_to<Node3D>(sb)->set_transform(Object::cast_to<Node3D>(p_node)->get_transform());
  714. _copy_meta(p_node, sb);
  715. p_node->replace_by(sb);
  716. p_node->set_owner(nullptr);
  717. memdelete(p_node);
  718. p_node = sb;
  719. CollisionShape3D *colshape = memnew(CollisionShape3D);
  720. if (empty_draw_type == "CUBE") {
  721. BoxShape3D *boxShape = memnew(BoxShape3D);
  722. boxShape->set_size(Vector3(2, 2, 2));
  723. colshape->set_shape(boxShape);
  724. } else if (empty_draw_type == "SINGLE_ARROW") {
  725. SeparationRayShape3D *rayShape = memnew(SeparationRayShape3D);
  726. rayShape->set_length(1);
  727. colshape->set_shape(rayShape);
  728. Object::cast_to<Node3D>(sb)->rotate_x(Math_PI / 2);
  729. } else if (empty_draw_type == "IMAGE") {
  730. WorldBoundaryShape3D *world_boundary_shape = memnew(WorldBoundaryShape3D);
  731. colshape->set_shape(world_boundary_shape);
  732. } else {
  733. SphereShape3D *sphereShape = memnew(SphereShape3D);
  734. sphereShape->set_radius(1);
  735. colshape->set_shape(sphereShape);
  736. }
  737. sb->add_child(colshape, true);
  738. colshape->set_owner(sb->get_owner());
  739. }
  740. } else if (_teststr(name, "rigid") && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  741. if (isroot) {
  742. return p_node;
  743. }
  744. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  745. Ref<ImporterMesh> mesh = mi->get_mesh();
  746. if (mesh.is_valid()) {
  747. Vector<Ref<Shape3D>> shapes;
  748. if (r_collision_map.has(mesh)) {
  749. shapes = r_collision_map[mesh];
  750. } else {
  751. _pre_gen_shape_list(mesh, shapes, true);
  752. }
  753. RigidBody3D *rigid_body = memnew(RigidBody3D);
  754. rigid_body->set_name(_fixstr(name, "rigid_body"));
  755. _copy_meta(p_node, rigid_body);
  756. p_node->replace_by(rigid_body);
  757. rigid_body->set_transform(mi->get_transform());
  758. p_node = rigid_body;
  759. mi->set_transform(Transform3D());
  760. rigid_body->add_child(mi, true);
  761. mi->set_owner(rigid_body->get_owner());
  762. _add_shapes(rigid_body, shapes);
  763. }
  764. } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  765. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  766. Ref<ImporterMesh> mesh = mi->get_mesh();
  767. if (mesh.is_valid()) {
  768. Vector<Ref<Shape3D>> shapes;
  769. String fixed_name;
  770. if (r_collision_map.has(mesh)) {
  771. shapes = r_collision_map[mesh];
  772. } else if (_teststr(name, "col")) {
  773. _pre_gen_shape_list(mesh, shapes, false);
  774. r_collision_map[mesh] = shapes;
  775. } else if (_teststr(name, "convcol")) {
  776. _pre_gen_shape_list(mesh, shapes, true);
  777. r_collision_map[mesh] = shapes;
  778. }
  779. if (_teststr(name, "col")) {
  780. fixed_name = _fixstr(name, "col");
  781. } else if (_teststr(name, "convcol")) {
  782. fixed_name = _fixstr(name, "convcol");
  783. }
  784. if (!fixed_name.is_empty()) {
  785. if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
  786. mi->set_name(fixed_name);
  787. }
  788. }
  789. if (shapes.size()) {
  790. StaticBody3D *col = memnew(StaticBody3D);
  791. mi->add_child(col, true);
  792. col->set_owner(mi->get_owner());
  793. _add_shapes(col, shapes);
  794. }
  795. }
  796. } else if (_teststr(name, "navmesh") && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  797. if (isroot) {
  798. return p_node;
  799. }
  800. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  801. Ref<ImporterMesh> mesh = mi->get_mesh();
  802. ERR_FAIL_COND_V(mesh.is_null(), nullptr);
  803. NavigationRegion3D *nmi = memnew(NavigationRegion3D);
  804. nmi->set_name(_fixstr(name, "navmesh"));
  805. Ref<NavigationMesh> nmesh = mesh->create_navigation_mesh();
  806. nmi->set_navigation_mesh(nmesh);
  807. Object::cast_to<Node3D>(nmi)->set_transform(mi->get_transform());
  808. _copy_meta(p_node, nmi);
  809. p_node->replace_by(nmi);
  810. p_node->set_owner(nullptr);
  811. memdelete(p_node);
  812. p_node = nmi;
  813. } else if (_teststr(name, "occ") || _teststr(name, "occonly")) {
  814. if (isroot) {
  815. return p_node;
  816. }
  817. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  818. if (mi) {
  819. Ref<ImporterMesh> mesh = mi->get_mesh();
  820. if (mesh.is_valid()) {
  821. if (r_occluder_arrays) {
  822. OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second);
  823. }
  824. if (_teststr(name, "occ")) {
  825. String fixed_name = _fixstr(name, "occ");
  826. if (!fixed_name.is_empty()) {
  827. if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
  828. mi->set_name(fixed_name);
  829. }
  830. }
  831. } else {
  832. p_node->set_owner(nullptr);
  833. memdelete(p_node);
  834. p_node = nullptr;
  835. }
  836. }
  837. }
  838. } else if (_teststr(name, "vehicle")) {
  839. if (isroot) {
  840. return p_node;
  841. }
  842. Node *owner = p_node->get_owner();
  843. Node3D *s = Object::cast_to<Node3D>(p_node);
  844. VehicleBody3D *bv = memnew(VehicleBody3D);
  845. String n = _fixstr(p_node->get_name(), "vehicle");
  846. bv->set_name(n);
  847. _copy_meta(p_node, bv);
  848. p_node->replace_by(bv);
  849. p_node->set_name(n);
  850. bv->add_child(p_node);
  851. bv->set_owner(owner);
  852. p_node->set_owner(owner);
  853. bv->set_transform(s->get_transform());
  854. s->set_transform(Transform3D());
  855. p_node = bv;
  856. } else if (_teststr(name, "wheel")) {
  857. if (isroot) {
  858. return p_node;
  859. }
  860. Node *owner = p_node->get_owner();
  861. Node3D *s = Object::cast_to<Node3D>(p_node);
  862. VehicleWheel3D *bv = memnew(VehicleWheel3D);
  863. String n = _fixstr(p_node->get_name(), "wheel");
  864. bv->set_name(n);
  865. _copy_meta(p_node, bv);
  866. p_node->replace_by(bv);
  867. p_node->set_name(n);
  868. bv->add_child(p_node);
  869. bv->set_owner(owner);
  870. p_node->set_owner(owner);
  871. bv->set_transform(s->get_transform());
  872. s->set_transform(Transform3D());
  873. p_node = bv;
  874. } else if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  875. //last attempt, maybe collision inside the mesh data
  876. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  877. Ref<ImporterMesh> mesh = mi->get_mesh();
  878. if (mesh.is_valid()) {
  879. Vector<Ref<Shape3D>> shapes;
  880. if (r_collision_map.has(mesh)) {
  881. shapes = r_collision_map[mesh];
  882. } else if (_teststr(mesh->get_name(), "col")) {
  883. _pre_gen_shape_list(mesh, shapes, false);
  884. r_collision_map[mesh] = shapes;
  885. mesh->set_name(_fixstr(mesh->get_name(), "col"));
  886. } else if (_teststr(mesh->get_name(), "convcol")) {
  887. _pre_gen_shape_list(mesh, shapes, true);
  888. r_collision_map[mesh] = shapes;
  889. mesh->set_name(_fixstr(mesh->get_name(), "convcol"));
  890. } else if (_teststr(mesh->get_name(), "occ")) {
  891. if (r_occluder_arrays) {
  892. OccluderInstance3D::bake_single_node(mi, 0.0f, r_occluder_arrays->first, r_occluder_arrays->second);
  893. }
  894. mesh->set_name(_fixstr(mesh->get_name(), "occ"));
  895. }
  896. if (shapes.size()) {
  897. StaticBody3D *col = memnew(StaticBody3D);
  898. p_node->add_child(col, true);
  899. col->set_owner(p_node->get_owner());
  900. _add_shapes(col, shapes);
  901. }
  902. }
  903. }
  904. if (p_node) {
  905. NodePath new_path = p_root->get_path_to(p_node);
  906. if (new_path != original_path) {
  907. print_verbose(vformat("Fix: Renamed %s to %s", original_path, new_path));
  908. r_node_renames.push_back({ original_path, p_node });
  909. }
  910. // If we created new node instead, merge meta values from the original node.
  911. p_node->merge_meta_from(*original_meta);
  912. }
  913. return p_node;
  914. }
  915. 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) {
  916. // children first
  917. for (int i = 0; i < p_node->get_child_count(); i++) {
  918. Node *r = _pre_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps);
  919. if (!r) {
  920. i--; //was erased
  921. }
  922. }
  923. String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node));
  924. Dictionary node_settings;
  925. if (p_node_data.has(import_id)) {
  926. node_settings = p_node_data[import_id];
  927. }
  928. {
  929. //make sure this is unique
  930. node_settings = node_settings.duplicate(true);
  931. //fill node settings for this node with default values
  932. List<ImportOption> iopts;
  933. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
  934. for (const ImportOption &E : iopts) {
  935. if (!node_settings.has(E.option.name)) {
  936. node_settings[E.option.name] = E.default_value;
  937. }
  938. }
  939. }
  940. if (Object::cast_to<AnimationPlayer>(p_node)) {
  941. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  942. List<StringName> anims;
  943. ap->get_animation_list(&anims);
  944. AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = {
  945. AnimationImportTracks(int(node_settings["import_tracks/position"])),
  946. AnimationImportTracks(int(node_settings["import_tracks/rotation"])),
  947. AnimationImportTracks(int(node_settings["import_tracks/scale"]))
  948. };
  949. if (!anims.is_empty() && (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)) {
  950. _optimize_track_usage(ap, import_tracks_mode);
  951. }
  952. }
  953. return p_node;
  954. }
  955. 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, bool p_remove_immutable_tracks) {
  956. // children first
  957. for (int i = 0; i < p_node->get_child_count(); i++) {
  958. Node *r = _post_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps, p_remove_immutable_tracks);
  959. if (!r) {
  960. i--; //was erased
  961. }
  962. }
  963. String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node));
  964. Dictionary node_settings;
  965. if (p_node_data.has(import_id)) {
  966. node_settings = p_node_data[import_id];
  967. }
  968. {
  969. //make sure this is unique
  970. node_settings = node_settings.duplicate(true);
  971. //fill node settings for this node with default values
  972. List<ImportOption> iopts;
  973. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
  974. for (const ImportOption &E : iopts) {
  975. if (!node_settings.has(E.option.name)) {
  976. node_settings[E.option.name] = E.default_value;
  977. }
  978. }
  979. }
  980. if (Object::cast_to<AnimationPlayer>(p_node)) {
  981. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  982. List<StringName> anims;
  983. ap->get_animation_list(&anims);
  984. if (p_remove_immutable_tracks) {
  985. AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = {
  986. AnimationImportTracks(int(node_settings["import_tracks/position"])),
  987. AnimationImportTracks(int(node_settings["import_tracks/rotation"])),
  988. AnimationImportTracks(int(node_settings["import_tracks/scale"]))
  989. };
  990. HashMap<NodePath, bool> used_tracks[TRACK_CHANNEL_MAX];
  991. for (const StringName &name : anims) {
  992. Ref<Animation> anim = ap->get_animation(name);
  993. int track_count = anim->get_track_count();
  994. LocalVector<int> tracks_to_keep;
  995. for (int track_i = 0; track_i < track_count; track_i++) {
  996. tracks_to_keep.push_back(track_i);
  997. int track_channel_type = 0;
  998. switch (anim->track_get_type(track_i)) {
  999. case Animation::TYPE_POSITION_3D:
  1000. track_channel_type = TRACK_CHANNEL_POSITION;
  1001. break;
  1002. case Animation::TYPE_ROTATION_3D:
  1003. track_channel_type = TRACK_CHANNEL_ROTATION;
  1004. break;
  1005. case Animation::TYPE_SCALE_3D:
  1006. track_channel_type = TRACK_CHANNEL_SCALE;
  1007. break;
  1008. default:
  1009. continue;
  1010. }
  1011. AnimationImportTracks track_mode = import_tracks_mode[track_channel_type];
  1012. NodePath path = anim->track_get_path(track_i);
  1013. Node *n = p_root->get_node(path);
  1014. Node3D *n3d = Object::cast_to<Node3D>(n);
  1015. Skeleton3D *skel = Object::cast_to<Skeleton3D>(n);
  1016. bool keep_track = false;
  1017. Vector3 loc;
  1018. Quaternion rot;
  1019. Vector3 scale;
  1020. if (skel && path.get_subname_count() > 0) {
  1021. StringName bone = path.get_subname(0);
  1022. int bone_idx = skel->find_bone(bone);
  1023. if (bone_idx == -1) {
  1024. continue;
  1025. }
  1026. // Note that this is using get_bone_pose to update the bone pose cache.
  1027. Transform3D bone_rest = skel->get_bone_rest(bone_idx);
  1028. loc = bone_rest.origin / skel->get_motion_scale();
  1029. rot = bone_rest.basis.get_rotation_quaternion();
  1030. scale = bone_rest.basis.get_scale();
  1031. } else if (n3d) {
  1032. loc = n3d->get_position();
  1033. rot = n3d->get_transform().basis.get_rotation_quaternion();
  1034. scale = n3d->get_scale();
  1035. } else {
  1036. continue;
  1037. }
  1038. if (track_mode == ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  1039. if (used_tracks[track_channel_type].has(path)) {
  1040. if (used_tracks[track_channel_type][path]) {
  1041. continue;
  1042. }
  1043. } else {
  1044. used_tracks[track_channel_type].insert(path, false);
  1045. }
  1046. }
  1047. for (int key_i = 0; key_i < anim->track_get_key_count(track_i) && !keep_track; key_i++) {
  1048. switch (track_channel_type) {
  1049. case TRACK_CHANNEL_POSITION: {
  1050. Vector3 key_pos;
  1051. anim->position_track_get_key(track_i, key_i, &key_pos);
  1052. if (!key_pos.is_equal_approx(loc)) {
  1053. keep_track = true;
  1054. if (track_mode == ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  1055. used_tracks[track_channel_type][path] = true;
  1056. }
  1057. }
  1058. } break;
  1059. case TRACK_CHANNEL_ROTATION: {
  1060. Quaternion key_rot;
  1061. anim->rotation_track_get_key(track_i, key_i, &key_rot);
  1062. if (!key_rot.is_equal_approx(rot)) {
  1063. keep_track = true;
  1064. if (track_mode == ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  1065. used_tracks[track_channel_type][path] = true;
  1066. }
  1067. }
  1068. } break;
  1069. case TRACK_CHANNEL_SCALE: {
  1070. Vector3 key_scl;
  1071. anim->scale_track_get_key(track_i, key_i, &key_scl);
  1072. if (!key_scl.is_equal_approx(scale)) {
  1073. keep_track = true;
  1074. if (track_mode == ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  1075. used_tracks[track_channel_type][path] = true;
  1076. }
  1077. }
  1078. } break;
  1079. default:
  1080. break;
  1081. }
  1082. }
  1083. if (track_mode != ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL && !keep_track) {
  1084. tracks_to_keep.remove_at(tracks_to_keep.size() - 1);
  1085. }
  1086. }
  1087. for (int dst_track_i = 0; dst_track_i < (int)tracks_to_keep.size(); dst_track_i++) {
  1088. int src_track_i = tracks_to_keep[dst_track_i];
  1089. if (src_track_i != dst_track_i) {
  1090. anim->track_swap(src_track_i, dst_track_i);
  1091. }
  1092. }
  1093. for (int track_i = track_count - 1; track_i >= (int)tracks_to_keep.size(); track_i--) {
  1094. anim->remove_track(track_i);
  1095. }
  1096. }
  1097. for (const StringName &name : anims) {
  1098. Ref<Animation> anim = ap->get_animation(name);
  1099. int track_count = anim->get_track_count();
  1100. LocalVector<int> tracks_to_keep;
  1101. for (int track_i = 0; track_i < track_count; track_i++) {
  1102. tracks_to_keep.push_back(track_i);
  1103. int track_channel_type = 0;
  1104. switch (anim->track_get_type(track_i)) {
  1105. case Animation::TYPE_POSITION_3D:
  1106. track_channel_type = TRACK_CHANNEL_POSITION;
  1107. break;
  1108. case Animation::TYPE_ROTATION_3D:
  1109. track_channel_type = TRACK_CHANNEL_ROTATION;
  1110. break;
  1111. case Animation::TYPE_SCALE_3D:
  1112. track_channel_type = TRACK_CHANNEL_SCALE;
  1113. break;
  1114. default:
  1115. continue;
  1116. }
  1117. AnimationImportTracks track_mode = import_tracks_mode[track_channel_type];
  1118. if (track_mode == ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  1119. NodePath path = anim->track_get_path(track_i);
  1120. if (used_tracks[track_channel_type].has(path) && !used_tracks[track_channel_type][path]) {
  1121. tracks_to_keep.remove_at(tracks_to_keep.size() - 1);
  1122. }
  1123. }
  1124. }
  1125. for (int dst_track_i = 0; dst_track_i < (int)tracks_to_keep.size(); dst_track_i++) {
  1126. int src_track_i = tracks_to_keep[dst_track_i];
  1127. if (src_track_i != dst_track_i) {
  1128. anim->track_swap(src_track_i, dst_track_i);
  1129. }
  1130. }
  1131. for (int track_i = track_count - 1; track_i >= (int)tracks_to_keep.size(); track_i--) {
  1132. anim->remove_track(track_i);
  1133. }
  1134. }
  1135. }
  1136. bool use_optimizer = node_settings["optimizer/enabled"];
  1137. float anim_optimizer_linerr = node_settings["optimizer/max_velocity_error"];
  1138. float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"];
  1139. int anim_optimizer_preerr = node_settings["optimizer/max_precision_error"];
  1140. if (use_optimizer) {
  1141. _optimize_animations(ap, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_preerr);
  1142. }
  1143. bool use_compression = node_settings["compression/enabled"];
  1144. int anim_compression_page_size = node_settings["compression/page_size"];
  1145. if (use_compression) {
  1146. _compress_animations(ap, anim_compression_page_size);
  1147. }
  1148. for (const StringName &name : anims) {
  1149. Ref<Animation> anim = ap->get_animation(name);
  1150. Array animation_slices;
  1151. if (p_animation_data.has(name)) {
  1152. Dictionary anim_settings = p_animation_data[name];
  1153. {
  1154. int slice_count = anim_settings["slices/amount"];
  1155. for (int i = 0; i < slice_count; i++) {
  1156. String slice_name = anim_settings["slice_" + itos(i + 1) + "/name"];
  1157. int from_frame = anim_settings["slice_" + itos(i + 1) + "/start_frame"];
  1158. int end_frame = anim_settings["slice_" + itos(i + 1) + "/end_frame"];
  1159. Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)anim_settings["slice_" + itos(i + 1) + "/loop_mode"]);
  1160. bool save_to_file = anim_settings["slice_" + itos(i + 1) + "/save_to_file/enabled"];
  1161. String save_to_path = anim_settings["slice_" + itos(i + 1) + "/save_to_file/path"];
  1162. bool save_to_file_keep_custom = anim_settings["slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"];
  1163. animation_slices.push_back(slice_name);
  1164. animation_slices.push_back(from_frame / p_animation_fps);
  1165. animation_slices.push_back(end_frame / p_animation_fps);
  1166. animation_slices.push_back(loop_mode);
  1167. animation_slices.push_back(save_to_file);
  1168. animation_slices.push_back(save_to_path);
  1169. animation_slices.push_back(save_to_file_keep_custom);
  1170. }
  1171. if (animation_slices.size() > 0) {
  1172. _create_slices(ap, anim, animation_slices, true);
  1173. }
  1174. }
  1175. {
  1176. //fill with default values
  1177. List<ImportOption> iopts;
  1178. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts);
  1179. for (const ImportOption &F : iopts) {
  1180. if (!anim_settings.has(F.option.name)) {
  1181. anim_settings[F.option.name] = F.default_value;
  1182. }
  1183. }
  1184. }
  1185. anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"]));
  1186. bool save = anim_settings["save_to_file/enabled"];
  1187. String path = anim_settings["save_to_file/path"];
  1188. bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"];
  1189. Ref<Animation> saved_anim = _save_animation_to_file(anim, save, path, keep_custom);
  1190. if (saved_anim != anim) {
  1191. Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim));
  1192. al->add_animation(name, saved_anim); //replace
  1193. }
  1194. }
  1195. }
  1196. }
  1197. return p_node;
  1198. }
  1199. 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) {
  1200. // children first
  1201. for (int i = 0; i < p_node->get_child_count(); i++) {
  1202. 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);
  1203. if (!r) {
  1204. i--; //was erased
  1205. }
  1206. }
  1207. bool isroot = p_node == p_root;
  1208. String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node));
  1209. Dictionary node_settings;
  1210. if (p_node_data.has(import_id)) {
  1211. node_settings = p_node_data[import_id];
  1212. }
  1213. if (!isroot && (node_settings.has("import/skip_import") && bool(node_settings["import/skip_import"]))) {
  1214. p_node->set_owner(nullptr);
  1215. memdelete(p_node);
  1216. return nullptr;
  1217. }
  1218. {
  1219. //make sure this is unique
  1220. node_settings = node_settings.duplicate(true);
  1221. //fill node settings for this node with default values
  1222. List<ImportOption> iopts;
  1223. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1224. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, &iopts);
  1225. } else if (Object::cast_to<AnimationPlayer>(p_node)) {
  1226. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts);
  1227. } else if (Object::cast_to<Skeleton3D>(p_node)) {
  1228. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE, &iopts);
  1229. } else {
  1230. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_NODE, &iopts);
  1231. }
  1232. for (const ImportOption &E : iopts) {
  1233. if (!node_settings.has(E.option.name)) {
  1234. node_settings[E.option.name] = E.default_value;
  1235. }
  1236. }
  1237. }
  1238. {
  1239. ObjectID node_id = p_node->get_instance_id();
  1240. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1241. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  1242. if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
  1243. break;
  1244. }
  1245. }
  1246. }
  1247. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1248. ObjectID node_id = p_node->get_instance_id();
  1249. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1250. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  1251. if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
  1252. break;
  1253. }
  1254. }
  1255. }
  1256. if (Object::cast_to<Skeleton3D>(p_node)) {
  1257. Ref<Animation> rest_animation;
  1258. float rest_animation_timestamp = 0.0;
  1259. Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node);
  1260. if (skeleton != nullptr && int(node_settings.get("rest_pose/load_pose", 0)) != 0) {
  1261. String selected_animation_name = node_settings.get("rest_pose/selected_animation", String());
  1262. if (int(node_settings["rest_pose/load_pose"]) == 1) {
  1263. TypedArray<Node> children = p_root->find_children("*", "AnimationPlayer", true, false);
  1264. for (int node_i = 0; node_i < children.size(); node_i++) {
  1265. AnimationPlayer *anim_player = cast_to<AnimationPlayer>(children[node_i]);
  1266. ERR_CONTINUE(anim_player == nullptr);
  1267. List<StringName> anim_list;
  1268. anim_player->get_animation_list(&anim_list);
  1269. if (anim_list.size() == 1) {
  1270. selected_animation_name = anim_list.front()->get();
  1271. }
  1272. rest_animation = anim_player->get_animation(selected_animation_name);
  1273. if (rest_animation.is_valid()) {
  1274. break;
  1275. }
  1276. }
  1277. } else if (int(node_settings["rest_pose/load_pose"]) == 2) {
  1278. Object *external_object = node_settings.get("rest_pose/external_animation_library", Variant());
  1279. rest_animation = external_object;
  1280. if (rest_animation.is_null()) {
  1281. Ref<AnimationLibrary> library(external_object);
  1282. if (library.is_valid()) {
  1283. List<StringName> anim_list;
  1284. library->get_animation_list(&anim_list);
  1285. if (anim_list.size() == 1) {
  1286. selected_animation_name = String(anim_list.front()->get());
  1287. }
  1288. rest_animation = library->get_animation(selected_animation_name);
  1289. }
  1290. }
  1291. }
  1292. rest_animation_timestamp = double(node_settings.get("rest_pose/selected_timestamp", 0.0));
  1293. if (rest_animation.is_valid()) {
  1294. for (int track_i = 0; track_i < rest_animation->get_track_count(); track_i++) {
  1295. NodePath path = rest_animation->track_get_path(track_i);
  1296. StringName node_path = path.get_concatenated_names();
  1297. if (String(node_path).begins_with("%")) {
  1298. continue; // Unique node names are commonly used with retargeted animations, which we do not want to use.
  1299. }
  1300. StringName skeleton_bone = path.get_concatenated_subnames();
  1301. if (skeleton_bone == StringName()) {
  1302. continue;
  1303. }
  1304. int bone_idx = skeleton->find_bone(skeleton_bone);
  1305. if (bone_idx == -1) {
  1306. continue;
  1307. }
  1308. switch (rest_animation->track_get_type(track_i)) {
  1309. case Animation::TYPE_POSITION_3D: {
  1310. Vector3 bone_position = rest_animation->position_track_interpolate(track_i, rest_animation_timestamp);
  1311. skeleton->set_bone_rest(bone_idx, Transform3D(skeleton->get_bone_rest(bone_idx).basis, bone_position));
  1312. } break;
  1313. case Animation::TYPE_ROTATION_3D: {
  1314. Quaternion bone_rotation = rest_animation->rotation_track_interpolate(track_i, rest_animation_timestamp);
  1315. Transform3D current_rest = skeleton->get_bone_rest(bone_idx);
  1316. skeleton->set_bone_rest(bone_idx, Transform3D(Basis(bone_rotation).scaled(current_rest.basis.get_scale()), current_rest.origin));
  1317. } break;
  1318. default:
  1319. break;
  1320. }
  1321. }
  1322. }
  1323. }
  1324. ObjectID node_id = p_node->get_instance_id();
  1325. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1326. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  1327. if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
  1328. break;
  1329. }
  1330. }
  1331. }
  1332. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1333. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1334. Ref<ImporterMesh> m = mi->get_mesh();
  1335. if (m.is_valid()) {
  1336. if (!r_scanned_meshes.has(m)) {
  1337. for (int i = 0; i < m->get_surface_count(); i++) {
  1338. Ref<Material> mat = m->get_surface_material(i);
  1339. if (mat.is_valid()) {
  1340. String mat_id = mat->get_meta("import_id", mat->get_name());
  1341. if (!mat_id.is_empty() && p_material_data.has(mat_id)) {
  1342. Dictionary matdata = p_material_data[mat_id];
  1343. {
  1344. //fill node settings for this node with default values
  1345. List<ImportOption> iopts;
  1346. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MATERIAL, &iopts);
  1347. for (const ImportOption &E : iopts) {
  1348. if (!matdata.has(E.option.name)) {
  1349. matdata[E.option.name] = E.default_value;
  1350. }
  1351. }
  1352. }
  1353. for (int j = 0; j < post_importer_plugins.size(); j++) {
  1354. post_importer_plugins.write[j]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL, p_root, p_node, mat, matdata);
  1355. }
  1356. if (matdata.has("use_external/enabled") && bool(matdata["use_external/enabled"]) && matdata.has("use_external/path")) {
  1357. String path = matdata["use_external/path"];
  1358. Ref<Material> external_mat = ResourceLoader::load(path);
  1359. if (external_mat.is_null()) {
  1360. if (matdata.has("use_external/fallback_path")) {
  1361. String fallback_save_path = matdata["use_external/fallback_path"];
  1362. if (!fallback_save_path.is_empty()) {
  1363. external_mat = ResourceLoader::load(fallback_save_path);
  1364. if (external_mat.is_valid()) {
  1365. path = fallback_save_path;
  1366. }
  1367. }
  1368. }
  1369. }
  1370. if (external_mat.is_valid()) {
  1371. m->set_surface_material(i, external_mat);
  1372. if (!path.begins_with("uid://")) {
  1373. const ResourceUID::ID id = ResourceLoader::get_resource_uid(path);
  1374. if (id != ResourceUID::INVALID_ID) {
  1375. matdata["use_external/path"] = ResourceUID::get_singleton()->id_to_text(id);
  1376. }
  1377. }
  1378. matdata["use_external/fallback_path"] = external_mat->get_path();
  1379. }
  1380. }
  1381. }
  1382. }
  1383. }
  1384. r_scanned_meshes.insert(m);
  1385. }
  1386. if (node_settings.has("generate/physics")) {
  1387. int mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_DISABLED;
  1388. const bool generate_collider = node_settings["generate/physics"];
  1389. if (generate_collider) {
  1390. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_MESH_AND_STATIC_COLLIDER;
  1391. if (node_settings.has("physics/body_type")) {
  1392. const BodyType body_type = (BodyType)node_settings["physics/body_type"].operator int();
  1393. switch (body_type) {
  1394. case BODY_TYPE_STATIC:
  1395. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_MESH_AND_STATIC_COLLIDER;
  1396. break;
  1397. case BODY_TYPE_DYNAMIC:
  1398. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_RIGID_BODY_AND_MESH;
  1399. break;
  1400. case BODY_TYPE_AREA:
  1401. mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_AREA_ONLY;
  1402. break;
  1403. }
  1404. }
  1405. }
  1406. if (mesh_physics_mode != MeshPhysicsMode::MESH_PHYSICS_DISABLED) {
  1407. Vector<Ref<Shape3D>> shapes;
  1408. if (collision_map.has(m)) {
  1409. shapes = collision_map[m];
  1410. } else {
  1411. shapes = get_collision_shapes(
  1412. m,
  1413. node_settings,
  1414. p_applied_root_scale);
  1415. }
  1416. if (shapes.size()) {
  1417. CollisionObject3D *base = nullptr;
  1418. switch (mesh_physics_mode) {
  1419. case MESH_PHYSICS_MESH_AND_STATIC_COLLIDER: {
  1420. StaticBody3D *col = memnew(StaticBody3D);
  1421. p_node->add_child(col, true);
  1422. col->set_owner(p_node->get_owner());
  1423. col->set_transform(get_collision_shapes_transform(node_settings));
  1424. col->set_position(p_applied_root_scale * col->get_position());
  1425. const Ref<PhysicsMaterial> &pmo = node_settings["physics/physics_material_override"];
  1426. if (pmo.is_valid()) {
  1427. col->set_physics_material_override(pmo);
  1428. }
  1429. base = col;
  1430. } break;
  1431. case MESH_PHYSICS_RIGID_BODY_AND_MESH: {
  1432. RigidBody3D *rigid_body = memnew(RigidBody3D);
  1433. rigid_body->set_name(p_node->get_name());
  1434. _copy_meta(p_node, rigid_body);
  1435. p_node->replace_by(rigid_body);
  1436. rigid_body->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
  1437. rigid_body->set_position(p_applied_root_scale * rigid_body->get_position());
  1438. p_node = rigid_body;
  1439. mi->set_transform(Transform3D());
  1440. rigid_body->add_child(mi, true);
  1441. mi->set_owner(rigid_body->get_owner());
  1442. const Ref<PhysicsMaterial> &pmo = node_settings["physics/physics_material_override"];
  1443. if (pmo.is_valid()) {
  1444. rigid_body->set_physics_material_override(pmo);
  1445. }
  1446. base = rigid_body;
  1447. } break;
  1448. case MESH_PHYSICS_STATIC_COLLIDER_ONLY: {
  1449. StaticBody3D *col = memnew(StaticBody3D);
  1450. col->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
  1451. col->set_position(p_applied_root_scale * col->get_position());
  1452. col->set_name(p_node->get_name());
  1453. _copy_meta(p_node, col);
  1454. p_node->replace_by(col);
  1455. p_node->set_owner(nullptr);
  1456. memdelete(p_node);
  1457. p_node = col;
  1458. const Ref<PhysicsMaterial> &pmo = node_settings["physics/physics_material_override"];
  1459. if (pmo.is_valid()) {
  1460. col->set_physics_material_override(pmo);
  1461. }
  1462. base = col;
  1463. } break;
  1464. case MESH_PHYSICS_AREA_ONLY: {
  1465. Area3D *area = memnew(Area3D);
  1466. area->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
  1467. area->set_position(p_applied_root_scale * area->get_position());
  1468. area->set_name(p_node->get_name());
  1469. _copy_meta(p_node, area);
  1470. p_node->replace_by(area);
  1471. p_node->set_owner(nullptr);
  1472. memdelete(p_node);
  1473. p_node = area;
  1474. base = area;
  1475. } break;
  1476. }
  1477. base->set_collision_layer(node_settings["physics/layer"]);
  1478. base->set_collision_mask(node_settings["physics/mask"]);
  1479. for (const Ref<Shape3D> &E : shapes) {
  1480. CollisionShape3D *cshape = memnew(CollisionShape3D);
  1481. cshape->set_shape(E);
  1482. base->add_child(cshape, true);
  1483. cshape->set_owner(base->get_owner());
  1484. }
  1485. }
  1486. }
  1487. }
  1488. }
  1489. }
  1490. //navmesh (node may have changed type above)
  1491. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1492. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1493. Ref<ImporterMesh> m = mi->get_mesh();
  1494. if (m.is_valid()) {
  1495. if (node_settings.has("generate/navmesh")) {
  1496. int navmesh_mode = node_settings["generate/navmesh"];
  1497. if (navmesh_mode != NAVMESH_DISABLED) {
  1498. NavigationRegion3D *nmi = memnew(NavigationRegion3D);
  1499. Ref<NavigationMesh> nmesh = m->create_navigation_mesh();
  1500. nmi->set_navigation_mesh(nmesh);
  1501. if (navmesh_mode == NAVMESH_NAVMESH_ONLY) {
  1502. nmi->set_transform(mi->get_transform());
  1503. _copy_meta(p_node, nmi);
  1504. p_node->replace_by(nmi);
  1505. p_node->set_owner(nullptr);
  1506. memdelete(p_node);
  1507. p_node = nmi;
  1508. } else {
  1509. mi->add_child(nmi, true);
  1510. nmi->set_owner(mi->get_owner());
  1511. }
  1512. }
  1513. }
  1514. }
  1515. }
  1516. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1517. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1518. Ref<ImporterMesh> m = mi->get_mesh();
  1519. if (m.is_valid()) {
  1520. if (node_settings.has("generate/occluder")) {
  1521. int occluder_mode = node_settings["generate/occluder"];
  1522. if (occluder_mode != OCCLUDER_DISABLED) {
  1523. float simplification_dist = 0.0f;
  1524. if (node_settings.has("occluder/simplification_distance")) {
  1525. simplification_dist = node_settings["occluder/simplification_distance"];
  1526. }
  1527. OccluderInstance3D::bake_single_node(mi, simplification_dist, r_occluder_arrays.first, r_occluder_arrays.second);
  1528. if (occluder_mode == OCCLUDER_OCCLUDER_ONLY) {
  1529. p_node->set_owner(nullptr);
  1530. memdelete(p_node);
  1531. p_node = nullptr;
  1532. }
  1533. }
  1534. }
  1535. }
  1536. }
  1537. if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
  1538. ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
  1539. if (node_settings.has("mesh_instance/layers")) {
  1540. mi->set_layer_mask(node_settings["mesh_instance/layers"]);
  1541. }
  1542. if (node_settings.has("mesh_instance/visibility_range_begin")) {
  1543. mi->set_visibility_range_begin(node_settings["mesh_instance/visibility_range_begin"]);
  1544. }
  1545. if (node_settings.has("mesh_instance/visibility_range_begin_margin")) {
  1546. mi->set_visibility_range_begin_margin(node_settings["mesh_instance/visibility_range_begin_margin"]);
  1547. }
  1548. if (node_settings.has("mesh_instance/visibility_range_end")) {
  1549. mi->set_visibility_range_end(node_settings["mesh_instance/visibility_range_end"]);
  1550. }
  1551. if (node_settings.has("mesh_instance/visibility_range_end_margin")) {
  1552. mi->set_visibility_range_end_margin(node_settings["mesh_instance/visibility_range_end_margin"]);
  1553. }
  1554. if (node_settings.has("mesh_instance/visibility_range_fade_mode")) {
  1555. const GeometryInstance3D::VisibilityRangeFadeMode range_fade_mode = (GeometryInstance3D::VisibilityRangeFadeMode)node_settings["mesh_instance/visibility_range_fade_mode"].operator int();
  1556. mi->set_visibility_range_fade_mode(range_fade_mode);
  1557. }
  1558. if (node_settings.has("mesh_instance/cast_shadow")) {
  1559. const GeometryInstance3D::ShadowCastingSetting cast_shadows = (GeometryInstance3D::ShadowCastingSetting)node_settings["mesh_instance/cast_shadow"].operator int();
  1560. mi->set_cast_shadows_setting(cast_shadows);
  1561. }
  1562. }
  1563. if (Object::cast_to<AnimationPlayer>(p_node)) {
  1564. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  1565. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1566. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, Ref<Resource>(), node_settings);
  1567. }
  1568. if (post_importer_plugins.size()) {
  1569. List<StringName> anims;
  1570. ap->get_animation_list(&anims);
  1571. for (const StringName &name : anims) {
  1572. if (p_animation_data.has(name)) {
  1573. Ref<Animation> anim = ap->get_animation(name);
  1574. Dictionary anim_settings = p_animation_data[name];
  1575. {
  1576. //fill with default values
  1577. List<ImportOption> iopts;
  1578. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts);
  1579. for (const ImportOption &F : iopts) {
  1580. if (!anim_settings.has(F.option.name)) {
  1581. anim_settings[F.option.name] = F.default_value;
  1582. }
  1583. }
  1584. }
  1585. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1586. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION, p_root, p_node, anim, anim_settings);
  1587. }
  1588. }
  1589. }
  1590. }
  1591. }
  1592. return p_node;
  1593. }
  1594. Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, const String &p_save_to_path, bool p_keep_custom_tracks) {
  1595. String res_path = ResourceUID::ensure_path(p_save_to_path);
  1596. if (!p_save_to_file || !res_path.is_resource_file()) {
  1597. return anim;
  1598. }
  1599. if (FileAccess::exists(res_path) && p_keep_custom_tracks) {
  1600. // Copy custom animation tracks from previously imported files.
  1601. Ref<Animation> old_anim = ResourceLoader::load(res_path, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE);
  1602. if (old_anim.is_valid()) {
  1603. for (int i = 0; i < old_anim->get_track_count(); i++) {
  1604. if (!old_anim->track_is_imported(i)) {
  1605. old_anim->copy_track(i, anim);
  1606. }
  1607. }
  1608. anim->set_loop_mode(old_anim->get_loop_mode());
  1609. }
  1610. }
  1611. if (ResourceCache::has(res_path)) {
  1612. Ref<Animation> old_anim = ResourceCache::get_ref(res_path);
  1613. if (old_anim.is_valid()) {
  1614. old_anim->copy_from(anim);
  1615. anim = old_anim;
  1616. }
  1617. }
  1618. anim->set_path(res_path, true); // Set path to save externally.
  1619. Error err = ResourceSaver::save(anim, res_path, ResourceSaver::FLAG_CHANGE_PATH);
  1620. ERR_FAIL_COND_V_MSG(err != OK, anim, "Saving of animation failed: " + res_path);
  1621. if (p_save_to_path.begins_with("uid://")) {
  1622. // slow
  1623. ResourceSaver::set_uid(res_path, ResourceUID::get_singleton()->text_to_id(p_save_to_path));
  1624. }
  1625. return anim;
  1626. }
  1627. void ResourceImporterScene::_create_slices(AnimationPlayer *ap, Ref<Animation> anim, const Array &p_slices, bool p_bake_all) {
  1628. Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim));
  1629. for (int i = 0; i < p_slices.size(); i += 7) {
  1630. String name = p_slices[i];
  1631. float from = p_slices[i + 1];
  1632. float to = p_slices[i + 2];
  1633. Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)p_slices[i + 3]);
  1634. bool save_to_file = p_slices[i + 4];
  1635. String save_to_path = p_slices[i + 5];
  1636. bool keep_current = p_slices[i + 6];
  1637. if (from >= to) {
  1638. continue;
  1639. }
  1640. Ref<Animation> new_anim = memnew(Animation);
  1641. for (int j = 0; j < anim->get_track_count(); j++) {
  1642. List<float> keys;
  1643. int kc = anim->track_get_key_count(j);
  1644. int dtrack = -1;
  1645. for (int k = 0; k < kc; k++) {
  1646. float kt = anim->track_get_key_time(j, k);
  1647. if (kt >= from && kt < to) {
  1648. //found a key within range, so create track
  1649. if (dtrack == -1) {
  1650. new_anim->add_track(anim->track_get_type(j));
  1651. dtrack = new_anim->get_track_count() - 1;
  1652. new_anim->track_set_path(dtrack, anim->track_get_path(j));
  1653. new_anim->track_set_imported(dtrack, true);
  1654. if (kt > (from + 0.01) && k > 0) {
  1655. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1656. Vector3 p;
  1657. anim->try_position_track_interpolate(j, from, &p);
  1658. new_anim->position_track_insert_key(dtrack, 0, p);
  1659. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1660. Quaternion r;
  1661. anim->try_rotation_track_interpolate(j, from, &r);
  1662. new_anim->rotation_track_insert_key(dtrack, 0, r);
  1663. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1664. Vector3 s;
  1665. anim->try_scale_track_interpolate(j, from, &s);
  1666. new_anim->scale_track_insert_key(dtrack, 0, s);
  1667. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1668. Variant var = anim->value_track_interpolate(j, from);
  1669. new_anim->track_insert_key(dtrack, 0, var);
  1670. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1671. float interp;
  1672. anim->try_blend_shape_track_interpolate(j, from, &interp);
  1673. new_anim->blend_shape_track_insert_key(dtrack, 0, interp);
  1674. }
  1675. }
  1676. }
  1677. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1678. Vector3 p;
  1679. anim->position_track_get_key(j, k, &p);
  1680. new_anim->position_track_insert_key(dtrack, kt - from, p);
  1681. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1682. Quaternion r;
  1683. anim->rotation_track_get_key(j, k, &r);
  1684. new_anim->rotation_track_insert_key(dtrack, kt - from, r);
  1685. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1686. Vector3 s;
  1687. anim->scale_track_get_key(j, k, &s);
  1688. new_anim->scale_track_insert_key(dtrack, kt - from, s);
  1689. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1690. Variant var = anim->track_get_key_value(j, k);
  1691. new_anim->track_insert_key(dtrack, kt - from, var);
  1692. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1693. float interp;
  1694. anim->blend_shape_track_get_key(j, k, &interp);
  1695. new_anim->blend_shape_track_insert_key(dtrack, kt - from, interp);
  1696. }
  1697. }
  1698. if (dtrack != -1 && kt >= to) {
  1699. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1700. Vector3 p;
  1701. anim->try_position_track_interpolate(j, to, &p);
  1702. new_anim->position_track_insert_key(dtrack, to - from, p);
  1703. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1704. Quaternion r;
  1705. anim->try_rotation_track_interpolate(j, to, &r);
  1706. new_anim->rotation_track_insert_key(dtrack, to - from, r);
  1707. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1708. Vector3 s;
  1709. anim->try_scale_track_interpolate(j, to, &s);
  1710. new_anim->scale_track_insert_key(dtrack, to - from, s);
  1711. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1712. Variant var = anim->value_track_interpolate(j, to);
  1713. new_anim->track_insert_key(dtrack, to - from, var);
  1714. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1715. float interp;
  1716. anim->try_blend_shape_track_interpolate(j, to, &interp);
  1717. new_anim->blend_shape_track_insert_key(dtrack, to - from, interp);
  1718. }
  1719. }
  1720. }
  1721. if (dtrack == -1 && p_bake_all) {
  1722. new_anim->add_track(anim->track_get_type(j));
  1723. dtrack = new_anim->get_track_count() - 1;
  1724. new_anim->track_set_path(dtrack, anim->track_get_path(j));
  1725. new_anim->track_set_imported(dtrack, true);
  1726. if (anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
  1727. Vector3 p;
  1728. anim->try_position_track_interpolate(j, from, &p);
  1729. new_anim->position_track_insert_key(dtrack, 0, p);
  1730. anim->try_position_track_interpolate(j, to, &p);
  1731. new_anim->position_track_insert_key(dtrack, to - from, p);
  1732. } else if (anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
  1733. Quaternion r;
  1734. anim->try_rotation_track_interpolate(j, from, &r);
  1735. new_anim->rotation_track_insert_key(dtrack, 0, r);
  1736. anim->try_rotation_track_interpolate(j, to, &r);
  1737. new_anim->rotation_track_insert_key(dtrack, to - from, r);
  1738. } else if (anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
  1739. Vector3 s;
  1740. anim->try_scale_track_interpolate(j, from, &s);
  1741. new_anim->scale_track_insert_key(dtrack, 0, s);
  1742. anim->try_scale_track_interpolate(j, to, &s);
  1743. new_anim->scale_track_insert_key(dtrack, to - from, s);
  1744. } else if (anim->track_get_type(j) == Animation::TYPE_VALUE) {
  1745. Variant var = anim->value_track_interpolate(j, from);
  1746. new_anim->track_insert_key(dtrack, 0, var);
  1747. Variant to_var = anim->value_track_interpolate(j, to);
  1748. new_anim->track_insert_key(dtrack, to - from, to_var);
  1749. } else if (anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
  1750. float interp;
  1751. anim->try_blend_shape_track_interpolate(j, from, &interp);
  1752. new_anim->blend_shape_track_insert_key(dtrack, 0, interp);
  1753. anim->try_blend_shape_track_interpolate(j, to, &interp);
  1754. new_anim->blend_shape_track_insert_key(dtrack, to - from, interp);
  1755. }
  1756. }
  1757. }
  1758. new_anim->set_loop_mode(loop_mode);
  1759. new_anim->set_length(to - from);
  1760. new_anim->set_step(anim->get_step());
  1761. al->add_animation(name, new_anim);
  1762. Ref<Animation> saved_anim = _save_animation_to_file(new_anim, save_to_file, save_to_path, keep_current);
  1763. if (saved_anim != new_anim) {
  1764. al->add_animation(name, saved_anim);
  1765. }
  1766. }
  1767. al->remove_animation(ap->find_animation(anim)); // Remove original animation (no longer needed).
  1768. }
  1769. void ResourceImporterScene::_optimize_animations(AnimationPlayer *anim, float p_max_vel_error, float p_max_ang_error, int p_prc_error) {
  1770. List<StringName> anim_names;
  1771. anim->get_animation_list(&anim_names);
  1772. for (const StringName &E : anim_names) {
  1773. Ref<Animation> a = anim->get_animation(E);
  1774. a->optimize(p_max_vel_error, p_max_ang_error, p_prc_error);
  1775. }
  1776. }
  1777. void ResourceImporterScene::_compress_animations(AnimationPlayer *anim, int p_page_size_kb) {
  1778. List<StringName> anim_names;
  1779. anim->get_animation_list(&anim_names);
  1780. for (const StringName &E : anim_names) {
  1781. Ref<Animation> a = anim->get_animation(E);
  1782. a->compress(p_page_size_kb * 1024);
  1783. }
  1784. }
  1785. void ResourceImporterScene::get_internal_import_options(InternalImportCategory p_category, List<ImportOption> *r_options) const {
  1786. switch (p_category) {
  1787. case INTERNAL_IMPORT_CATEGORY_NODE: {
  1788. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1789. } break;
  1790. case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
  1791. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1792. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate/physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1793. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/navmesh", PROPERTY_HINT_ENUM, "Disabled,Mesh + NavMesh,NavMesh Only"), 0));
  1794. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/body_type", PROPERTY_HINT_ENUM, "Static,Dynamic,Area"), 0));
  1795. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/shape_type", PROPERTY_HINT_ENUM, "Decompose Convex,Simple Convex,Trimesh,Box,Sphere,Cylinder,Capsule,Automatic", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 7));
  1796. r_options->push_back(ImportOption(PropertyInfo(Variant::OBJECT, "physics/physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), Variant()));
  1797. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), 1));
  1798. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), 1));
  1799. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mesh_instance/layers", PROPERTY_HINT_LAYERS_3D_RENDER), 1));
  1800. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "mesh_instance/visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), 0.0f));
  1801. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "mesh_instance/visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), 0.0f));
  1802. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "mesh_instance/visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), 0.0f));
  1803. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "mesh_instance/visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), 0.0f));
  1804. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mesh_instance/visibility_range_fade_mode", PROPERTY_HINT_ENUM, "Disabled,Self,Dependencies"), GeometryInstance3D::VISIBILITY_RANGE_FADE_DISABLED));
  1805. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mesh_instance/cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), GeometryInstance3D::SHADOW_CASTING_SETTING_ON));
  1806. // Decomposition
  1807. Ref<MeshConvexDecompositionSettings> decomposition_default = Ref<MeshConvexDecompositionSettings>();
  1808. decomposition_default.instantiate();
  1809. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/advanced", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1810. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/precision", PROPERTY_HINT_RANGE, "1,10,1"), 5));
  1811. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/max_concavity", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT), decomposition_default->get_max_concavity()));
  1812. 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), decomposition_default->get_symmetry_planes_clipping_bias()));
  1813. 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), decomposition_default->get_revolution_axes_clipping_bias()));
  1814. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/min_volume_per_convex_hull", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), decomposition_default->get_min_volume_per_convex_hull()));
  1815. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/resolution", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), decomposition_default->get_resolution()));
  1816. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_num_vertices_per_convex_hull", PROPERTY_HINT_RANGE, "5,512,1", PROPERTY_USAGE_DEFAULT), decomposition_default->get_max_num_vertices_per_convex_hull()));
  1817. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT), decomposition_default->get_plane_downsampling()));
  1818. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/convexhull_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT), decomposition_default->get_convex_hull_downsampling()));
  1819. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/normalize_mesh", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), decomposition_default->get_normalize_mesh()));
  1820. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron", PROPERTY_USAGE_DEFAULT), static_cast<int>(decomposition_default->get_mode())));
  1821. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/convexhull_approximation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), decomposition_default->get_convex_hull_approximation()));
  1822. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_convex_hulls", PROPERTY_HINT_RANGE, "1,100,1", PROPERTY_USAGE_DEFAULT), decomposition_default->get_max_convex_hulls()));
  1823. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/project_hull_vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), decomposition_default->get_project_hull_vertices()));
  1824. // Primitives: Box, Sphere, Cylinder, Capsule.
  1825. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), Vector3(2.0, 2.0, 2.0)));
  1826. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/height", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), 1.0));
  1827. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/radius", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), 1.0));
  1828. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), Vector3()));
  1829. r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT), Vector3()));
  1830. 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));
  1831. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "occluder/simplification_distance", PROPERTY_HINT_RANGE, "0.0,2.0,0.01", PROPERTY_USAGE_DEFAULT), 0.1f));
  1832. } break;
  1833. case INTERNAL_IMPORT_CATEGORY_MESH: {
  1834. 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));
  1835. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), ""));
  1836. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
  1837. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/shadow_meshes", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
  1838. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lightmap_uv", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
  1839. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lods", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
  1840. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_merge_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 60.0f));
  1841. } break;
  1842. case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
  1843. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "use_external/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1844. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "use_external/path", PROPERTY_HINT_FILE, "*.material,*.res,*.tres"), ""));
  1845. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "use_external/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
  1846. } break;
  1847. case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
  1848. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "settings/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
  1849. 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));
  1850. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.anim,*.tres"), ""));
  1851. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
  1852. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/keep_custom_tracks"), ""));
  1853. 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));
  1854. for (int i = 0; i < 256; i++) {
  1855. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/name"), ""));
  1856. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/start_frame"), 0));
  1857. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/end_frame"), 0));
  1858. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
  1859. 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));
  1860. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.anim,*.tres"), ""));
  1861. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
  1862. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false));
  1863. }
  1864. } break;
  1865. case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
  1866. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1867. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
  1868. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_velocity_error", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.01));
  1869. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_angular_error", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.01));
  1870. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "optimizer/max_precision_error", PROPERTY_HINT_NONE, "1,6,1"), 3));
  1871. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compression/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1872. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compression/page_size", PROPERTY_HINT_RANGE, "4,512,1,suffix:kb"), 8));
  1873. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/position", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
  1874. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/rotation", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
  1875. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/scale", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
  1876. } break;
  1877. case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
  1878. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
  1879. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rest_pose/load_pose", PROPERTY_HINT_ENUM, "Default Pose,Use AnimationPlayer,Load External Animation", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
  1880. r_options->push_back(ImportOption(PropertyInfo(Variant::OBJECT, "rest_pose/external_animation_library", PROPERTY_HINT_RESOURCE_TYPE, "Animation,AnimationLibrary", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Variant()));
  1881. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "rest_pose/selected_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), ""));
  1882. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "rest_pose/selected_timestamp", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:s", PROPERTY_USAGE_DEFAULT), 0.0f));
  1883. String mismatched_or_empty_profile_warning = String(
  1884. "The external rest animation is missing some bones. "
  1885. "Consider disabling Remove Immutable Tracks on the other file."); // TODO: translate.
  1886. r_options->push_back(ImportOption(
  1887. PropertyInfo(
  1888. Variant::STRING, U"rest_pose/\u26A0_validation_warning/mismatched_or_empty_profile",
  1889. PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY),
  1890. Variant(mismatched_or_empty_profile_warning)));
  1891. String profile_must_not_be_retargeted_warning = String(
  1892. "This external rest animation appears to have been imported with a BoneMap. "
  1893. "Disable the bone map when exporting a rest animation from the reference model."); // TODO: translate.
  1894. r_options->push_back(ImportOption(
  1895. PropertyInfo(
  1896. Variant::STRING, U"rest_pose/\u26A0_validation_warning/profile_must_not_be_retargeted",
  1897. PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY),
  1898. Variant(profile_must_not_be_retargeted_warning)));
  1899. String no_animation_warning = String(
  1900. "Select an animation: Find a FBX or glTF in a compatible rest pose "
  1901. "and export a compatible animation from its import settings."); // TODO: translate.
  1902. r_options->push_back(ImportOption(
  1903. PropertyInfo(
  1904. Variant::STRING, U"rest_pose//no_animation_chosen",
  1905. PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY),
  1906. Variant(no_animation_warning)));
  1907. 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()));
  1908. } break;
  1909. default: {
  1910. }
  1911. }
  1912. for (int i = 0; i < post_importer_plugins.size(); i++) {
  1913. post_importer_plugins.write[i]->get_internal_import_options(EditorScenePostImportPlugin::InternalImportCategory(p_category), r_options);
  1914. }
  1915. }
  1916. bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  1917. if (p_options.has("import/skip_import") && p_option != "import/skip_import" && bool(p_options["import/skip_import"])) {
  1918. return false; //if skip import
  1919. }
  1920. switch (p_category) {
  1921. case INTERNAL_IMPORT_CATEGORY_NODE: {
  1922. } break;
  1923. case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
  1924. const bool generate_physics =
  1925. p_options.has("generate/physics") &&
  1926. p_options["generate/physics"].operator bool();
  1927. if (p_option.contains("physics/")) {
  1928. // Show if need to generate collisions.
  1929. return generate_physics;
  1930. }
  1931. if (p_option.contains("decomposition/")) {
  1932. // Show if need to generate collisions.
  1933. if (generate_physics &&
  1934. // Show if convex is enabled.
  1935. p_options["physics/shape_type"] == Variant(SHAPE_TYPE_DECOMPOSE_CONVEX)) {
  1936. if (p_option == "decomposition/advanced") {
  1937. return true;
  1938. }
  1939. const bool decomposition_advanced =
  1940. p_options.has("decomposition/advanced") &&
  1941. p_options["decomposition/advanced"].operator bool();
  1942. if (p_option == "decomposition/precision") {
  1943. return !decomposition_advanced;
  1944. } else {
  1945. return decomposition_advanced;
  1946. }
  1947. }
  1948. return false;
  1949. }
  1950. if (p_option == "primitive/position" || p_option == "primitive/rotation") {
  1951. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1952. return generate_physics &&
  1953. physics_shape >= SHAPE_TYPE_BOX;
  1954. }
  1955. if (p_option == "primitive/size") {
  1956. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1957. return generate_physics &&
  1958. physics_shape == SHAPE_TYPE_BOX;
  1959. }
  1960. if (p_option == "primitive/radius") {
  1961. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1962. return generate_physics &&
  1963. (physics_shape == SHAPE_TYPE_SPHERE ||
  1964. physics_shape == SHAPE_TYPE_CYLINDER ||
  1965. physics_shape == SHAPE_TYPE_CAPSULE);
  1966. }
  1967. if (p_option == "primitive/height") {
  1968. const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
  1969. return generate_physics &&
  1970. (physics_shape == SHAPE_TYPE_CYLINDER ||
  1971. physics_shape == SHAPE_TYPE_CAPSULE);
  1972. }
  1973. if (p_option == "occluder/simplification_distance") {
  1974. // Show only if occluder generation is enabled
  1975. return p_options.has("generate/occluder") && p_options["generate/occluder"].operator signed int() != OCCLUDER_DISABLED;
  1976. }
  1977. } break;
  1978. case INTERNAL_IMPORT_CATEGORY_MESH: {
  1979. if (p_option == "save_to_file/path") {
  1980. return p_options["save_to_file/enabled"];
  1981. }
  1982. } break;
  1983. case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
  1984. if (p_option == "use_external/path") {
  1985. return p_options["use_external/enabled"];
  1986. }
  1987. } break;
  1988. case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
  1989. if (p_option == "save_to_file/path" || p_option == "save_to_file/keep_custom_tracks") {
  1990. return p_options["save_to_file/enabled"];
  1991. }
  1992. if (p_option.begins_with("slice_")) {
  1993. int max_slice = p_options["slices/amount"];
  1994. int slice = p_option.get_slicec('_', 1).to_int() - 1;
  1995. if (slice >= max_slice) {
  1996. return false;
  1997. }
  1998. }
  1999. } break;
  2000. case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
  2001. if (p_option.begins_with("optimizer/") && p_option != "optimizer/enabled" && !bool(p_options["optimizer/enabled"])) {
  2002. return false;
  2003. }
  2004. if (p_option.begins_with("compression/") && p_option != "compression/enabled" && !bool(p_options["compression/enabled"])) {
  2005. return false;
  2006. }
  2007. } break;
  2008. case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
  2009. const bool use_retarget = Object::cast_to<BoneMap>(p_options["retarget/bone_map"].get_validated_object()) != nullptr;
  2010. if (!use_retarget && p_option != "retarget/bone_map" && p_option.begins_with("retarget/")) {
  2011. return false;
  2012. }
  2013. int rest_warning = 0;
  2014. if (p_option.begins_with("rest_pose/")) {
  2015. if (!p_options.has("rest_pose/load_pose") || int(p_options["rest_pose/load_pose"]) == 0) {
  2016. if (p_option != "rest_pose/load_pose") {
  2017. return false;
  2018. }
  2019. } else if (int(p_options["rest_pose/load_pose"]) == 1) {
  2020. if (p_option == "rest_pose/external_animation_library") {
  2021. return false;
  2022. }
  2023. } else if (int(p_options["rest_pose/load_pose"]) == 2) {
  2024. Object *res = p_options["rest_pose/external_animation_library"];
  2025. Ref<Animation> anim(res);
  2026. if (anim.is_valid() && p_option == "rest_pose/selected_animation") {
  2027. return false;
  2028. }
  2029. Ref<AnimationLibrary> library(res);
  2030. String selected_animation_name = p_options["rest_pose/selected_animation"];
  2031. if (library.is_valid()) {
  2032. List<StringName> anim_list;
  2033. library->get_animation_list(&anim_list);
  2034. if (anim_list.size() == 1) {
  2035. selected_animation_name = String(anim_list.front()->get());
  2036. }
  2037. if (library->has_animation(selected_animation_name)) {
  2038. anim = library->get_animation(selected_animation_name);
  2039. }
  2040. }
  2041. int found_bone_count = 0;
  2042. Ref<BoneMap> bone_map;
  2043. Ref<SkeletonProfile> prof;
  2044. if (p_options.has("retarget/bone_map")) {
  2045. bone_map = p_options["retarget/bone_map"];
  2046. }
  2047. if (bone_map.is_valid()) {
  2048. prof = bone_map->get_profile();
  2049. }
  2050. if (anim.is_valid()) {
  2051. HashSet<StringName> target_bones;
  2052. if (bone_map.is_valid() && prof.is_valid()) {
  2053. for (int target_i = 0; target_i < prof->get_bone_size(); target_i++) {
  2054. StringName skeleton_bone_name = bone_map->get_skeleton_bone_name(prof->get_bone_name(target_i));
  2055. if (skeleton_bone_name) {
  2056. target_bones.insert(skeleton_bone_name);
  2057. }
  2058. }
  2059. }
  2060. for (int track_i = 0; track_i < anim->get_track_count(); track_i++) {
  2061. if (anim->track_get_type(track_i) != Animation::TYPE_POSITION_3D && anim->track_get_type(track_i) != Animation::TYPE_ROTATION_3D) {
  2062. continue;
  2063. }
  2064. NodePath path = anim->track_get_path(track_i);
  2065. StringName node_path = path.get_concatenated_names();
  2066. StringName skeleton_bone = path.get_concatenated_subnames();
  2067. if (skeleton_bone) {
  2068. if (String(node_path).begins_with("%")) {
  2069. rest_warning = 1;
  2070. }
  2071. if (target_bones.has(skeleton_bone)) {
  2072. target_bones.erase(skeleton_bone);
  2073. }
  2074. found_bone_count++;
  2075. }
  2076. }
  2077. if ((found_bone_count < 15 || !target_bones.is_empty()) && rest_warning != 1) {
  2078. rest_warning = 2; // heuristic: animation targeted too few bones.
  2079. }
  2080. } else {
  2081. rest_warning = 3;
  2082. }
  2083. }
  2084. if (p_option.begins_with("rest_pose/") && p_option.ends_with("profile_must_not_be_retargeted")) {
  2085. return rest_warning == 1;
  2086. }
  2087. if (p_option.begins_with("rest_pose/") && p_option.ends_with("mismatched_or_empty_profile")) {
  2088. return rest_warning == 2;
  2089. }
  2090. if (p_option.begins_with("rest_pose/") && p_option.ends_with("no_animation_chosen")) {
  2091. return rest_warning == 3;
  2092. }
  2093. }
  2094. } break;
  2095. default: {
  2096. }
  2097. }
  2098. // TODO: If there are more than 2 or equal get_internal_option_visibility method, visibility state is broken.
  2099. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2100. Variant ret = post_importer_plugins.write[i]->get_internal_option_visibility(EditorScenePostImportPlugin::InternalImportCategory(p_category), _scene_import_type, p_option, p_options);
  2101. if (ret.get_type() == Variant::BOOL) {
  2102. return ret;
  2103. }
  2104. }
  2105. return true;
  2106. }
  2107. bool ResourceImporterScene::get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
  2108. switch (p_category) {
  2109. case INTERNAL_IMPORT_CATEGORY_NODE: {
  2110. } break;
  2111. case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
  2112. if (
  2113. p_option == "generate/physics" ||
  2114. p_option == "physics/shape_type" ||
  2115. p_option.contains("decomposition/") ||
  2116. p_option.contains("primitive/")) {
  2117. return true;
  2118. }
  2119. } break;
  2120. case INTERNAL_IMPORT_CATEGORY_MESH: {
  2121. } break;
  2122. case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
  2123. } break;
  2124. case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
  2125. } break;
  2126. case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
  2127. } break;
  2128. case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
  2129. } break;
  2130. default: {
  2131. }
  2132. }
  2133. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2134. Variant ret = post_importer_plugins.write[i]->get_internal_option_update_view_required(EditorScenePostImportPlugin::InternalImportCategory(p_category), p_option, p_options);
  2135. if (ret.get_type() == Variant::BOOL) {
  2136. return ret;
  2137. }
  2138. }
  2139. return false;
  2140. }
  2141. void ResourceImporterScene::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
  2142. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), ""));
  2143. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), ""));
  2144. List<String> script_extensions;
  2145. ResourceLoader::get_recognized_extensions_for_type("Script", &script_extensions);
  2146. String script_ext_hint;
  2147. for (const String &E : script_extensions) {
  2148. if (!script_ext_hint.is_empty()) {
  2149. script_ext_hint += ",";
  2150. }
  2151. script_ext_hint += "*." + E;
  2152. }
  2153. bool trimming_defaults_on = p_path.get_extension().to_lower() == "fbx";
  2154. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "nodes/apply_root_scale"), true));
  2155. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "nodes/root_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001"), 1.0));
  2156. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "nodes/import_as_skeleton_bones"), false));
  2157. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "nodes/use_node_type_suffixes"), true));
  2158. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
  2159. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true));
  2160. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true));
  2161. r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Static,Static Lightmaps,Dynamic", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
  2162. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.2));
  2163. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/force_disable_compression"), false));
  2164. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true));
  2165. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
  2166. r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30));
  2167. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), trimming_defaults_on));
  2168. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/remove_immutable_tracks"), true));
  2169. r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import_rest_as_RESET"), false));
  2170. r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
  2171. r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary()));
  2172. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2173. post_importer_plugins.write[i]->get_import_options(p_path, r_options);
  2174. }
  2175. for (Ref<EditorSceneFormatImporter> importer_elem : scene_importers) {
  2176. importer_elem->get_import_options(p_path, r_options);
  2177. }
  2178. }
  2179. void ResourceImporterScene::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {
  2180. for (Ref<EditorSceneFormatImporter> importer_elem : scene_importers) {
  2181. importer_elem->handle_compatibility_options(p_import_params);
  2182. }
  2183. }
  2184. void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) {
  2185. if (p_node != p_new_owner && p_node->get_owner() == p_scene) {
  2186. p_node->set_owner(p_new_owner);
  2187. }
  2188. for (int i = 0; i < p_node->get_child_count(); i++) {
  2189. Node *n = p_node->get_child(i);
  2190. _replace_owner(n, p_scene, p_new_owner);
  2191. }
  2192. }
  2193. Array ResourceImporterScene::_get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node) {
  2194. Array skin_pose_transform_array;
  2195. const Ref<Skin> skin = p_src_mesh_node->get_skin();
  2196. if (skin.is_valid()) {
  2197. NodePath skeleton_path = p_src_mesh_node->get_skeleton_path();
  2198. const Node *node = p_src_mesh_node->get_node_or_null(skeleton_path);
  2199. const Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
  2200. if (skeleton) {
  2201. int bind_count = skin->get_bind_count();
  2202. for (int i = 0; i < bind_count; i++) {
  2203. Transform3D bind_pose = skin->get_bind_pose(i);
  2204. String bind_name = skin->get_bind_name(i);
  2205. int bone_idx = bind_name.is_empty() ? skin->get_bind_bone(i) : skeleton->find_bone(bind_name);
  2206. ERR_FAIL_COND_V(bone_idx >= skeleton->get_bone_count(), Array());
  2207. Transform3D bp_global_rest;
  2208. if (bone_idx >= 0) {
  2209. bp_global_rest = skeleton->get_bone_global_pose(bone_idx);
  2210. } else {
  2211. bp_global_rest = skeleton->get_bone_global_pose(i);
  2212. }
  2213. skin_pose_transform_array.push_back(bp_global_rest * bind_pose);
  2214. }
  2215. }
  2216. }
  2217. return skin_pose_transform_array;
  2218. }
  2219. Node *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) {
  2220. ImporterMeshInstance3D *src_mesh_node = Object::cast_to<ImporterMeshInstance3D>(p_node);
  2221. if (src_mesh_node) {
  2222. //is mesh
  2223. MeshInstance3D *mesh_node = memnew(MeshInstance3D);
  2224. mesh_node->set_name(src_mesh_node->get_name());
  2225. mesh_node->set_transform(src_mesh_node->get_transform());
  2226. mesh_node->set_skin(src_mesh_node->get_skin());
  2227. mesh_node->set_skeleton_path(src_mesh_node->get_skeleton_path());
  2228. mesh_node->merge_meta_from(src_mesh_node);
  2229. if (src_mesh_node->get_mesh().is_valid()) {
  2230. Ref<ArrayMesh> mesh;
  2231. if (!src_mesh_node->get_mesh()->has_mesh()) {
  2232. //do mesh processing
  2233. bool generate_lods = p_generate_lods;
  2234. float merge_angle = 60.0f;
  2235. bool create_shadow_meshes = p_create_shadow_meshes;
  2236. bool bake_lightmaps = p_light_bake_mode == LIGHT_BAKE_STATIC_LIGHTMAPS;
  2237. String save_to_file;
  2238. String mesh_id = src_mesh_node->get_mesh()->get_meta("import_id", src_mesh_node->get_mesh()->get_name());
  2239. if (!mesh_id.is_empty() && p_mesh_data.has(mesh_id)) {
  2240. Dictionary mesh_settings = p_mesh_data[mesh_id];
  2241. {
  2242. //fill node settings for this node with default values
  2243. List<ImportOption> iopts;
  2244. get_internal_import_options(INTERNAL_IMPORT_CATEGORY_MESH, &iopts);
  2245. for (const ImportOption &E : iopts) {
  2246. if (!mesh_settings.has(E.option.name)) {
  2247. mesh_settings[E.option.name] = E.default_value;
  2248. }
  2249. }
  2250. }
  2251. if (mesh_settings.has("generate/shadow_meshes")) {
  2252. int shadow_meshes = mesh_settings["generate/shadow_meshes"];
  2253. if (shadow_meshes == MESH_OVERRIDE_ENABLE) {
  2254. create_shadow_meshes = true;
  2255. } else if (shadow_meshes == MESH_OVERRIDE_DISABLE) {
  2256. create_shadow_meshes = false;
  2257. }
  2258. }
  2259. if (mesh_settings.has("generate/lightmap_uv")) {
  2260. int lightmap_uv = mesh_settings["generate/lightmap_uv"];
  2261. if (lightmap_uv == MESH_OVERRIDE_ENABLE) {
  2262. bake_lightmaps = true;
  2263. } else if (lightmap_uv == MESH_OVERRIDE_DISABLE) {
  2264. bake_lightmaps = false;
  2265. }
  2266. }
  2267. if (mesh_settings.has("generate/lods")) {
  2268. int lods = mesh_settings["generate/lods"];
  2269. if (lods == MESH_OVERRIDE_ENABLE) {
  2270. generate_lods = true;
  2271. } else if (lods == MESH_OVERRIDE_DISABLE) {
  2272. generate_lods = false;
  2273. }
  2274. }
  2275. if (mesh_settings.has("lods/normal_merge_angle")) {
  2276. merge_angle = mesh_settings["lods/normal_merge_angle"];
  2277. }
  2278. if (bool(mesh_settings.get("save_to_file/enabled", false))) {
  2279. save_to_file = mesh_settings.get("save_to_file/path", String());
  2280. if (!ResourceUID::ensure_path(save_to_file).is_resource_file()) {
  2281. save_to_file = "";
  2282. }
  2283. }
  2284. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2285. post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH, nullptr, src_mesh_node, src_mesh_node->get_mesh(), mesh_settings);
  2286. }
  2287. }
  2288. if (bake_lightmaps) {
  2289. Transform3D xf;
  2290. Node3D *n = src_mesh_node;
  2291. while (n) {
  2292. xf = n->get_transform() * xf;
  2293. n = n->get_parent_node_3d();
  2294. }
  2295. Vector<uint8_t> lightmap_cache;
  2296. src_mesh_node->get_mesh()->lightmap_unwrap_cached(xf, p_lightmap_texel_size, p_src_lightmap_cache, lightmap_cache);
  2297. if (!lightmap_cache.is_empty()) {
  2298. if (r_lightmap_caches.is_empty()) {
  2299. r_lightmap_caches.push_back(lightmap_cache);
  2300. } else {
  2301. String new_md5 = String::md5(lightmap_cache.ptr()); // MD5 is stored at the beginning of the cache data
  2302. for (int i = 0; i < r_lightmap_caches.size(); i++) {
  2303. String md5 = String::md5(r_lightmap_caches[i].ptr());
  2304. if (new_md5 < md5) {
  2305. r_lightmap_caches.insert(i, lightmap_cache);
  2306. break;
  2307. }
  2308. if (new_md5 == md5) {
  2309. break;
  2310. }
  2311. }
  2312. }
  2313. }
  2314. }
  2315. if (generate_lods) {
  2316. Array skin_pose_transform_array = _get_skinned_pose_transforms(src_mesh_node);
  2317. src_mesh_node->get_mesh()->generate_lods(merge_angle, skin_pose_transform_array);
  2318. }
  2319. if (create_shadow_meshes) {
  2320. src_mesh_node->get_mesh()->create_shadow_mesh();
  2321. }
  2322. src_mesh_node->get_mesh()->optimize_indices();
  2323. if (!save_to_file.is_empty()) {
  2324. String save_res_path = ResourceUID::ensure_path(save_to_file);
  2325. Ref<Mesh> existing = ResourceCache::get_ref(save_res_path);
  2326. if (existing.is_valid()) {
  2327. //if somehow an existing one is useful, create
  2328. existing->reset_state();
  2329. }
  2330. mesh = src_mesh_node->get_mesh()->get_mesh(existing);
  2331. Error err = ResourceSaver::save(mesh, save_res_path); //override
  2332. if (err != OK) {
  2333. WARN_PRINT(vformat("Failed to save mesh %s to '%s'.", mesh->get_name(), save_res_path));
  2334. }
  2335. if (err == OK && save_to_file.begins_with("uid://")) {
  2336. // slow
  2337. ResourceSaver::set_uid(save_res_path, ResourceUID::get_singleton()->text_to_id(save_to_file));
  2338. }
  2339. mesh->set_path(save_res_path, true); //takeover existing, if needed
  2340. } else {
  2341. mesh = src_mesh_node->get_mesh()->get_mesh();
  2342. }
  2343. } else {
  2344. mesh = src_mesh_node->get_mesh()->get_mesh();
  2345. }
  2346. if (mesh.is_valid()) {
  2347. _copy_meta(src_mesh_node->get_mesh().ptr(), mesh.ptr());
  2348. mesh_node->set_mesh(mesh);
  2349. for (int i = 0; i < mesh->get_surface_count(); i++) {
  2350. mesh_node->set_surface_override_material(i, src_mesh_node->get_surface_material(i));
  2351. }
  2352. mesh->merge_meta_from(*src_mesh_node->get_mesh());
  2353. }
  2354. }
  2355. switch (p_light_bake_mode) {
  2356. case LIGHT_BAKE_DISABLED: {
  2357. mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_DISABLED);
  2358. } break;
  2359. case LIGHT_BAKE_DYNAMIC: {
  2360. mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_DYNAMIC);
  2361. } break;
  2362. case LIGHT_BAKE_STATIC:
  2363. case LIGHT_BAKE_STATIC_LIGHTMAPS: {
  2364. mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_STATIC);
  2365. } break;
  2366. }
  2367. mesh_node->set_layer_mask(src_mesh_node->get_layer_mask());
  2368. mesh_node->set_cast_shadows_setting(src_mesh_node->get_cast_shadows_setting());
  2369. mesh_node->set_visible(src_mesh_node->is_visible());
  2370. mesh_node->set_visibility_range_begin(src_mesh_node->get_visibility_range_begin());
  2371. mesh_node->set_visibility_range_begin_margin(src_mesh_node->get_visibility_range_begin_margin());
  2372. mesh_node->set_visibility_range_end(src_mesh_node->get_visibility_range_end());
  2373. mesh_node->set_visibility_range_end_margin(src_mesh_node->get_visibility_range_end_margin());
  2374. mesh_node->set_visibility_range_fade_mode(src_mesh_node->get_visibility_range_fade_mode());
  2375. _copy_meta(p_node, mesh_node);
  2376. p_node->replace_by(mesh_node);
  2377. p_node->set_owner(nullptr);
  2378. memdelete(p_node);
  2379. p_node = mesh_node;
  2380. }
  2381. for (int i = 0; i < p_node->get_child_count(); i++) {
  2382. _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);
  2383. }
  2384. return p_node;
  2385. }
  2386. void ResourceImporterScene::_add_shapes(Node *p_node, const Vector<Ref<Shape3D>> &p_shapes) {
  2387. for (const Ref<Shape3D> &E : p_shapes) {
  2388. CollisionShape3D *cshape = memnew(CollisionShape3D);
  2389. cshape->set_shape(E);
  2390. p_node->add_child(cshape, true);
  2391. cshape->set_owner(p_node->get_owner());
  2392. }
  2393. }
  2394. void ResourceImporterScene::_copy_meta(Object *p_src_object, Object *p_dst_object) {
  2395. List<StringName> meta_list;
  2396. p_src_object->get_meta_list(&meta_list);
  2397. for (const StringName &meta_key : meta_list) {
  2398. Variant meta_value = p_src_object->get_meta(meta_key);
  2399. p_dst_object->set_meta(meta_key, meta_value);
  2400. }
  2401. }
  2402. void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, AnimationImportTracks *p_track_actions) {
  2403. List<StringName> anims;
  2404. p_player->get_animation_list(&anims);
  2405. Node *parent = p_player->get_parent();
  2406. ERR_FAIL_NULL(parent);
  2407. HashMap<NodePath, uint32_t> used_tracks[TRACK_CHANNEL_MAX];
  2408. bool tracks_to_add = false;
  2409. 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 };
  2410. for (const StringName &I : anims) {
  2411. Ref<Animation> anim = p_player->get_animation(I);
  2412. for (int i = 0; i < anim->get_track_count(); i++) {
  2413. for (int j = 0; j < TRACK_CHANNEL_MAX; j++) {
  2414. if (anim->track_get_type(i) != track_types[j]) {
  2415. continue;
  2416. }
  2417. switch (p_track_actions[j]) {
  2418. case ANIMATION_IMPORT_TRACKS_IF_PRESENT: {
  2419. // Do Nothing.
  2420. } break;
  2421. case ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL: {
  2422. used_tracks[j].insert(anim->track_get_path(i), 0);
  2423. tracks_to_add = true;
  2424. } break;
  2425. case ANIMATION_IMPORT_TRACKS_NEVER: {
  2426. anim->remove_track(i);
  2427. i--;
  2428. } break;
  2429. }
  2430. }
  2431. }
  2432. }
  2433. if (!tracks_to_add) {
  2434. return;
  2435. }
  2436. uint32_t pass = 0;
  2437. for (const StringName &I : anims) {
  2438. Ref<Animation> anim = p_player->get_animation(I);
  2439. for (int j = 0; j < TRACK_CHANNEL_MAX; j++) {
  2440. if (p_track_actions[j] != ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
  2441. continue;
  2442. }
  2443. pass++;
  2444. for (int i = 0; i < anim->get_track_count(); i++) {
  2445. if (anim->track_get_type(i) != track_types[j]) {
  2446. continue;
  2447. }
  2448. NodePath path = anim->track_get_path(i);
  2449. ERR_CONTINUE(!used_tracks[j].has(path)); // Should never happen.
  2450. used_tracks[j][path] = pass;
  2451. }
  2452. for (const KeyValue<NodePath, uint32_t> &J : used_tracks[j]) {
  2453. if (J.value == pass) {
  2454. continue;
  2455. }
  2456. NodePath path = J.key;
  2457. Node *n = parent->get_node(path);
  2458. if (j == TRACK_CHANNEL_BLEND_SHAPE) {
  2459. MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n);
  2460. if (mi && path.get_subname_count() > 0) {
  2461. StringName bs = path.get_subname(0);
  2462. bool valid;
  2463. float value = mi->get(bs, &valid);
  2464. if (valid) {
  2465. int track_idx = anim->add_track(track_types[j]);
  2466. anim->track_set_path(track_idx, path);
  2467. anim->track_set_imported(track_idx, true);
  2468. anim->blend_shape_track_insert_key(track_idx, 0, value);
  2469. }
  2470. }
  2471. } else {
  2472. Skeleton3D *skel = Object::cast_to<Skeleton3D>(n);
  2473. Node3D *n3d = Object::cast_to<Node3D>(n);
  2474. Vector3 loc;
  2475. Quaternion rot;
  2476. Vector3 scale;
  2477. if (skel && path.get_subname_count() > 0) {
  2478. StringName bone = path.get_subname(0);
  2479. int bone_idx = skel->find_bone(bone);
  2480. if (bone_idx == -1) {
  2481. continue;
  2482. }
  2483. // Note that this is using get_bone_pose to update the bone pose cache.
  2484. _ALLOW_DISCARD_ skel->get_bone_pose(bone_idx);
  2485. loc = skel->get_bone_pose_position(bone_idx);
  2486. rot = skel->get_bone_pose_rotation(bone_idx);
  2487. scale = skel->get_bone_pose_scale(bone_idx);
  2488. } else if (n3d) {
  2489. loc = n3d->get_position();
  2490. rot = n3d->get_transform().basis.get_rotation_quaternion();
  2491. scale = n3d->get_scale();
  2492. } else {
  2493. continue;
  2494. }
  2495. // Ensure insertion keeps tracks together and ordered by type (loc/rot/scale)
  2496. int insert_at_pos = -1;
  2497. for (int k = 0; k < anim->get_track_count(); k++) {
  2498. NodePath tpath = anim->track_get_path(k);
  2499. if (path == tpath) {
  2500. Animation::TrackType ttype = anim->track_get_type(k);
  2501. if (insert_at_pos == -1) {
  2502. // First insert, determine whether replacing or kicking back
  2503. if (track_types[j] < ttype) {
  2504. insert_at_pos = k;
  2505. break; // No point in continuing.
  2506. } else {
  2507. insert_at_pos = k + 1;
  2508. }
  2509. } else if (ttype < track_types[j]) {
  2510. // Kick back.
  2511. insert_at_pos = k + 1;
  2512. }
  2513. } else if (insert_at_pos >= 0) {
  2514. break;
  2515. }
  2516. }
  2517. int track_idx = anim->add_track(track_types[j], insert_at_pos);
  2518. anim->track_set_path(track_idx, path);
  2519. anim->track_set_imported(track_idx, true);
  2520. switch (j) {
  2521. case TRACK_CHANNEL_POSITION: {
  2522. anim->position_track_insert_key(track_idx, 0, loc);
  2523. } break;
  2524. case TRACK_CHANNEL_ROTATION: {
  2525. anim->rotation_track_insert_key(track_idx, 0, rot);
  2526. } break;
  2527. case TRACK_CHANNEL_SCALE: {
  2528. anim->scale_track_insert_key(track_idx, 0, scale);
  2529. } break;
  2530. default: {
  2531. }
  2532. }
  2533. }
  2534. }
  2535. }
  2536. }
  2537. }
  2538. void ResourceImporterScene::_generate_editor_preview_for_scene(const String &p_path, Node *p_scene) {
  2539. if (!Engine::get_singleton()->is_editor_hint()) {
  2540. return;
  2541. }
  2542. ERR_FAIL_COND_MSG(p_path.is_empty(), "Path is empty, cannot generate preview.");
  2543. ERR_FAIL_NULL_MSG(p_scene, "Scene is null, cannot generate preview.");
  2544. EditorInterface::get_singleton()->make_scene_preview(p_path, p_scene, 1024);
  2545. }
  2546. Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashMap<StringName, Variant> &p_options) {
  2547. Ref<EditorSceneFormatImporter> importer;
  2548. String ext = p_source_file.get_extension().to_lower();
  2549. // TRANSLATORS: This is an editor progress label.
  2550. EditorProgress progress("pre-import", TTR("Pre-Import Scene"), 0);
  2551. progress.step(TTR("Importing Scene..."), 0);
  2552. for (Ref<EditorSceneFormatImporter> importer_elem : scene_importers) {
  2553. List<String> extensions;
  2554. importer_elem->get_extensions(&extensions);
  2555. for (const String &F : extensions) {
  2556. if (F.to_lower() == ext) {
  2557. importer = importer_elem;
  2558. break;
  2559. }
  2560. }
  2561. if (importer.is_valid()) {
  2562. break;
  2563. }
  2564. }
  2565. ERR_FAIL_COND_V(importer.is_null(), nullptr);
  2566. ERR_FAIL_COND_V(p_options.is_empty(), nullptr);
  2567. Error err = OK;
  2568. Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS | EditorSceneFormatImporter::IMPORT_FORCE_DISABLE_MESH_COMPRESSION, p_options, nullptr, &err);
  2569. if (!scene || err != OK) {
  2570. return nullptr;
  2571. }
  2572. _pre_fix_global(scene, p_options);
  2573. HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
  2574. List<Pair<NodePath, Node *>> node_renames;
  2575. _pre_fix_node(scene, scene, collision_map, nullptr, node_renames, p_options);
  2576. return scene;
  2577. }
  2578. static Error convert_path_to_uid(ResourceUID::ID p_source_id, const String &p_hash_str, Dictionary &p_settings, const String &p_path_key, const String &p_fallback_path_key) {
  2579. const String &raw_save_path = p_settings[p_path_key];
  2580. String save_path = ResourceUID::ensure_path(raw_save_path);
  2581. if (raw_save_path.begins_with("uid://")) {
  2582. if (save_path.is_empty() || !DirAccess::exists(save_path.get_base_dir())) {
  2583. if (p_settings.has(p_fallback_path_key)) {
  2584. String fallback_save_path = p_settings[p_fallback_path_key];
  2585. if (!fallback_save_path.is_empty() && DirAccess::exists(fallback_save_path.get_base_dir())) {
  2586. save_path = fallback_save_path;
  2587. ResourceUID::get_singleton()->add_id(ResourceUID::get_singleton()->text_to_id(raw_save_path), save_path);
  2588. }
  2589. }
  2590. } else {
  2591. p_settings[p_fallback_path_key] = save_path;
  2592. }
  2593. }
  2594. ERR_FAIL_COND_V(!save_path.is_empty() && !DirAccess::exists(save_path.get_base_dir()), ERR_FILE_BAD_PATH);
  2595. if (!save_path.is_empty() && !raw_save_path.begins_with("uid://")) {
  2596. const ResourceUID::ID id = ResourceLoader::get_resource_uid(save_path);
  2597. if (id != ResourceUID::INVALID_ID) {
  2598. p_settings[p_path_key] = ResourceUID::get_singleton()->id_to_text(id);
  2599. } else {
  2600. ResourceUID::ID save_id = hash64_murmur3_64(p_hash_str.hash64(), p_source_id) & 0x7FFFFFFFFFFFFFFF;
  2601. if (ResourceUID::get_singleton()->has_id(save_id)) {
  2602. if (save_path != ResourceUID::get_singleton()->get_id_path(save_id)) {
  2603. // The user has specified a path which does not match the default UID.
  2604. save_id = ResourceUID::get_singleton()->create_id_for_path(save_path);
  2605. }
  2606. }
  2607. p_settings[p_path_key] = ResourceUID::get_singleton()->id_to_text(save_id);
  2608. ResourceUID::get_singleton()->add_id(save_id, save_path);
  2609. }
  2610. p_settings[p_fallback_path_key] = save_path;
  2611. }
  2612. return OK;
  2613. }
  2614. Error ResourceImporterScene::_check_resource_save_paths(ResourceUID::ID p_source_id, const String &p_hash_suffix, const Dictionary &p_data) {
  2615. for (const KeyValue<Variant, Variant> &kv : p_data) {
  2616. Dictionary settings = kv.value;
  2617. if (bool(settings.get("save_to_file/enabled", false)) && settings.has("save_to_file/path")) {
  2618. String to_hash = kv.key.operator String() + p_hash_suffix;
  2619. Error ret = convert_path_to_uid(p_source_id, to_hash, settings, "save_to_file/path", "save_to_file/fallback_path");
  2620. ERR_FAIL_COND_V_MSG(ret != OK, ret, vformat("Resource save path %s not valid. Ensure parent directory has been created.", settings.has("save_to_file/path")));
  2621. }
  2622. if (settings.has("slices/amount")) {
  2623. int slice_count = settings["slices/amount"];
  2624. for (int si = 0; si < slice_count; si++) {
  2625. if (bool(settings.get("slice_" + itos(si + 1) + "/save_to_file/enabled", false)) &&
  2626. settings.has("slice_" + itos(si + 1) + "/save_to_file/path")) {
  2627. String to_hash = kv.key.operator String() + p_hash_suffix + itos(si + 1);
  2628. Error ret = convert_path_to_uid(p_source_id, to_hash, settings,
  2629. "slice_" + itos(si + 1) + "/save_to_file/path",
  2630. "slice_" + itos(si + 1) + "/save_to_file/fallback_path");
  2631. ERR_FAIL_COND_V_MSG(ret != OK, ret, vformat("Slice save path %s not valid. Ensure parent directory has been created.", settings.has("save_to_file/path")));
  2632. }
  2633. }
  2634. }
  2635. }
  2636. return OK;
  2637. }
  2638. Error ResourceImporterScene::import(ResourceUID::ID p_source_id, 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) {
  2639. const String &src_path = p_source_file;
  2640. Ref<EditorSceneFormatImporter> importer;
  2641. String ext = src_path.get_extension().to_lower();
  2642. EditorProgress progress("import", TTR("Import Scene"), 104);
  2643. progress.step(TTR("Importing Scene..."), 0);
  2644. for (Ref<EditorSceneFormatImporter> importer_elem : scene_importers) {
  2645. List<String> extensions;
  2646. importer_elem->get_extensions(&extensions);
  2647. for (const String &F : extensions) {
  2648. if (F.to_lower() == ext) {
  2649. importer = importer_elem;
  2650. break;
  2651. }
  2652. }
  2653. if (importer.is_valid()) {
  2654. break;
  2655. }
  2656. }
  2657. ERR_FAIL_COND_V(importer.is_null(), ERR_FILE_UNRECOGNIZED);
  2658. ERR_FAIL_COND_V(p_options.is_empty(), ERR_BUG);
  2659. int import_flags = 0;
  2660. if (_scene_import_type == "AnimationLibrary") {
  2661. import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
  2662. import_flags |= EditorSceneFormatImporter::IMPORT_DISCARD_MESHES_AND_MATERIALS;
  2663. } else if (bool(p_options["animation/import"])) {
  2664. import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
  2665. }
  2666. if (bool(p_options["skins/use_named_skins"])) {
  2667. import_flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
  2668. }
  2669. bool ensure_tangents = p_options["meshes/ensure_tangents"];
  2670. if (ensure_tangents) {
  2671. import_flags |= EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
  2672. }
  2673. bool force_disable_compression = p_options["meshes/force_disable_compression"];
  2674. if (force_disable_compression) {
  2675. import_flags |= EditorSceneFormatImporter::IMPORT_FORCE_DISABLE_MESH_COMPRESSION;
  2676. }
  2677. Dictionary subresources = p_options["_subresources"];
  2678. Error err = OK;
  2679. // Check whether any of the meshes or animations have nonexistent save paths
  2680. // and if they do, fail the import immediately.
  2681. if (subresources.has("meshes")) {
  2682. err = _check_resource_save_paths(p_source_id, "m", subresources["meshes"]);
  2683. if (err != OK) {
  2684. return err;
  2685. }
  2686. }
  2687. if (subresources.has("animations")) {
  2688. err = _check_resource_save_paths(p_source_id, "a", subresources["animations"]);
  2689. if (err != OK) {
  2690. return err;
  2691. }
  2692. }
  2693. List<String> missing_deps; // for now, not much will be done with this
  2694. Node *scene = importer->import_scene(src_path, import_flags, p_options, &missing_deps, &err);
  2695. if (!scene || err != OK) {
  2696. return err;
  2697. }
  2698. bool apply_root = true;
  2699. if (p_options.has("nodes/apply_root_scale")) {
  2700. apply_root = p_options["nodes/apply_root_scale"];
  2701. }
  2702. real_t root_scale = 1;
  2703. if (p_options.has("nodes/root_scale")) {
  2704. root_scale = p_options["nodes/root_scale"];
  2705. }
  2706. if (Object::cast_to<Node3D>(scene)) {
  2707. Node3D *scene_3d = Object::cast_to<Node3D>(scene);
  2708. Vector3 scale = Vector3(root_scale, root_scale, root_scale);
  2709. if (apply_root) {
  2710. _apply_permanent_scale_to_descendants(scene, scale);
  2711. } else {
  2712. scene_3d->scale(scale);
  2713. }
  2714. }
  2715. _pre_fix_global(scene, p_options);
  2716. HashSet<Ref<ImporterMesh>> scanned_meshes;
  2717. HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
  2718. Pair<PackedVector3Array, PackedInt32Array> occluder_arrays;
  2719. List<Pair<NodePath, Node *>> node_renames;
  2720. _pre_fix_node(scene, scene, collision_map, &occluder_arrays, node_renames, p_options);
  2721. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2722. post_importer_plugins.write[i]->pre_process(scene, p_options);
  2723. }
  2724. // data in _subresources may be modified by pre_process(), so wait until now to check.
  2725. Dictionary node_data;
  2726. if (subresources.has("nodes")) {
  2727. node_data = subresources["nodes"];
  2728. }
  2729. Dictionary material_data;
  2730. if (subresources.has("materials")) {
  2731. material_data = subresources["materials"];
  2732. }
  2733. Dictionary animation_data;
  2734. if (subresources.has("animations")) {
  2735. animation_data = subresources["animations"];
  2736. }
  2737. Dictionary mesh_data;
  2738. if (subresources.has("meshes")) {
  2739. mesh_data = subresources["meshes"];
  2740. }
  2741. float fps = 30;
  2742. if (p_options.has(SNAME("animation/fps"))) {
  2743. fps = (float)p_options[SNAME("animation/fps")];
  2744. }
  2745. bool remove_immutable_tracks = p_options.has("animation/remove_immutable_tracks") ? (bool)p_options["animation/remove_immutable_tracks"] : true;
  2746. _pre_fix_animations(scene, scene, node_data, animation_data, fps);
  2747. _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps, apply_root ? root_scale : 1.0);
  2748. _post_fix_animations(scene, scene, node_data, animation_data, fps, remove_immutable_tracks);
  2749. String root_type = p_options["nodes/root_type"];
  2750. if (!root_type.is_empty()) {
  2751. root_type = root_type.split(" ")[0]; // Full root_type is "ClassName (filename.gd)" for a script global class.
  2752. Ref<Script> root_script = nullptr;
  2753. if (ScriptServer::is_global_class(root_type)) {
  2754. root_script = ResourceLoader::load(ScriptServer::get_global_class_path(root_type));
  2755. root_type = ScriptServer::get_global_class_base(root_type);
  2756. }
  2757. if (scene->get_class_name() != root_type) {
  2758. // If the user specified a Godot node type that does not match
  2759. // what the scene import gave us, replace the root node.
  2760. Node *base_node = Object::cast_to<Node>(ClassDB::instantiate(root_type));
  2761. if (base_node) {
  2762. scene->replace_by(base_node);
  2763. scene->set_owner(nullptr);
  2764. memdelete(scene);
  2765. scene = base_node;
  2766. }
  2767. }
  2768. if (root_script.is_valid()) {
  2769. scene->set_script(Variant(root_script));
  2770. }
  2771. }
  2772. String root_name = p_options["nodes/root_name"];
  2773. if (!root_name.is_empty() && root_name != "Scene Root") {
  2774. // TODO: Remove `&& root_name != "Scene Root"` for Godot 5.0.
  2775. // For backwards compatibility with existing .import files,
  2776. // treat "Scene Root" as having no root name override.
  2777. scene->set_name(root_name);
  2778. } else if (String(scene->get_name()).is_empty()) {
  2779. scene->set_name(p_save_path.get_file().get_basename());
  2780. }
  2781. if (!occluder_arrays.first.is_empty() && !occluder_arrays.second.is_empty()) {
  2782. Ref<ArrayOccluder3D> occ = memnew(ArrayOccluder3D);
  2783. occ->set_arrays(occluder_arrays.first, occluder_arrays.second);
  2784. OccluderInstance3D *occluder_instance = memnew(OccluderInstance3D);
  2785. occluder_instance->set_occluder(occ);
  2786. scene->add_child(occluder_instance, true);
  2787. occluder_instance->set_owner(scene);
  2788. }
  2789. bool gen_lods = bool(p_options["meshes/generate_lods"]);
  2790. bool create_shadow_meshes = bool(p_options["meshes/create_shadow_meshes"]);
  2791. int light_bake_mode = p_options["meshes/light_baking"];
  2792. float texel_size = p_options["meshes/lightmap_texel_size"];
  2793. float lightmap_texel_size = MAX(0.001, texel_size);
  2794. Vector<uint8_t> src_lightmap_cache;
  2795. Vector<Vector<uint8_t>> mesh_lightmap_caches;
  2796. {
  2797. src_lightmap_cache = FileAccess::get_file_as_bytes(p_source_file + ".unwrap_cache", &err);
  2798. if (err != OK) {
  2799. src_lightmap_cache.clear();
  2800. }
  2801. }
  2802. scene = _generate_meshes(scene, mesh_data, gen_lods, create_shadow_meshes, LightBakeMode(light_bake_mode), lightmap_texel_size, src_lightmap_cache, mesh_lightmap_caches);
  2803. if (mesh_lightmap_caches.size()) {
  2804. Ref<FileAccess> f = FileAccess::open(p_source_file + ".unwrap_cache", FileAccess::WRITE);
  2805. if (f.is_valid()) {
  2806. f->store_32(mesh_lightmap_caches.size());
  2807. for (int i = 0; i < mesh_lightmap_caches.size(); i++) {
  2808. String md5 = String::md5(mesh_lightmap_caches[i].ptr());
  2809. f->store_buffer(mesh_lightmap_caches[i].ptr(), mesh_lightmap_caches[i].size());
  2810. }
  2811. }
  2812. }
  2813. err = OK;
  2814. progress.step(TTR("Running Custom Script..."), 2);
  2815. String post_import_script_path = p_options["import_script/path"];
  2816. Ref<EditorScenePostImport> post_import_script;
  2817. if (!post_import_script_path.is_empty()) {
  2818. if (post_import_script_path.is_relative_path()) {
  2819. post_import_script_path = p_source_file.get_base_dir().path_join(post_import_script_path);
  2820. }
  2821. Ref<Script> scr = ResourceLoader::load(post_import_script_path);
  2822. if (scr.is_null()) {
  2823. EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path);
  2824. } else {
  2825. post_import_script.instantiate();
  2826. post_import_script->set_script(scr);
  2827. if (!post_import_script->get_script_instance()) {
  2828. EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):") + " " + post_import_script_path);
  2829. post_import_script.unref();
  2830. return ERR_CANT_CREATE;
  2831. }
  2832. }
  2833. }
  2834. // Apply RESET animation before serializing.
  2835. if (_scene_import_type == "PackedScene") {
  2836. int scene_child_count = scene->get_child_count();
  2837. for (int i = 0; i < scene_child_count; i++) {
  2838. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(scene->get_child(i));
  2839. if (ap) {
  2840. if (ap->can_apply_reset()) {
  2841. ap->apply_reset();
  2842. }
  2843. }
  2844. }
  2845. }
  2846. if (post_import_script.is_valid()) {
  2847. post_import_script->init(p_source_file);
  2848. scene = post_import_script->post_import(scene);
  2849. if (!scene) {
  2850. EditorNode::add_io_error(
  2851. TTR("Error running post-import script:") + " " + post_import_script_path + "\n" +
  2852. TTR("Did you return a Node-derived object in the `_post_import()` method?"));
  2853. return err;
  2854. }
  2855. }
  2856. for (int i = 0; i < post_importer_plugins.size(); i++) {
  2857. post_importer_plugins.write[i]->post_process(scene, p_options);
  2858. }
  2859. progress.step(TTR("Saving..."), 104);
  2860. int flags = 0;
  2861. if (EditorSettings::get_singleton() && EDITOR_GET("filesystem/on_save/compress_binary_resources")) {
  2862. flags |= ResourceSaver::FLAG_COMPRESS;
  2863. }
  2864. if (_scene_import_type == "AnimationLibrary") {
  2865. Ref<AnimationLibrary> library;
  2866. for (int i = 0; i < scene->get_child_count(); i++) {
  2867. AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(scene->get_child(i));
  2868. if (ap) {
  2869. List<StringName> libs;
  2870. ap->get_animation_library_list(&libs);
  2871. if (libs.size()) {
  2872. library = ap->get_animation_library(libs.front()->get());
  2873. break;
  2874. }
  2875. }
  2876. }
  2877. if (library.is_null()) {
  2878. library.instantiate(); // Will be empty
  2879. }
  2880. print_verbose("Saving animation to: " + p_save_path + ".res");
  2881. err = ResourceSaver::save(library, p_save_path + ".res", flags); //do not take over, let the changed files reload themselves
  2882. ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save animation to file '" + p_save_path + ".res'.");
  2883. } else if (_scene_import_type == "PackedScene") {
  2884. Ref<PackedScene> packer = memnew(PackedScene);
  2885. packer->pack(scene);
  2886. print_verbose("Saving scene to: " + p_save_path + ".scn");
  2887. err = ResourceSaver::save(packer, p_save_path + ".scn", flags); //do not take over, let the changed files reload themselves
  2888. ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save scene to file '" + p_save_path + ".scn'.");
  2889. _generate_editor_preview_for_scene(p_source_file, scene);
  2890. } else {
  2891. ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unknown scene import type: " + _scene_import_type);
  2892. }
  2893. memdelete(scene);
  2894. //this is not the time to reimport, wait until import process is done, import file is saved, etc.
  2895. //EditorNode::get_singleton()->reload_scene(p_source_file);
  2896. return OK;
  2897. }
  2898. ResourceImporterScene *ResourceImporterScene::scene_singleton = nullptr;
  2899. ResourceImporterScene *ResourceImporterScene::animation_singleton = nullptr;
  2900. Vector<Ref<EditorSceneFormatImporter>> ResourceImporterScene::scene_importers;
  2901. Vector<Ref<EditorScenePostImportPlugin>> ResourceImporterScene::post_importer_plugins;
  2902. bool ResourceImporterScene::has_advanced_options() const {
  2903. return true;
  2904. }
  2905. void ResourceImporterScene::show_advanced_options(const String &p_path) {
  2906. SceneImportSettingsDialog::get_singleton()->open_settings(p_path, _scene_import_type);
  2907. }
  2908. ResourceImporterScene::ResourceImporterScene(const String &p_scene_import_type, bool p_singleton) {
  2909. // This should only be set through the EditorNode.
  2910. if (p_singleton) {
  2911. if (p_scene_import_type == "AnimationLibrary") {
  2912. animation_singleton = this;
  2913. } else if (p_scene_import_type == "PackedScene") {
  2914. scene_singleton = this;
  2915. }
  2916. }
  2917. _scene_import_type = p_scene_import_type;
  2918. }
  2919. ResourceImporterScene::~ResourceImporterScene() {
  2920. if (animation_singleton == this) {
  2921. animation_singleton = nullptr;
  2922. }
  2923. if (scene_singleton == this) {
  2924. scene_singleton = nullptr;
  2925. }
  2926. }
  2927. void ResourceImporterScene::add_scene_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority) {
  2928. ERR_FAIL_COND(p_importer.is_null());
  2929. if (p_first_priority) {
  2930. scene_importers.insert(0, p_importer);
  2931. } else {
  2932. scene_importers.push_back(p_importer);
  2933. }
  2934. }
  2935. void ResourceImporterScene::remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) {
  2936. post_importer_plugins.erase(p_plugin);
  2937. }
  2938. void ResourceImporterScene::add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin, bool p_first_priority) {
  2939. ERR_FAIL_COND(p_plugin.is_null());
  2940. if (p_first_priority) {
  2941. post_importer_plugins.insert(0, p_plugin);
  2942. } else {
  2943. post_importer_plugins.push_back(p_plugin);
  2944. }
  2945. }
  2946. void ResourceImporterScene::remove_scene_importer(Ref<EditorSceneFormatImporter> p_importer) {
  2947. scene_importers.erase(p_importer);
  2948. }
  2949. void ResourceImporterScene::clean_up_importer_plugins() {
  2950. scene_importers.clear();
  2951. post_importer_plugins.clear();
  2952. }
  2953. void ResourceImporterScene::get_scene_importer_extensions(List<String> *p_extensions) {
  2954. for (Ref<EditorSceneFormatImporter> importer_elem : scene_importers) {
  2955. importer_elem->get_extensions(p_extensions);
  2956. }
  2957. }
  2958. ///////////////////////////////////////
  2959. void EditorSceneFormatImporterESCN::get_extensions(List<String> *r_extensions) const {
  2960. r_extensions->push_back("escn");
  2961. }
  2962. 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) {
  2963. Error error;
  2964. Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
  2965. ERR_FAIL_COND_V_MSG(ps.is_null(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");
  2966. Node *scene = ps->instantiate();
  2967. TypedArray<Node> nodes = scene->find_children("*", "MeshInstance3D");
  2968. for (int32_t node_i = 0; node_i < nodes.size(); node_i++) {
  2969. MeshInstance3D *mesh_3d = cast_to<MeshInstance3D>(nodes[node_i]);
  2970. Ref<ImporterMesh> mesh;
  2971. mesh.instantiate();
  2972. // Ignore the aabb, it will be recomputed.
  2973. ImporterMeshInstance3D *importer_mesh_3d = memnew(ImporterMeshInstance3D);
  2974. importer_mesh_3d->set_name(mesh_3d->get_name());
  2975. importer_mesh_3d->set_transform(mesh_3d->get_relative_transform(mesh_3d->get_parent()));
  2976. importer_mesh_3d->set_skin(mesh_3d->get_skin());
  2977. importer_mesh_3d->set_skeleton_path(mesh_3d->get_skeleton_path());
  2978. Ref<ArrayMesh> array_mesh_3d_mesh = mesh_3d->get_mesh();
  2979. if (array_mesh_3d_mesh.is_valid()) {
  2980. // For the MeshInstance3D nodes, we need to convert the ArrayMesh to an ImporterMesh specially.
  2981. mesh->set_name(array_mesh_3d_mesh->get_name());
  2982. for (int32_t blend_i = 0; blend_i < array_mesh_3d_mesh->get_blend_shape_count(); blend_i++) {
  2983. mesh->add_blend_shape(array_mesh_3d_mesh->get_blend_shape_name(blend_i));
  2984. }
  2985. for (int32_t surface_i = 0; surface_i < array_mesh_3d_mesh->get_surface_count(); surface_i++) {
  2986. mesh->add_surface(array_mesh_3d_mesh->surface_get_primitive_type(surface_i),
  2987. array_mesh_3d_mesh->surface_get_arrays(surface_i),
  2988. array_mesh_3d_mesh->surface_get_blend_shape_arrays(surface_i),
  2989. array_mesh_3d_mesh->surface_get_lods(surface_i),
  2990. array_mesh_3d_mesh->surface_get_material(surface_i),
  2991. array_mesh_3d_mesh->surface_get_name(surface_i),
  2992. array_mesh_3d_mesh->surface_get_format(surface_i));
  2993. }
  2994. mesh->set_blend_shape_mode(array_mesh_3d_mesh->get_blend_shape_mode());
  2995. importer_mesh_3d->set_mesh(mesh);
  2996. mesh_3d->replace_by(importer_mesh_3d);
  2997. continue;
  2998. }
  2999. Ref<Mesh> mesh_3d_mesh = mesh_3d->get_mesh();
  3000. if (mesh_3d_mesh.is_valid()) {
  3001. // For the MeshInstance3D nodes, we need to convert the Mesh to an ImporterMesh specially.
  3002. mesh->set_name(mesh_3d_mesh->get_name());
  3003. for (int32_t surface_i = 0; surface_i < mesh_3d_mesh->get_surface_count(); surface_i++) {
  3004. mesh->add_surface(mesh_3d_mesh->surface_get_primitive_type(surface_i),
  3005. mesh_3d_mesh->surface_get_arrays(surface_i),
  3006. Array(),
  3007. mesh_3d_mesh->surface_get_lods(surface_i),
  3008. mesh_3d_mesh->surface_get_material(surface_i),
  3009. mesh_3d_mesh->surface_get_material(surface_i).is_valid() ? mesh_3d_mesh->surface_get_material(surface_i)->get_name() : String(),
  3010. mesh_3d_mesh->surface_get_format(surface_i));
  3011. }
  3012. importer_mesh_3d->set_mesh(mesh);
  3013. mesh_3d->replace_by(importer_mesh_3d);
  3014. continue;
  3015. }
  3016. }
  3017. ERR_FAIL_NULL_V(scene, nullptr);
  3018. return scene;
  3019. }