resource_importer_scene.cpp 88 KB

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