resource_importer_scene.cpp 113 KB

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