editor_scene_import_plugin.cpp 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784
  1. /*************************************************************************/
  2. /* editor_scene_import_plugin.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2020 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 "editor_scene_import_plugin.h"
  31. #include "editor/create_dialog.h"
  32. #include "editor/editor_node.h"
  33. #include "globals.h"
  34. #include "io/resource_saver.h"
  35. #include "os/file_access.h"
  36. #include "os/os.h"
  37. #include "scene/3d/body_shape.h"
  38. #include "scene/3d/mesh_instance.h"
  39. #include "scene/3d/navigation.h"
  40. #include "scene/3d/path.h"
  41. #include "scene/3d/physics_body.h"
  42. #include "scene/3d/portal.h"
  43. #include "scene/3d/room_instance.h"
  44. #include "scene/3d/vehicle_body.h"
  45. #include "scene/animation/animation_player.h"
  46. #include "scene/resources/box_shape.h"
  47. #include "scene/resources/packed_scene.h"
  48. #include "scene/resources/sphere_shape.h"
  49. #include <scene/resources/box_shape.h>
  50. #include <scene/resources/plane_shape.h>
  51. #include <scene/resources/ray_shape.h>
  52. EditorSceneImporter::EditorSceneImporter() {
  53. }
  54. void EditorScenePostImport::_bind_methods() {
  55. BIND_VMETHOD(MethodInfo("post_import", PropertyInfo(Variant::OBJECT, "scene")));
  56. }
  57. Node *EditorScenePostImport::post_import(Node *p_scene) {
  58. if (get_script_instance())
  59. return get_script_instance()->call("post_import", p_scene);
  60. return p_scene;
  61. }
  62. EditorScenePostImport::EditorScenePostImport() {
  63. }
  64. /////////////////////////////
  65. class EditorImportAnimationOptions : public VBoxContainer {
  66. OBJ_TYPE(EditorImportAnimationOptions, VBoxContainer);
  67. TreeItem *fps;
  68. TreeItem *optimize_linear_error;
  69. TreeItem *optimize_angular_error;
  70. TreeItem *optimize_max_angle;
  71. TreeItem *clips_base;
  72. TextEdit *filters;
  73. Vector<TreeItem *> clips;
  74. Tree *flags;
  75. Tree *clips_tree;
  76. Tree *optimization_tree;
  77. Vector<TreeItem *> items;
  78. bool updating;
  79. bool validating;
  80. void _changed();
  81. void _item_edited();
  82. void _button_action(Object *p_obj, int p_col, int p_id);
  83. protected:
  84. static void _bind_methods();
  85. void _notification(int p_what);
  86. public:
  87. void set_flags(uint32_t p_flags);
  88. uint32_t get_flags() const;
  89. void set_fps(int p_fps);
  90. int get_fps() const;
  91. void set_optimize_linear_error(float p_error);
  92. float get_optimize_linear_error() const;
  93. void set_optimize_angular_error(float p_error);
  94. float get_optimize_angular_error() const;
  95. void set_optimize_max_angle(float p_error);
  96. float get_optimize_max_angle() const;
  97. void setup_clips(const Array &p_clips);
  98. Array get_clips() const;
  99. void set_filter(const String &p_filter);
  100. String get_filter() const;
  101. EditorImportAnimationOptions();
  102. };
  103. ////////////////////////////
  104. class EditorSceneImportDialog : public ConfirmationDialog {
  105. OBJ_TYPE(EditorSceneImportDialog, ConfirmationDialog);
  106. struct FlagInfo {
  107. int value;
  108. const char *category;
  109. const char *text;
  110. bool defval;
  111. };
  112. static const FlagInfo scene_flag_names[];
  113. EditorImportTextureOptions *texture_options;
  114. EditorImportAnimationOptions *animation_options;
  115. EditorSceneImportPlugin *plugin;
  116. EditorNode *editor;
  117. LineEdit *import_path;
  118. LineEdit *save_path;
  119. LineEdit *script_path;
  120. Tree *import_options;
  121. EditorFileDialog *file_select;
  122. EditorFileDialog *script_select;
  123. EditorDirDialog *save_select;
  124. OptionButton *texture_action;
  125. CreateDialog *root_type_choose;
  126. LineEdit *root_node_name;
  127. ConfirmationDialog *confirm_open;
  128. ConfirmationDialog *confirm_import;
  129. RichTextLabel *missing_files;
  130. Vector<TreeItem *> scene_flags;
  131. Map<Ref<Mesh>, Ref<Shape> > collision_map;
  132. ConfirmationDialog *error_dialog;
  133. Button *root_type;
  134. CheckBox *root_default;
  135. void _root_default_pressed();
  136. void _root_type_pressed();
  137. void _set_root_type();
  138. void _choose_file(const String &p_path);
  139. void _choose_save_file(const String &p_path);
  140. void _choose_script(const String &p_path);
  141. void _browse();
  142. void _browse_target();
  143. void _browse_script();
  144. void _import(bool p_and_open = false);
  145. void _import_confirm();
  146. Ref<ResourceImportMetadata> wip_rimd;
  147. Node *wip_import;
  148. String wip_save_file;
  149. bool wip_blocked;
  150. bool wip_open;
  151. void _dialog_hid();
  152. void _open_and_import();
  153. protected:
  154. void _notification(int p_what);
  155. static void _bind_methods();
  156. public:
  157. void setup_popup(const String &p_from, const String &p_to_path) {
  158. _choose_file(p_from);
  159. _choose_save_file(p_to_path);
  160. }
  161. Error import(const String &p_from, const String &p_to, const String &p_preset);
  162. void popup_import(const String &p_from);
  163. EditorSceneImportDialog(EditorNode *p_editor, EditorSceneImportPlugin *p_plugin);
  164. };
  165. ///////////////////////////////////
  166. static const char *anim_flag_names[] = {
  167. "Detect Loop (-loop,-cycle)",
  168. "Keep Value Tracks",
  169. "Optimize",
  170. "Force All Tracks in All Clips",
  171. NULL
  172. };
  173. static const char *anim_flag_descript[] = {
  174. "Set loop flag for animation names that\ncontain 'cycle' or 'loop' in the name.",
  175. "When merging an existing aimation,\nkeep the user-created value-tracks.",
  176. "Remove redundant keyframes in\n transform tacks.",
  177. "Some exporters will rely on default pose for some bones.\nThis forces those bones to have at least one animation key.",
  178. NULL
  179. };
  180. void EditorImportAnimationOptions::set_flags(uint32_t p_flags) {
  181. updating = true;
  182. for (int i = 0; i < items.size(); i++) {
  183. items[i]->set_checked(0, p_flags & (1 << i));
  184. }
  185. updating = false;
  186. }
  187. uint32_t EditorImportAnimationOptions::get_flags() const {
  188. uint32_t f = 0;
  189. for (int i = 0; i < items.size(); i++) {
  190. if (items[i]->is_checked(0))
  191. f |= (1 << i);
  192. }
  193. return f;
  194. }
  195. void EditorImportAnimationOptions::_changed() {
  196. if (updating)
  197. return;
  198. emit_signal("changed");
  199. }
  200. void EditorImportAnimationOptions::_button_action(Object *p_obj, int p_col, int p_id) {
  201. memdelete(p_obj);
  202. }
  203. void EditorImportAnimationOptions::_item_edited() {
  204. if (validating)
  205. return;
  206. if (clips.size() == 0)
  207. return;
  208. validating = true;
  209. print_line("edited");
  210. TreeItem *item = clips_tree->get_edited();
  211. if (item == clips[clips.size() - 1]) {
  212. //add new
  213. print_line("islast");
  214. if (item->get_text(0).find("<") != -1 || item->get_text(0).find(">") != -1) {
  215. validating = false;
  216. return; //fuckit
  217. }
  218. item->set_editable(1, true);
  219. item->set_editable(2, true);
  220. item->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Del", "EditorIcons"));
  221. item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
  222. item->set_range_config(1, 0, 3600, 0.01);
  223. item->set_range(1, 0);
  224. item->set_editable(1, true);
  225. item->set_cell_mode(2, TreeItem::CELL_MODE_RANGE);
  226. item->set_range_config(2, 0, 3600, 0.01);
  227. item->set_range(2, 0);
  228. item->set_cell_mode(3, TreeItem::CELL_MODE_CHECK);
  229. item->set_editable(3, true);
  230. TreeItem *newclip = clips_tree->create_item(clips_base);
  231. newclip->set_text(0, "<new clip>");
  232. newclip->set_editable(0, true);
  233. newclip->set_editable(1, false);
  234. newclip->set_editable(2, false);
  235. clips.push_back(newclip);
  236. }
  237. //make name unique JUST IN CASE
  238. String name = item->get_text(0);
  239. name = name.replace("/", "_").replace(":", "_").strip_edges();
  240. if (name == "")
  241. name = TTR("New Clip");
  242. if (clips.size() > 2) {
  243. int index = 1;
  244. while (true) {
  245. bool valid = true;
  246. String try_name = name;
  247. if (index > 1)
  248. try_name += " " + itos(index);
  249. for (int i = 0; i < clips.size() - 1; i++) {
  250. if (clips[i] == item)
  251. continue;
  252. if (clips[i]->get_text(0) == try_name) {
  253. index++;
  254. valid = false;
  255. break;
  256. }
  257. }
  258. if (valid) {
  259. name = try_name;
  260. break;
  261. }
  262. }
  263. }
  264. if (item->get_text(0) != name)
  265. item->set_text(0, name);
  266. validating = false;
  267. }
  268. void EditorImportAnimationOptions::_bind_methods() {
  269. ObjectTypeDB::bind_method("_changed", &EditorImportAnimationOptions::_changed);
  270. ObjectTypeDB::bind_method("_item_edited", &EditorImportAnimationOptions::_item_edited);
  271. ObjectTypeDB::bind_method("_button_action", &EditorImportAnimationOptions::_button_action);
  272. // ObjectTypeDB::bind_method("_changedp",&EditorImportAnimationOptions::_changedp);
  273. ADD_SIGNAL(MethodInfo("changed"));
  274. }
  275. void EditorImportAnimationOptions::_notification(int p_what) {
  276. if (p_what == NOTIFICATION_ENTER_TREE) {
  277. flags->connect("item_edited", this, "_changed");
  278. clips_tree->connect("item_edited", this, "_item_edited");
  279. clips_tree->connect("button_pressed", this, "_button_action", varray(), CONNECT_DEFERRED);
  280. // format->connect("item_selected",this,"_changedp");
  281. }
  282. }
  283. Array EditorImportAnimationOptions::get_clips() const {
  284. Array arr;
  285. for (int i = 0; i < clips.size() - 1; i++) {
  286. arr.push_back(clips[i]->get_text(0));
  287. arr.push_back(clips[i]->get_range(1));
  288. arr.push_back(clips[i]->get_range(2));
  289. arr.push_back(clips[i]->is_checked(3));
  290. }
  291. return arr;
  292. }
  293. void EditorImportAnimationOptions::setup_clips(const Array &p_clips) {
  294. ERR_FAIL_COND(p_clips.size() % 4 != 0);
  295. for (int i = 0; i < clips.size(); i++) {
  296. memdelete(clips[i]);
  297. }
  298. clips.clear();
  299. for (int i = 0; i < p_clips.size(); i += 4) {
  300. TreeItem *clip = clips_tree->create_item(clips_base);
  301. clip->set_text(0, p_clips[i]);
  302. clip->add_button(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Del", "EditorIcons"));
  303. clip->set_editable(0, true);
  304. clip->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
  305. clip->set_range_config(1, 0, 3600, 0.01);
  306. clip->set_range(1, p_clips[i + 1]);
  307. clip->set_editable(1, true);
  308. clip->set_cell_mode(2, TreeItem::CELL_MODE_RANGE);
  309. clip->set_range_config(2, 0, 3600, 0.01);
  310. clip->set_range(2, p_clips[i + 2]);
  311. clip->set_editable(2, true);
  312. clip->set_cell_mode(3, TreeItem::CELL_MODE_CHECK);
  313. clip->set_editable(3, true);
  314. clip->set_checked(3, p_clips[i + 3]);
  315. clips.push_back(clip);
  316. }
  317. TreeItem *newclip = clips_tree->create_item(clips_base);
  318. newclip->set_text(0, "<new clip>");
  319. newclip->set_editable(0, true);
  320. newclip->set_editable(1, false);
  321. newclip->set_editable(2, false);
  322. newclip->set_editable(3, false);
  323. clips.push_back(newclip);
  324. }
  325. EditorImportAnimationOptions::EditorImportAnimationOptions() {
  326. updating = false;
  327. validating = false;
  328. TabContainer *tab = memnew(TabContainer);
  329. add_margin_child(TTR("Animation Options"), tab, true);
  330. flags = memnew(Tree);
  331. flags->set_hide_root(true);
  332. tab->add_child(flags);
  333. flags->set_name(TTR("Flags"));
  334. TreeItem *root = flags->create_item();
  335. const char **fname = anim_flag_names;
  336. const char **fdescr = anim_flag_descript;
  337. while (*fname) {
  338. TreeItem *ti = flags->create_item(root);
  339. ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  340. ti->set_text(0, *fname);
  341. ti->set_editable(0, true);
  342. ti->set_tooltip(0, *fdescr);
  343. items.push_back(ti);
  344. fname++;
  345. fdescr++;
  346. }
  347. TreeItem *fps_base = flags->create_item(root);
  348. fps_base->set_text(0, TTR("Bake FPS:"));
  349. fps_base->set_editable(0, false);
  350. fps = flags->create_item(fps_base);
  351. fps->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
  352. fps->set_editable(0, true);
  353. fps->set_range_config(0, 1, 120, 1);
  354. fps->set_range(0, 15);
  355. optimization_tree = memnew(Tree);
  356. optimization_tree->set_columns(2);
  357. tab->add_child(optimization_tree);
  358. optimization_tree->set_name(TTR("Optimizer"));
  359. optimization_tree->set_column_expand(0, true);
  360. optimization_tree->set_column_expand(1, false);
  361. optimization_tree->set_column_min_width(1, 80);
  362. optimization_tree->set_hide_root(true);
  363. TreeItem *optimize_root = optimization_tree->create_item();
  364. optimize_linear_error = optimization_tree->create_item(optimize_root);
  365. optimize_linear_error->set_text(0, TTR("Max Linear Error"));
  366. optimize_linear_error->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
  367. optimize_linear_error->set_editable(1, true);
  368. optimize_linear_error->set_range_config(1, 0, 1, 0.001);
  369. optimize_linear_error->set_range(1, 0.05);
  370. optimize_angular_error = optimization_tree->create_item(optimize_root);
  371. optimize_angular_error->set_text(0, TTR("Max Angular Error"));
  372. optimize_angular_error->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
  373. optimize_angular_error->set_editable(1, true);
  374. optimize_angular_error->set_range_config(1, 0, 1, 0.001);
  375. optimize_angular_error->set_range(1, 0.01);
  376. optimize_max_angle = optimization_tree->create_item(optimize_root);
  377. optimize_max_angle->set_text(0, TTR("Max Angle"));
  378. optimize_max_angle->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
  379. optimize_max_angle->set_editable(1, true);
  380. optimize_max_angle->set_range_config(1, 0, 360, 0.001);
  381. optimize_max_angle->set_range(1, int(180 * 0.125));
  382. clips_tree = memnew(Tree);
  383. clips_tree->set_hide_root(true);
  384. tab->add_child(clips_tree);
  385. clips_tree->set_name(TTR("Clips"));
  386. clips_tree->set_columns(4);
  387. clips_tree->set_column_expand(0, 1);
  388. clips_tree->set_column_expand(1, 0);
  389. clips_tree->set_column_expand(2, 0);
  390. clips_tree->set_column_expand(3, 0);
  391. clips_tree->set_column_min_width(1, 60);
  392. clips_tree->set_column_min_width(2, 60);
  393. clips_tree->set_column_min_width(3, 40);
  394. clips_tree->set_column_titles_visible(true);
  395. clips_tree->set_column_title(0, TTR("Name"));
  396. clips_tree->set_column_title(1, TTR("Start(s)"));
  397. clips_tree->set_column_title(2, TTR("End(s)"));
  398. clips_tree->set_column_title(3, TTR("Loop"));
  399. clips_base = clips_tree->create_item(0);
  400. setup_clips(Array());
  401. filters = memnew(TextEdit);
  402. tab->add_child(filters);
  403. filters->set_name(TTR("Filters"));
  404. }
  405. void EditorImportAnimationOptions::set_fps(int p_fps) {
  406. fps->set_range(0, p_fps);
  407. }
  408. int EditorImportAnimationOptions::get_fps() const {
  409. return fps->get_range(0);
  410. }
  411. void EditorImportAnimationOptions::set_optimize_linear_error(float p_optimize_linear_error) {
  412. optimize_linear_error->set_range(1, p_optimize_linear_error);
  413. }
  414. float EditorImportAnimationOptions::get_optimize_linear_error() const {
  415. return optimize_linear_error->get_range(1);
  416. }
  417. void EditorImportAnimationOptions::set_optimize_angular_error(float p_optimize_angular_error) {
  418. optimize_angular_error->set_range(1, p_optimize_angular_error);
  419. }
  420. float EditorImportAnimationOptions::get_optimize_angular_error() const {
  421. return optimize_angular_error->get_range(1);
  422. }
  423. void EditorImportAnimationOptions::set_optimize_max_angle(float p_optimize_max_angle) {
  424. optimize_max_angle->set_range(1, p_optimize_max_angle);
  425. }
  426. float EditorImportAnimationOptions::get_optimize_max_angle() const {
  427. return optimize_max_angle->get_range(1);
  428. }
  429. void EditorImportAnimationOptions::set_filter(const String &p_filter) {
  430. filters->set_text(p_filter);
  431. }
  432. String EditorImportAnimationOptions::get_filter() const {
  433. return filters->get_text();
  434. }
  435. ////////////////////////////////////////////////////////
  436. void EditorSceneImportDialog::_choose_file(const String &p_path) {
  437. #if 0
  438. StringName sn = EditorImportDB::get_singleton()->find_source_path(p_path);
  439. if (sn!=StringName()) {
  440. EditorImportDB::ImportScene isc;
  441. if (EditorImportDB::get_singleton()->get_scene(sn,isc)==OK) {
  442. save_path->set_text(String(sn).get_base_dir());
  443. texture_options->set_flags( isc.image_flags );
  444. texture_options->set_quality( isc.image_quality );
  445. texture_options->set_format( isc.image_format );
  446. animation_options->set_flags( isc.anim_flags );
  447. script_path->set_text( isc.import_script );
  448. uint32_t f = isc.flags;
  449. for(int i=0;i<scene_flags.size();i++) {
  450. scene_flags[i]->set_checked(0,f&(1<<i));
  451. }
  452. }
  453. } else {
  454. #endif
  455. save_path->set_text("");
  456. root_node_name->set_text("");
  457. //save_path->set_text(p_path.get_file().basename()+".scn");
  458. #if 0
  459. }
  460. #endif
  461. if (p_path != String()) {
  462. String from_path = EditorFileSystem::get_singleton()->find_resource_from_source(EditorImportPlugin::validate_source_path(p_path));
  463. print_line("from path.." + from_path);
  464. if (from_path != String()) {
  465. popup_import(from_path);
  466. }
  467. }
  468. import_path->set_text(p_path);
  469. if (root_node_name->get_text().size() == 0) {
  470. root_node_name->set_text(import_path->get_text().get_file().basename());
  471. }
  472. }
  473. void EditorSceneImportDialog::_choose_save_file(const String &p_path) {
  474. save_path->set_text(p_path);
  475. }
  476. void EditorSceneImportDialog::_choose_script(const String &p_path) {
  477. String p = Globals::get_singleton()->localize_path(p_path);
  478. if (!p.is_resource_file())
  479. p = Globals::get_singleton()->get_resource_path().path_to(p_path.get_base_dir()) + p_path.get_file();
  480. script_path->set_text(p);
  481. }
  482. void EditorSceneImportDialog::_open_and_import() {
  483. bool unsaved = EditorNode::has_unsaved_changes();
  484. if (unsaved) {
  485. confirm_open->popup_centered_minsize(Size2(300, 80) * EDSCALE);
  486. } else {
  487. _import(true);
  488. }
  489. }
  490. void EditorSceneImportDialog::_import(bool p_and_open) {
  491. wip_open = p_and_open;
  492. //' ImportMonitorBlock imb;
  493. if (import_path->get_text().strip_edges() == "") {
  494. error_dialog->set_text(TTR("Source path is empty."));
  495. error_dialog->popup_centered_minsize();
  496. return;
  497. }
  498. if (save_path->get_text().strip_edges() == "") {
  499. error_dialog->set_text(TTR("Target path is empty."));
  500. error_dialog->popup_centered_minsize();
  501. return;
  502. }
  503. if (!save_path->get_text().begins_with("res://")) {
  504. error_dialog->set_text(TTR("Target path must be a complete resource path."));
  505. error_dialog->popup_centered_minsize();
  506. return;
  507. }
  508. if (!DirAccess::exists(save_path->get_text())) {
  509. error_dialog->set_text(TTR("Target path must exist."));
  510. error_dialog->popup_centered_minsize();
  511. return;
  512. }
  513. uint32_t flags = 0;
  514. for (int i = 0; i < scene_flags.size(); i++) {
  515. if (scene_flags[i]->is_checked(0)) {
  516. int md = scene_flags[i]->get_metadata(0);
  517. flags |= md;
  518. }
  519. }
  520. if (script_path->get_text() != "") {
  521. Ref<Script> scr = ResourceLoader::load(script_path->get_text());
  522. if (!scr.is_valid()) {
  523. error_dialog->set_text(TTR("Couldn't load post-import script."));
  524. error_dialog->popup_centered(Size2(200, 100) * EDSCALE);
  525. return;
  526. }
  527. Ref<EditorScenePostImport> pi = Ref<EditorScenePostImport>(memnew(EditorScenePostImport));
  528. pi->set_script(scr.get_ref_ptr());
  529. if (!pi->get_script_instance()) {
  530. error_dialog->set_text(TTR("Invalid/broken script for post-import."));
  531. error_dialog->popup_centered(Size2(200, 100) * EDSCALE);
  532. return;
  533. }
  534. }
  535. // Scenes should always be imported as binary format since vertex data is large and would take
  536. // up a lot of space and time to load if imported as text format (GH-5778)
  537. String save_file = save_path->get_text().plus_file(import_path->get_text().get_file().basename() + ".scn");
  538. print_line("Saving to: " + save_file);
  539. Node *scene = NULL;
  540. Ref<ResourceImportMetadata> rim = memnew(ResourceImportMetadata);
  541. rim->add_source(EditorImportPlugin::validate_source_path(import_path->get_text()));
  542. rim->set_option("flags", flags);
  543. print_line("GET FLAGS: " + itos(texture_options->get_flags()));
  544. rim->set_option("texture_flags", texture_options->get_flags());
  545. rim->set_option("texture_format", texture_options->get_format());
  546. rim->set_option("texture_quality", texture_options->get_quality());
  547. rim->set_option("texture_action", texture_action->get_selected());
  548. rim->set_option("animation_flags", animation_options->get_flags());
  549. rim->set_option("animation_bake_fps", animation_options->get_fps());
  550. rim->set_option("animation_optimizer_linear_error", animation_options->get_optimize_linear_error());
  551. rim->set_option("animation_optimizer_angular_error", animation_options->get_optimize_angular_error());
  552. rim->set_option("animation_optimizer_max_angle", animation_options->get_optimize_max_angle());
  553. rim->set_option("animation_filters", animation_options->get_filter());
  554. rim->set_option("animation_clips", animation_options->get_clips());
  555. rim->set_option("post_import_script", script_path->get_text());
  556. rim->set_option("reimport", true);
  557. if (!root_default->is_pressed()) {
  558. rim->set_option("root_type", root_type->get_text());
  559. }
  560. if (root_node_name->get_text().size() == 0) {
  561. root_node_name->set_text(import_path->get_text().get_file().basename());
  562. }
  563. rim->set_option("root_name", root_node_name->get_text());
  564. List<String> missing;
  565. Error err = plugin->import1(rim, &scene, &missing);
  566. if (err || !scene) {
  567. error_dialog->set_text(TTR("Error importing scene."));
  568. error_dialog->popup_centered(Size2(200, 100) * EDSCALE);
  569. return;
  570. }
  571. if (missing.size()) {
  572. missing_files->clear();
  573. for (List<String>::Element *E = missing.front(); E; E = E->next()) {
  574. missing_files->add_text(E->get());
  575. missing_files->add_newline();
  576. }
  577. wip_import = scene;
  578. wip_rimd = rim;
  579. wip_save_file = save_file;
  580. confirm_import->popup_centered_ratio();
  581. return;
  582. } else {
  583. err = plugin->import2(scene, save_file, rim);
  584. if (err) {
  585. error_dialog->set_text(TTR("Error importing scene."));
  586. error_dialog->popup_centered(Size2(200, 100) * EDSCALE);
  587. return;
  588. }
  589. if (wip_open)
  590. EditorNode::get_singleton()->load_scene(save_file, false, false, false);
  591. }
  592. hide();
  593. /*
  594. editor->clear_scene();
  595. Error err = EditorImport::import_scene(import_path->get_text(),save_file,dst_path,flags,texture_options->get_format(),compression,texture_options->get_flags(),texture_options->get_quality(),animation_options->get_flags(), &scene,pi);
  596. if (err) {
  597. error_dialog->set_text("Error importing scene.");
  598. error_dialog->popup_centered(Size2(200,100));
  599. return;
  600. }
  601. editor->save_import_export();
  602. if (scene)
  603. editor->set_edited_scene(scene);
  604. hide();
  605. */
  606. };
  607. void EditorSceneImportDialog::_import_confirm() {
  608. wip_blocked = true;
  609. print_line("import confirm!");
  610. Error err = plugin->import2(wip_import, wip_save_file, wip_rimd);
  611. wip_blocked = false;
  612. wip_import = NULL;
  613. wip_rimd = Ref<ResourceImportMetadata>();
  614. confirm_import->hide();
  615. if (err) {
  616. wip_save_file = "";
  617. error_dialog->set_text(TTR("Error importing scene."));
  618. error_dialog->popup_centered(Size2(200, 100) * EDSCALE);
  619. return;
  620. }
  621. if (wip_open)
  622. EditorNode::get_singleton()->load_scene(wip_save_file, false, false, false);
  623. wip_open = false;
  624. wip_save_file = "";
  625. hide();
  626. }
  627. void EditorSceneImportDialog::_browse() {
  628. file_select->popup_centered_ratio();
  629. }
  630. void EditorSceneImportDialog::_browse_target() {
  631. save_select->popup_centered_ratio();
  632. if (save_path->get_text() != "")
  633. save_select->set_current_path(save_path->get_text());
  634. }
  635. void EditorSceneImportDialog::_browse_script() {
  636. script_select->popup_centered_ratio();
  637. }
  638. void EditorSceneImportDialog::popup_import(const String &p_from) {
  639. popup_centered(Size2(750, 550) * EDSCALE);
  640. if (p_from != "") {
  641. Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from);
  642. if (rimd.is_null())
  643. return;
  644. int flags = rimd->get_option("flags");
  645. for (int i = 0; i < scene_flags.size(); i++) {
  646. int md = scene_flags[i]->get_metadata(0);
  647. scene_flags[i]->set_checked(0, flags & md);
  648. }
  649. texture_options->set_flags(rimd->get_option("texture_flags"));
  650. texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("texture_format"))));
  651. texture_options->set_quality(rimd->get_option("texture_quality"));
  652. texture_action->select(rimd->get_option("texture_action"));
  653. animation_options->set_flags(rimd->get_option("animation_flags"));
  654. if (rimd->has_option("animation_clips"))
  655. animation_options->setup_clips(rimd->get_option("animation_clips"));
  656. if (rimd->has_option("animation_filters"))
  657. animation_options->set_filter(rimd->get_option("animation_filters"));
  658. if (rimd->has_option("animation_bake_fps"))
  659. animation_options->set_fps(rimd->get_option("animation_bake_fps"));
  660. if (rimd->has_option("animation_optimizer_linear_error"))
  661. animation_options->set_optimize_linear_error(rimd->get_option("animation_optimizer_linear_error"));
  662. if (rimd->has_option("animation_optimizer_angular_error"))
  663. animation_options->set_optimize_angular_error(rimd->get_option("animation_optimizer_angular_error"));
  664. if (rimd->has_option("animation_optimizer_max_angle"))
  665. animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle"));
  666. if (rimd->has_option("root_type")) {
  667. root_default->set_pressed(false);
  668. String type = rimd->get_option("root_type");
  669. root_type->set_text(type);
  670. root_type->set_disabled(false);
  671. if (has_icon(type, "EditorIcons")) {
  672. root_type->set_icon(get_icon(type, "EditorIcons"));
  673. } else {
  674. root_type->set_icon(get_icon("Object", "EditorIcons"));
  675. }
  676. } else {
  677. root_default->set_pressed(true);
  678. root_type->set_disabled(true);
  679. }
  680. if (rimd->has_option("root_name")) {
  681. root_node_name->set_text(rimd->get_option("root_name"));
  682. } else {
  683. root_node_name->set_text(root_type->get_text()); // backward compatibility for 2.1 or before
  684. }
  685. script_path->set_text(rimd->get_option("post_import_script"));
  686. save_path->set_text(p_from.get_base_dir());
  687. import_path->set_text(EditorImportPlugin::expand_source_path(rimd->get_source_path(0)));
  688. }
  689. }
  690. void EditorSceneImportDialog::_notification(int p_what) {
  691. if (p_what == NOTIFICATION_ENTER_TREE) {
  692. List<String> extensions;
  693. file_select->clear_filters();
  694. root_type->set_icon(get_icon("Spatial", "EditorIcons"));
  695. root_type->set_text("Spatial");
  696. root_type->set_disabled(true);
  697. for (int i = 0; i < plugin->get_importers().size(); i++) {
  698. plugin->get_importers()[i]->get_extensions(&extensions);
  699. }
  700. for (int i = 0; i < extensions.size(); i++) {
  701. file_select->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
  702. }
  703. extensions.clear();
  704. //EditorImport::get_import_extensions(&extensions)
  705. /* ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
  706. save_select->clear_filters();
  707. for(int i=0;i<extensions.size();i++) {
  708. save_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
  709. }*/
  710. }
  711. }
  712. Error EditorSceneImportDialog::import(const String &p_from, const String &p_to, const String &p_preset) {
  713. import_path->set_text(p_from);
  714. save_path->set_text(p_to);
  715. script_path->set_text(p_preset);
  716. _import();
  717. return OK;
  718. }
  719. void EditorSceneImportDialog::_dialog_hid() {
  720. if (wip_blocked)
  721. return;
  722. print_line("DIALOGHID!");
  723. if (wip_import) {
  724. memdelete(wip_import);
  725. wip_import = NULL;
  726. wip_save_file = "";
  727. wip_rimd = Ref<ResourceImportMetadata>();
  728. }
  729. }
  730. void EditorSceneImportDialog::_root_default_pressed() {
  731. root_type->set_disabled(root_default->is_pressed());
  732. }
  733. void EditorSceneImportDialog::_root_type_pressed() {
  734. root_type_choose->popup(false);
  735. }
  736. void EditorSceneImportDialog::_set_root_type() {
  737. String type = root_type_choose->get_selected_type();
  738. if (type == String())
  739. return;
  740. root_type->set_text(type);
  741. if (has_icon(type, "EditorIcons")) {
  742. root_type->set_icon(get_icon(type, "EditorIcons"));
  743. } else {
  744. root_type->set_icon(get_icon("Object", "EditorIcons"));
  745. }
  746. }
  747. void EditorSceneImportDialog::_bind_methods() {
  748. ObjectTypeDB::bind_method("_choose_file", &EditorSceneImportDialog::_choose_file);
  749. ObjectTypeDB::bind_method("_choose_save_file", &EditorSceneImportDialog::_choose_save_file);
  750. ObjectTypeDB::bind_method("_choose_script", &EditorSceneImportDialog::_choose_script);
  751. ObjectTypeDB::bind_method("_import", &EditorSceneImportDialog::_import, DEFVAL(false));
  752. ObjectTypeDB::bind_method("_browse", &EditorSceneImportDialog::_browse);
  753. ObjectTypeDB::bind_method("_browse_target", &EditorSceneImportDialog::_browse_target);
  754. ObjectTypeDB::bind_method("_browse_script", &EditorSceneImportDialog::_browse_script);
  755. ObjectTypeDB::bind_method("_dialog_hid", &EditorSceneImportDialog::_dialog_hid);
  756. ObjectTypeDB::bind_method("_import_confirm", &EditorSceneImportDialog::_import_confirm);
  757. ObjectTypeDB::bind_method("_open_and_import", &EditorSceneImportDialog::_open_and_import);
  758. ObjectTypeDB::bind_method("_root_default_pressed", &EditorSceneImportDialog::_root_default_pressed);
  759. ObjectTypeDB::bind_method("_root_type_pressed", &EditorSceneImportDialog::_root_type_pressed);
  760. ObjectTypeDB::bind_method("_set_root_type", &EditorSceneImportDialog::_set_root_type);
  761. ADD_SIGNAL(MethodInfo("imported", PropertyInfo(Variant::OBJECT, "scene")));
  762. }
  763. const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[] = {
  764. { EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP, ("Actions"), "Remove Nodes (-noimp)", true },
  765. { EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS, ("Actions"), "Import Animations", true },
  766. { EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY, ("Actions"), "Compress Geometry", false },
  767. { EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS, ("Actions"), "Force Generation of Tangent Arrays", false },
  768. { EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES, ("Actions"), "SRGB->Linear Of Diffuse Textures", false },
  769. { EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY, ("Actions"), "Convert Normal Maps to XY", true },
  770. { EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS, ("Actions"), "Set Material Lightmap to UV2 if Tex2Array Exists", true },
  771. { EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_MATERIALS, ("Merge"), "Keep Materials after first import (delete them for re-import).", true },
  772. { EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS, ("Merge"), "Keep user-added Animation tracks.", true },
  773. { EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA, ("Materials"), "Set Alpha in Materials (-alpha)", true },
  774. { EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR, ("Materials"), "Set Vert. Color in Materials (-vcol)", true },
  775. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS, ("Create"), "Create Collisions and/or Rigid Bodies (-col,-colonly,-rigid,-rigidonly)", true },
  776. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS, ("Create"), "Create Portals (-portal)", true },
  777. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS, ("Create"), "Create Rooms (-room)", true },
  778. { EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS, ("Create"), "Simplify Rooms", false },
  779. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS, ("Create"), "Create Billboards (-bb)", true },
  780. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS, ("Create"), "Create Impostors (-imp:dist)", true },
  781. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS, ("Create"), "Create LODs (-lod:dist)", true },
  782. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS, ("Create"), "Create Vehicles (-vehicle)", true },
  783. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS, ("Create"), "Create Vehicle Wheels (-wheel)", true },
  784. { EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH, ("Create"), "Create Navigation Meshes (-navmesh)", true },
  785. { EditorSceneImportPlugin::SCENE_FLAG_DETECT_LIGHTMAP_LAYER, ("Create"), "Detect LightMap Layer (-lm:<int>).", true },
  786. { -1, NULL, NULL, false }
  787. };
  788. EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSceneImportPlugin *p_plugin) {
  789. editor = p_editor;
  790. plugin = p_plugin;
  791. set_title(TTR("Import 3D Scene"));
  792. HBoxContainer *import_hb = memnew(HBoxContainer);
  793. add_child(import_hb);
  794. set_child_rect(import_hb);
  795. VBoxContainer *vbc = memnew(VBoxContainer);
  796. import_hb->add_child(vbc);
  797. vbc->set_h_size_flags(SIZE_EXPAND_FILL);
  798. HBoxContainer *hbc = memnew(HBoxContainer);
  799. vbc->add_margin_child(TTR("Source Scene:"), hbc);
  800. import_path = memnew(LineEdit);
  801. import_path->set_h_size_flags(SIZE_EXPAND_FILL);
  802. hbc->add_child(import_path);
  803. Button *import_choose = memnew(Button);
  804. import_choose->set_text(" .. ");
  805. hbc->add_child(import_choose);
  806. import_choose->connect("pressed", this, "_browse");
  807. hbc = memnew(HBoxContainer);
  808. vbc->add_margin_child(TTR("Target Path:"), hbc);
  809. save_path = memnew(LineEdit);
  810. save_path->set_h_size_flags(SIZE_EXPAND_FILL);
  811. hbc->add_child(save_path);
  812. Button *save_choose = memnew(Button);
  813. save_choose->set_text(" .. ");
  814. hbc->add_child(save_choose);
  815. save_choose->connect("pressed", this, "_browse_target");
  816. import_options = memnew(Tree);
  817. vbc->set_v_size_flags(SIZE_EXPAND_FILL);
  818. vbc->add_margin_child(TTR("Options:"), import_options, true);
  819. file_select = memnew(EditorFileDialog);
  820. file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
  821. add_child(file_select);
  822. file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE);
  823. file_select->connect("file_selected", this, "_choose_file");
  824. save_select = memnew(EditorDirDialog);
  825. add_child(save_select);
  826. //save_select->set_mode(EditorFileDialog::MODE_SAVE_FILE);
  827. save_select->connect("dir_selected", this, "_choose_save_file");
  828. get_ok()->connect("pressed", this, "_import");
  829. get_ok()->set_text(TTR("Import"));
  830. TreeItem *root = import_options->create_item(NULL);
  831. import_options->set_hide_root(true);
  832. const FlagInfo *fn = scene_flag_names;
  833. Map<String, TreeItem *> categories;
  834. while (fn->text) {
  835. String cat = fn->category;
  836. TreeItem *parent;
  837. if (!categories.has(cat)) {
  838. parent = import_options->create_item(root);
  839. parent->set_text(0, cat);
  840. categories[cat] = parent;
  841. } else {
  842. parent = categories[cat];
  843. }
  844. TreeItem *opt = import_options->create_item(parent);
  845. opt->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
  846. opt->set_checked(0, fn->defval);
  847. opt->set_editable(0, true);
  848. opt->set_text(0, fn->text);
  849. opt->set_metadata(0, fn->value);
  850. scene_flags.push_back(opt);
  851. fn++;
  852. }
  853. hbc = memnew(HBoxContainer);
  854. vbc->add_margin_child(TTR("Post-Process Script:"), hbc);
  855. script_path = memnew(LineEdit);
  856. script_path->set_h_size_flags(SIZE_EXPAND_FILL);
  857. hbc->add_child(script_path);
  858. Button *script_choose = memnew(Button);
  859. script_choose->set_text(" .. ");
  860. hbc->add_child(script_choose);
  861. script_choose->connect("pressed", this, "_browse_script");
  862. script_select = memnew(EditorFileDialog);
  863. add_child(script_select);
  864. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  865. ScriptLanguage *sl = ScriptServer::get_language(i);
  866. String ext = sl->get_extension();
  867. if (ext == "")
  868. continue;
  869. script_select->add_filter("*." + ext + " ; " + sl->get_name());
  870. }
  871. script_select->set_mode(EditorFileDialog::MODE_OPEN_FILE);
  872. script_select->connect("file_selected", this, "_choose_script");
  873. error_dialog = memnew(ConfirmationDialog);
  874. add_child(error_dialog);
  875. error_dialog->get_ok()->set_text(TTR("Accept"));
  876. // error_dialog->get_cancel()->hide();
  877. HBoxContainer *custom_root_hb = memnew(HBoxContainer);
  878. vbc->add_margin_child(TTR("Custom Root Node Type:"), custom_root_hb);
  879. root_type = memnew(Button);
  880. root_type->set_h_size_flags(SIZE_EXPAND_FILL);
  881. root_type->set_text_align(Button::ALIGN_LEFT);
  882. root_type->connect("pressed", this, "_root_type_pressed");
  883. custom_root_hb->add_child(root_type);
  884. root_default = memnew(CheckBox);
  885. root_default->set_text(TTR("Auto"));
  886. root_default->set_pressed(true);
  887. root_default->connect("pressed", this, "_root_default_pressed");
  888. custom_root_hb->add_child(root_default);
  889. root_node_name = memnew(LineEdit);
  890. root_node_name->set_h_size_flags(SIZE_EXPAND_FILL);
  891. vbc->add_margin_child(TTR("Root Node Name:"), root_node_name);
  892. /*
  893. this_import = memnew( OptionButton );
  894. this_import->add_item("Overwrite Existing Scene");
  895. this_import->add_item("Overwrite Existing, Keep Materials");
  896. this_import->add_item("Keep Existing, Merge with New");
  897. this_import->add_item("Keep Existing, Ignore New");
  898. vbc->add_margin_child("This Time:",this_import);
  899. next_import = memnew( OptionButton );
  900. next_import->add_item("Overwrite Existing Scene");
  901. next_import->add_item("Overwrite Existing, Keep Materials");
  902. next_import->add_item("Keep Existing, Merge with New");
  903. next_import->add_item("Keep Existing, Ignore New");
  904. vbc->add_margin_child("Next Time:",next_import);
  905. */
  906. set_hide_on_ok(false);
  907. GLOBAL_DEF("editor/import_shared_textures", "res://");
  908. Globals::get_singleton()->set_custom_property_info("editor/import_shared_textures", PropertyInfo(Variant::STRING, "editor/import_shared_textures", PROPERTY_HINT_DIR));
  909. import_hb->add_constant_override("separation", 30);
  910. VBoxContainer *ovb = memnew(VBoxContainer);
  911. ovb->set_h_size_flags(SIZE_EXPAND_FILL);
  912. import_hb->add_child(ovb);
  913. texture_action = memnew(OptionButton);
  914. texture_action->add_item(TTR("Import to Target Scene Folder"));
  915. texture_action->add_item(TTR("Import to Shared Textures Folder"));
  916. texture_action->add_item(TTR("Import to Source Folder"));
  917. texture_action->add_item(TTR("Reuse Source Textures"));
  918. texture_action->select(0);
  919. ovb->add_margin_child(TTR("Texture Action"), texture_action);
  920. texture_options = memnew(EditorImportTextureOptions);
  921. ovb->add_child(texture_options);
  922. texture_options->set_v_size_flags(SIZE_EXPAND_FILL);
  923. //animation_options->set_flags(EditorImport::
  924. texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM);
  925. texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA | EditorTextureImportPlugin::IMAGE_FLAG_REPEAT | EditorTextureImportPlugin::IMAGE_FLAG_FILTER);
  926. animation_options = memnew(EditorImportAnimationOptions);
  927. ovb->add_child(animation_options);
  928. animation_options->set_v_size_flags(SIZE_EXPAND_FILL);
  929. animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP | EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS | EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE | EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
  930. confirm_import = memnew(ConfirmationDialog);
  931. add_child(confirm_import);
  932. VBoxContainer *cvb = memnew(VBoxContainer);
  933. confirm_import->add_child(cvb);
  934. confirm_import->set_child_rect(cvb);
  935. PanelContainer *pc = memnew(PanelContainer);
  936. pc->add_style_override("panel", get_stylebox("normal", "TextEdit"));
  937. //ec->add_child(pc);
  938. missing_files = memnew(RichTextLabel);
  939. cvb->add_margin_child(TTR("The Following Files are Missing:"), pc, true);
  940. pc->add_child(missing_files);
  941. confirm_import->get_ok()->set_text(TTR("Import Anyway"));
  942. confirm_import->get_cancel()->set_text(TTR("Cancel"));
  943. confirm_import->connect("popup_hide", this, "_dialog_hid");
  944. confirm_import->connect("confirmed", this, "_import_confirm");
  945. confirm_import->set_hide_on_ok(false);
  946. add_button(TTR("Import & Open"), !OS::get_singleton()->get_swap_ok_cancel())->connect("pressed", this, "_open_and_import");
  947. confirm_open = memnew(ConfirmationDialog);
  948. add_child(confirm_open);
  949. confirm_open->set_text(TTR("Edited scene has not been saved, open imported scene anyway?"));
  950. confirm_open->connect("confirmed", this, "_import", varray(true));
  951. wip_import = NULL;
  952. wip_blocked = false;
  953. wip_open = false;
  954. //texture_options->set_format(EditorImport::IMAGE_FORMAT_C);
  955. root_type_choose = memnew(CreateDialog);
  956. add_child(root_type_choose);
  957. root_type_choose->set_base_type("Node");
  958. root_type_choose->connect("create", this, "_set_root_type");
  959. }
  960. ////////////////////////////////
  961. String EditorSceneImportPlugin::get_name() const {
  962. return "scene_3d";
  963. }
  964. String EditorSceneImportPlugin::get_visible_name() const {
  965. return TTR("Scene");
  966. }
  967. void EditorSceneImportPlugin::import_dialog(const String &p_from) {
  968. dialog->popup_import(p_from);
  969. }
  970. //////////////////////////
  971. static bool _teststr(const String &p_what, const String &p_str) {
  972. if (p_what.findn("$" + p_str) != -1) //blender and other stuff
  973. return true;
  974. if (p_what.to_lower().ends_with("-" + p_str)) //collada only supports "_" and "-" besides letters
  975. return true;
  976. if (p_what.to_lower().ends_with("_" + p_str)) //collada only supports "_" and "-" besides letters
  977. return true;
  978. return false;
  979. }
  980. static String _fixstr(const String &p_what, const String &p_str) {
  981. if (p_what.findn("$" + p_str) != -1) //blender and other stuff
  982. return p_what.replace("$" + p_str, "");
  983. if (p_what.to_lower().ends_with("-" + p_str)) //collada only supports "_" and "-" besides letters
  984. return p_what.substr(0, p_what.length() - (p_str.length() + 1));
  985. if (p_what.to_lower().ends_with("_" + p_str)) //collada only supports "_" and "-" besides letters
  986. return p_what.substr(0, p_what.length() - (p_str.length() + 1));
  987. return p_what;
  988. }
  989. void EditorSceneImportPlugin::_find_resources(const Variant &p_var, Map<Ref<ImageTexture>, TextureRole> &image_map, int p_flags) {
  990. switch (p_var.get_type()) {
  991. case Variant::OBJECT: {
  992. Ref<Resource> res = p_var;
  993. if (res.is_valid()) {
  994. if (res->is_type("Texture") && !image_map.has(res)) {
  995. image_map.insert(res, TEXTURE_ROLE_DEFAULT);
  996. } else {
  997. List<PropertyInfo> pl;
  998. res->get_property_list(&pl);
  999. for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
  1000. if (E->get().type == Variant::OBJECT || E->get().type == Variant::ARRAY || E->get().type == Variant::DICTIONARY) {
  1001. if (E->get().type == Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name == "textures/diffuse" || E->get().name == "textures/detail" || E->get().name == "textures/emission")) {
  1002. Ref<ImageTexture> tex = res->get(E->get().name);
  1003. if (tex.is_valid()) {
  1004. image_map.insert(tex, TEXTURE_ROLE_DIFFUSE);
  1005. }
  1006. } else if (E->get().type == Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name == "textures/normal")) {
  1007. Ref<ImageTexture> tex = res->get(E->get().name);
  1008. if (tex.is_valid()) {
  1009. image_map.insert(tex, TEXTURE_ROLE_NORMALMAP);
  1010. if (p_flags & SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY)
  1011. res->cast_to<FixedMaterial>()->set_fixed_flag(FixedMaterial::FLAG_USE_XY_NORMALMAP, true);
  1012. }
  1013. } else {
  1014. _find_resources(res->get(E->get().name), image_map, p_flags);
  1015. }
  1016. }
  1017. }
  1018. }
  1019. }
  1020. } break;
  1021. case Variant::DICTIONARY: {
  1022. Dictionary d = p_var;
  1023. List<Variant> keys;
  1024. d.get_key_list(&keys);
  1025. for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
  1026. _find_resources(E->get(), image_map, p_flags);
  1027. _find_resources(d[E->get()], image_map, p_flags);
  1028. }
  1029. } break;
  1030. case Variant::ARRAY: {
  1031. Array a = p_var;
  1032. for (int i = 0; i < a.size(); i++) {
  1033. _find_resources(a[i], image_map, p_flags);
  1034. }
  1035. } break;
  1036. }
  1037. }
  1038. Node *EditorSceneImportPlugin::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, Ref<Shape> > &collision_map, uint32_t p_flags, Map<Ref<ImageTexture>, TextureRole> &image_map) {
  1039. // children first..
  1040. for (int i = 0; i < p_node->get_child_count(); i++) {
  1041. Node *r = _fix_node(p_node->get_child(i), p_root, collision_map, p_flags, image_map);
  1042. if (!r) {
  1043. print_line("was erased..");
  1044. i--; //was erased
  1045. }
  1046. }
  1047. String name = p_node->get_name();
  1048. bool isroot = p_node == p_root;
  1049. if (!isroot && p_flags & SCENE_FLAG_REMOVE_NOIMP && _teststr(name, "noimp")) {
  1050. memdelete(p_node);
  1051. return NULL;
  1052. }
  1053. {
  1054. List<PropertyInfo> pl;
  1055. p_node->get_property_list(&pl);
  1056. for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
  1057. if (E->get().type == Variant::OBJECT || E->get().type == Variant::ARRAY || E->get().type == Variant::DICTIONARY) {
  1058. _find_resources(p_node->get(E->get().name), image_map, p_flags);
  1059. }
  1060. }
  1061. }
  1062. if (p_flags & SCENE_FLAG_CREATE_BILLBOARDS && p_node->cast_to<MeshInstance>()) {
  1063. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1064. bool bb = false;
  1065. if ((_teststr(name, "bb"))) {
  1066. bb = true;
  1067. } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(), "bb"))) {
  1068. bb = true;
  1069. }
  1070. if (bb) {
  1071. mi->set_flag(GeometryInstance::FLAG_BILLBOARD, true);
  1072. if (mi->get_mesh().is_valid()) {
  1073. Ref<Mesh> m = mi->get_mesh();
  1074. for (int i = 0; i < m->get_surface_count(); i++) {
  1075. Ref<FixedMaterial> fm = m->surface_get_material(i);
  1076. if (fm.is_valid()) {
  1077. fm->set_flag(Material::FLAG_UNSHADED, true);
  1078. fm->set_flag(Material::FLAG_DOUBLE_SIDED, true);
  1079. fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
  1080. fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
  1081. }
  1082. }
  1083. }
  1084. }
  1085. }
  1086. if (p_flags & (SCENE_FLAG_DETECT_ALPHA | SCENE_FLAG_DETECT_VCOLOR | SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS) && p_node->cast_to<MeshInstance>()) {
  1087. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1088. Ref<Mesh> m = mi->get_mesh();
  1089. if (m.is_valid()) {
  1090. for (int i = 0; i < m->get_surface_count(); i++) {
  1091. Ref<FixedMaterial> mat = m->surface_get_material(i);
  1092. if (!mat.is_valid())
  1093. continue;
  1094. if (p_flags & SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(), "alpha")) {
  1095. mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
  1096. mat->set_name(_fixstr(mat->get_name(), "alpha"));
  1097. }
  1098. if (p_flags & SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(), "vcol")) {
  1099. mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
  1100. mat->set_name(_fixstr(mat->get_name(), "vcol"));
  1101. }
  1102. if (p_flags & SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS && m->surface_get_format(i) & Mesh::ARRAY_FORMAT_TEX_UV2) {
  1103. mat->set_flag(Material::FLAG_LIGHTMAP_ON_UV2, true);
  1104. }
  1105. }
  1106. }
  1107. }
  1108. if (p_flags & SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) {
  1109. //remove animations referencing non-importable nodes
  1110. AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();
  1111. List<StringName> anims;
  1112. ap->get_animation_list(&anims);
  1113. for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
  1114. Ref<Animation> anim = ap->get_animation(E->get());
  1115. ERR_CONTINUE(anim.is_null());
  1116. for (int i = 0; i < anim->get_track_count(); i++) {
  1117. NodePath path = anim->track_get_path(i);
  1118. for (int j = 0; j < path.get_name_count(); j++) {
  1119. String node = path.get_name(j);
  1120. if (_teststr(node, "noimp")) {
  1121. anim->remove_track(i);
  1122. i--;
  1123. break;
  1124. }
  1125. }
  1126. }
  1127. }
  1128. }
  1129. if (p_flags & SCENE_FLAG_CREATE_IMPOSTORS && p_node->cast_to<MeshInstance>()) {
  1130. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1131. String str;
  1132. if ((_teststr(name, "imp"))) {
  1133. str = name;
  1134. } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(), "imp"))) {
  1135. str = mi->get_mesh()->get_name();
  1136. }
  1137. if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
  1138. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1139. MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
  1140. String d = str.substr(str.find("imp") + 3, str.length());
  1141. if (d != "") {
  1142. if ((d[0] < '0' || d[0] > '9'))
  1143. d = d.substr(1, d.length());
  1144. if (d.length() && d[0] >= '0' && d[0] <= '9') {
  1145. float dist = d.to_double();
  1146. mi->set_flag(GeometryInstance::FLAG_BILLBOARD, true);
  1147. mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y, true);
  1148. mi->set_draw_range_begin(dist);
  1149. mi->set_draw_range_end(100000);
  1150. mip->set_draw_range_begin(0);
  1151. mip->set_draw_range_end(dist);
  1152. if (mi->get_mesh().is_valid()) {
  1153. Ref<Mesh> m = mi->get_mesh();
  1154. for (int i = 0; i < m->get_surface_count(); i++) {
  1155. Ref<FixedMaterial> fm = m->surface_get_material(i);
  1156. if (fm.is_valid()) {
  1157. fm->set_flag(Material::FLAG_UNSHADED, true);
  1158. fm->set_flag(Material::FLAG_DOUBLE_SIDED, true);
  1159. fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER);
  1160. fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
  1161. }
  1162. }
  1163. }
  1164. }
  1165. }
  1166. }
  1167. }
  1168. if (p_flags & SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) {
  1169. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1170. String str;
  1171. if ((_teststr(name, "lod"))) {
  1172. str = name;
  1173. } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(), "lod"))) {
  1174. str = mi->get_mesh()->get_name();
  1175. }
  1176. if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
  1177. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1178. MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
  1179. String d = str.substr(str.find("lod") + 3, str.length());
  1180. if (d != "") {
  1181. if ((d[0] < '0' || d[0] > '9'))
  1182. d = d.substr(1, d.length());
  1183. if (d.length() && d[0] >= '0' && d[0] <= '9') {
  1184. float dist = d.to_double();
  1185. mi->set_draw_range_begin(dist);
  1186. mi->set_draw_range_end(100000);
  1187. mip->set_draw_range_begin(0);
  1188. mip->set_draw_range_end(dist);
  1189. /*if (mi->get_mesh().is_valid()) {
  1190. Ref<Mesh> m = mi->get_mesh();
  1191. for(int i=0;i<m->get_surface_count();i++) {
  1192. Ref<FixedMaterial> fm = m->surface_get_material(i);
  1193. if (fm.is_valid()) {
  1194. fm->set_flag(Material::FLAG_UNSHADED,true);
  1195. fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
  1196. fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
  1197. fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
  1198. }
  1199. }
  1200. }*/
  1201. }
  1202. }
  1203. }
  1204. }
  1205. if (p_flags & SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name, "lm") && p_node->cast_to<MeshInstance>()) {
  1206. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1207. String str = name;
  1208. int layer = str.substr(str.find("lm") + 3, str.length()).to_int();
  1209. mi->set_baked_light_texture_id(layer);
  1210. }
  1211. bool is_rigid = _teststr(name, "rigidonly");
  1212. if (p_flags & SCENE_FLAG_CREATE_COLLISIONS && (_teststr(name, "colonly") || is_rigid)) {
  1213. if (isroot)
  1214. return p_node;
  1215. if (p_node->cast_to<MeshInstance>() && !is_rigid) {
  1216. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1217. Node *col = mi->create_trimesh_collision_node();
  1218. ERR_FAIL_COND_V(!col, NULL);
  1219. col->set_name(_fixstr(name, "colonly"));
  1220. col->cast_to<Spatial>()->set_transform(mi->get_transform());
  1221. p_node->replace_by(col);
  1222. memdelete(p_node);
  1223. p_node = col;
  1224. StaticBody *sb = col->cast_to<StaticBody>();
  1225. CollisionShape *colshape = memnew(CollisionShape);
  1226. colshape->set_shape(sb->get_shape(0));
  1227. colshape->set_name("shape");
  1228. sb->add_child(colshape);
  1229. colshape->set_owner(p_node->get_owner());
  1230. } else if (p_node->has_meta("empty_draw_type")) {
  1231. String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
  1232. print_line(empty_draw_type);
  1233. PhysicsBody *pb;
  1234. if (is_rigid) {
  1235. pb = memnew(RigidBody);
  1236. pb->set_name(_fixstr(name, "rigidonly"));
  1237. } else {
  1238. pb = memnew(StaticBody);
  1239. pb->set_name(_fixstr(name, "colonly"));
  1240. }
  1241. pb->cast_to<Spatial>()->set_transform(p_node->cast_to<Spatial>()->get_transform());
  1242. p_node->replace_by(pb);
  1243. memdelete(p_node);
  1244. CollisionShape *colshape = memnew(CollisionShape);
  1245. if (empty_draw_type == "CUBE") {
  1246. BoxShape *boxShape = memnew(BoxShape);
  1247. boxShape->set_extents(Vector3(1, 1, 1));
  1248. colshape->set_shape(boxShape);
  1249. colshape->set_name("BoxShape");
  1250. } else if (empty_draw_type == "SINGLE_ARROW") {
  1251. RayShape *rayShape = memnew(RayShape);
  1252. rayShape->set_length(1);
  1253. colshape->set_shape(rayShape);
  1254. colshape->set_name("RayShape");
  1255. pb->cast_to<Spatial>()->rotate_x(Math_PI / 2);
  1256. } else if (empty_draw_type == "IMAGE") {
  1257. PlaneShape *planeShape = memnew(PlaneShape);
  1258. colshape->set_shape(planeShape);
  1259. colshape->set_name("PlaneShape");
  1260. } else {
  1261. SphereShape *sphereShape = memnew(SphereShape);
  1262. sphereShape->set_radius(1);
  1263. colshape->set_shape(sphereShape);
  1264. colshape->set_name("SphereShape");
  1265. }
  1266. pb->add_child(colshape);
  1267. colshape->set_owner(pb->get_owner());
  1268. }
  1269. } else if (p_flags & SCENE_FLAG_CREATE_COLLISIONS && _teststr(name, "rigid") && p_node->cast_to<MeshInstance>()) {
  1270. if (isroot)
  1271. return p_node;
  1272. // get mesh instance and bounding box
  1273. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1274. AABB aabb = mi->get_aabb();
  1275. // create a new rigid body collision node
  1276. RigidBody *rigid_body = memnew(RigidBody);
  1277. Node *col = rigid_body;
  1278. ERR_FAIL_COND_V(!col, NULL);
  1279. // remove node name postfix
  1280. col->set_name(_fixstr(name, "rigid"));
  1281. // get mesh instance xform matrix to the rigid body collision node
  1282. col->cast_to<Spatial>()->set_transform(mi->get_transform());
  1283. // save original node by duplicating it into a new instance and correcting the name
  1284. Node *mesh = p_node->duplicate();
  1285. mesh->set_name(_fixstr(name, "rigid"));
  1286. // reset the xform matrix of the duplicated node so it can inherit parent node xform
  1287. mesh->cast_to<Spatial>()->set_transform(Transform(Matrix3()));
  1288. // reparent the new mesh node to the rigid body collision node
  1289. p_node->add_child(mesh);
  1290. mesh->set_owner(p_node->get_owner());
  1291. // replace the original node with the rigid body collision node
  1292. p_node->replace_by(col);
  1293. memdelete(p_node);
  1294. p_node = col;
  1295. // create an alias for the rigid body collision node
  1296. RigidBody *rb = col->cast_to<RigidBody>();
  1297. // create a new Box collision shape and set the right extents
  1298. Ref<BoxShape> shape = memnew(BoxShape);
  1299. shape->set_extents(aabb.get_size() * 0.5);
  1300. CollisionShape *colshape = memnew(CollisionShape);
  1301. colshape->set_name("shape");
  1302. colshape->set_shape(shape);
  1303. // reparent the new collision shape to the rigid body collision node
  1304. rb->add_child(colshape);
  1305. colshape->set_owner(p_node->get_owner());
  1306. } else if (p_flags & SCENE_FLAG_CREATE_COLLISIONS && _teststr(name, "col") && p_node->cast_to<MeshInstance>()) {
  1307. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1308. mi->set_name(_fixstr(name, "col"));
  1309. Node *col = mi->create_trimesh_collision_node();
  1310. ERR_FAIL_COND_V(!col, NULL);
  1311. col->set_name("col");
  1312. p_node->add_child(col);
  1313. StaticBody *sb = col->cast_to<StaticBody>();
  1314. CollisionShape *colshape = memnew(CollisionShape);
  1315. colshape->set_shape(sb->get_shape(0));
  1316. colshape->set_name("shape");
  1317. col->add_child(colshape);
  1318. colshape->set_owner(p_node->get_owner());
  1319. sb->set_owner(p_node->get_owner());
  1320. } else if (p_flags & SCENE_FLAG_CREATE_NAVMESH && _teststr(name, "navmesh") && p_node->cast_to<MeshInstance>()) {
  1321. if (isroot)
  1322. return p_node;
  1323. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1324. Ref<Mesh> mesh = mi->get_mesh();
  1325. ERR_FAIL_COND_V(mesh.is_null(), NULL);
  1326. NavigationMeshInstance *nmi = memnew(NavigationMeshInstance);
  1327. nmi->set_name(_fixstr(name, "navmesh"));
  1328. Ref<NavigationMesh> nmesh = memnew(NavigationMesh);
  1329. nmesh->create_from_mesh(mesh);
  1330. nmi->set_navigation_mesh(nmesh);
  1331. nmi->cast_to<Spatial>()->set_transform(mi->get_transform());
  1332. p_node->replace_by(nmi);
  1333. memdelete(p_node);
  1334. p_node = nmi;
  1335. } else if (p_flags & SCENE_FLAG_CREATE_CARS && _teststr(name, "vehicle")) {
  1336. if (isroot)
  1337. return p_node;
  1338. Node *owner = p_node->get_owner();
  1339. Spatial *s = p_node->cast_to<Spatial>();
  1340. VehicleBody *bv = memnew(VehicleBody);
  1341. String n = _fixstr(p_node->get_name(), "vehicle");
  1342. bv->set_name(n);
  1343. p_node->replace_by(bv);
  1344. p_node->set_name(n);
  1345. bv->add_child(p_node);
  1346. bv->set_owner(owner);
  1347. p_node->set_owner(owner);
  1348. bv->set_transform(s->get_transform());
  1349. s->set_transform(Transform());
  1350. p_node = bv;
  1351. } else if (p_flags & SCENE_FLAG_CREATE_CARS && _teststr(name, "wheel")) {
  1352. if (isroot)
  1353. return p_node;
  1354. Node *owner = p_node->get_owner();
  1355. Spatial *s = p_node->cast_to<Spatial>();
  1356. VehicleWheel *bv = memnew(VehicleWheel);
  1357. String n = _fixstr(p_node->get_name(), "wheel");
  1358. bv->set_name(n);
  1359. p_node->replace_by(bv);
  1360. p_node->set_name(n);
  1361. bv->add_child(p_node);
  1362. bv->set_owner(owner);
  1363. p_node->set_owner(owner);
  1364. bv->set_transform(s->get_transform());
  1365. s->set_transform(Transform());
  1366. p_node = bv;
  1367. } else if (p_flags & SCENE_FLAG_CREATE_ROOMS && _teststr(name, "room") && p_node->cast_to<MeshInstance>()) {
  1368. if (isroot)
  1369. return p_node;
  1370. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1371. DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);
  1372. BSP_Tree bsptree(faces);
  1373. Ref<RoomBounds> area = memnew(RoomBounds);
  1374. area->set_bounds(faces);
  1375. area->set_geometry_hint(faces);
  1376. Room *room = memnew(Room);
  1377. room->set_name(_fixstr(name, "room"));
  1378. room->set_transform(mi->get_transform());
  1379. room->set_room(area);
  1380. p_node->replace_by(room);
  1381. memdelete(p_node);
  1382. p_node = room;
  1383. } else if (p_flags & SCENE_FLAG_CREATE_ROOMS && _teststr(name, "room")) {
  1384. if (isroot)
  1385. return p_node;
  1386. Spatial *dummy = p_node->cast_to<Spatial>();
  1387. ERR_FAIL_COND_V(!dummy, NULL);
  1388. Room *room = memnew(Room);
  1389. room->set_name(_fixstr(name, "room"));
  1390. room->set_transform(dummy->get_transform());
  1391. p_node->replace_by(room);
  1392. memdelete(p_node);
  1393. p_node = room;
  1394. room->compute_room_from_subtree();
  1395. } else if (p_flags & SCENE_FLAG_CREATE_PORTALS && _teststr(name, "portal") && p_node->cast_to<MeshInstance>()) {
  1396. if (isroot)
  1397. return p_node;
  1398. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1399. DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);
  1400. ERR_FAIL_COND_V(faces.size() == 0, NULL);
  1401. //step 1 compute the plane
  1402. Set<Vector3> points;
  1403. Plane plane;
  1404. Vector3 center;
  1405. for (int i = 0; i < faces.size(); i++) {
  1406. Face3 f = faces.get(i);
  1407. Plane p = f.get_plane();
  1408. plane.normal += p.normal;
  1409. plane.d += p.d;
  1410. for (int i = 0; i < 3; i++) {
  1411. Vector3 v = f.vertex[i].snapped(0.01);
  1412. if (!points.has(v)) {
  1413. points.insert(v);
  1414. center += v;
  1415. }
  1416. }
  1417. }
  1418. plane.normal.normalize();
  1419. plane.d /= faces.size();
  1420. center /= points.size();
  1421. //step 2, create points
  1422. Transform t;
  1423. t.basis.from_z(plane.normal);
  1424. t.basis.transpose();
  1425. t.origin = center;
  1426. Vector<Point2> portal_points;
  1427. for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) {
  1428. Vector3 local = t.xform_inv(E->get());
  1429. portal_points.push_back(Point2(local.x, local.y));
  1430. }
  1431. // step 3 bubbly sort points
  1432. int swaps = 0;
  1433. do {
  1434. swaps = 0;
  1435. for (int i = 0; i < portal_points.size() - 1; i++) {
  1436. float a = portal_points[i].angle();
  1437. float b = portal_points[i + 1].angle();
  1438. if (a > b) {
  1439. SWAP(portal_points[i], portal_points[i + 1]);
  1440. swaps++;
  1441. }
  1442. }
  1443. } while (swaps);
  1444. Portal *portal = memnew(Portal);
  1445. portal->set_shape(portal_points);
  1446. portal->set_transform(mi->get_transform() * t);
  1447. p_node->replace_by(portal);
  1448. memdelete(p_node);
  1449. p_node = portal;
  1450. } else if (p_node->cast_to<MeshInstance>()) {
  1451. //last attempt, maybe collision insde the mesh data
  1452. MeshInstance *mi = p_node->cast_to<MeshInstance>();
  1453. Ref<Mesh> mesh = mi->get_mesh();
  1454. if (!mesh.is_null()) {
  1455. if (p_flags & SCENE_FLAG_CREATE_COLLISIONS && _teststr(mesh->get_name(), "col")) {
  1456. mesh->set_name(_fixstr(mesh->get_name(), "col"));
  1457. Ref<Shape> shape;
  1458. if (collision_map.has(mesh)) {
  1459. shape = collision_map[mesh];
  1460. } else {
  1461. shape = mesh->create_trimesh_shape();
  1462. if (!shape.is_null())
  1463. collision_map[mesh] = shape;
  1464. }
  1465. if (!shape.is_null()) {
  1466. #if 0
  1467. StaticBody* static_body = memnew( StaticBody );
  1468. ERR_FAIL_COND_V(!static_body,NULL);
  1469. static_body->set_name( String(mesh->get_name()) + "_col" );
  1470. shape->set_name(static_body->get_name());
  1471. static_body->add_shape(shape);
  1472. mi->add_child(static_body);
  1473. if (mi->get_owner())
  1474. static_body->set_owner( mi->get_owner() );
  1475. #endif
  1476. }
  1477. }
  1478. for (int i = 0; i < mesh->get_surface_count(); i++) {
  1479. Ref<FixedMaterial> fm = mesh->surface_get_material(i);
  1480. if (fm.is_valid()) {
  1481. String name = fm->get_name();
  1482. if (_teststr(name, "alpha")) {
  1483. fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
  1484. name = _fixstr(name, "alpha");
  1485. }
  1486. if (_teststr(name, "vcol")) {
  1487. fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
  1488. name = _fixstr(name, "vcol");
  1489. }
  1490. fm->set_name(name);
  1491. }
  1492. }
  1493. }
  1494. }
  1495. return p_node;
  1496. }
  1497. #if 0
  1498. Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,const String& p_resource_path,uint32_t p_flags,ImageFormat p_image_format,ImageCompression p_image_compression,uint32_t p_image_flags,float p_quality,uint32_t animation_flags,Node **r_scene,Ref<EditorPostImport> p_post_import) {
  1499. }
  1500. #endif
  1501. void EditorSceneImportPlugin::_tag_import_paths(Node *p_scene, Node *p_node) {
  1502. if (p_scene != p_node && p_node->get_owner() != p_scene)
  1503. return;
  1504. NodePath path = p_scene->get_path_to(p_node);
  1505. p_node->set_import_path(path);
  1506. Spatial *snode = p_node->cast_to<Spatial>();
  1507. if (snode) {
  1508. snode->set_import_transform(snode->get_transform());
  1509. }
  1510. for (int i = 0; i < p_node->get_child_count(); i++) {
  1511. _tag_import_paths(p_scene, p_node->get_child(i));
  1512. }
  1513. }
  1514. Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata> &p_from, Node **r_node, List<String> *r_missing) {
  1515. Ref<ResourceImportMetadata> from = p_from;
  1516. ERR_FAIL_COND_V(from->get_source_count() != 1, ERR_INVALID_PARAMETER);
  1517. String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0));
  1518. Ref<EditorSceneImporter> importer;
  1519. String ext = src_path.extension().to_lower();
  1520. EditorProgress progress("import", TTR("Import Scene"), 104);
  1521. progress.step(TTR("Importing Scene.."), 0);
  1522. for (int i = 0; i < importers.size(); i++) {
  1523. List<String> extensions;
  1524. importers[i]->get_extensions(&extensions);
  1525. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  1526. if (E->get().to_lower() == ext) {
  1527. importer = importers[i];
  1528. break;
  1529. }
  1530. }
  1531. if (importer.is_valid())
  1532. break;
  1533. }
  1534. ERR_FAIL_COND_V(!importer.is_valid(), ERR_FILE_UNRECOGNIZED);
  1535. int animation_flags = p_from->get_option("animation_flags");
  1536. int scene_flags = from->get_option("flags");
  1537. int fps = 24;
  1538. if (from->has_option("animation_bake_fps"))
  1539. fps = from->get_option("animation_bake_fps");
  1540. Array clips;
  1541. if (from->has_option("animation_clips"))
  1542. clips = from->get_option("animation_clips");
  1543. uint32_t import_flags = 0;
  1544. if (animation_flags & EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP)
  1545. import_flags |= EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP;
  1546. if (animation_flags & EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS)
  1547. import_flags |= EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS;
  1548. if (animation_flags & EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
  1549. import_flags |= EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE;
  1550. if (animation_flags & EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS)
  1551. import_flags |= EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS;
  1552. if (scene_flags & SCENE_FLAG_IMPORT_ANIMATIONS)
  1553. import_flags |= EditorSceneImporter::IMPORT_ANIMATION;
  1554. //if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES)
  1555. // import_flags|=EditorSceneImporter::IMPORT_FAIL_ON_MISSING_DEPENDENCIES;
  1556. if (scene_flags & SCENE_FLAG_GENERATE_TANGENT_ARRAYS)
  1557. import_flags |= EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
  1558. Error err = OK;
  1559. Node *scene = importer->import_scene(src_path, import_flags, fps, r_missing, &err);
  1560. if (!scene || err != OK) {
  1561. return err;
  1562. }
  1563. if (from->has_option("root_type")) {
  1564. String type = from->get_option("root_type");
  1565. Object *base = ObjectTypeDB::instance(type);
  1566. Node *base_node = NULL;
  1567. if (base)
  1568. base_node = base->cast_to<Node>();
  1569. if (base_node) {
  1570. scene->replace_by(base_node);
  1571. memdelete(scene);
  1572. scene = base_node;
  1573. }
  1574. }
  1575. scene->set_name(from->get_option("root_name"));
  1576. _tag_import_paths(scene, scene);
  1577. *r_node = scene;
  1578. return OK;
  1579. }
  1580. void EditorSceneImportPlugin::_create_clips(Node *scene, const Array &p_clips, bool p_bake_all) {
  1581. if (!scene->has_node(String("AnimationPlayer")))
  1582. return;
  1583. Node *n = scene->get_node(String("AnimationPlayer"));
  1584. ERR_FAIL_COND(!n);
  1585. AnimationPlayer *anim = n->cast_to<AnimationPlayer>();
  1586. ERR_FAIL_COND(!anim);
  1587. if (!anim->has_animation("default"))
  1588. return;
  1589. Ref<Animation> default_anim = anim->get_animation("default");
  1590. for (int i = 0; i < p_clips.size(); i += 4) {
  1591. String name = p_clips[i];
  1592. float from = p_clips[i + 1];
  1593. float to = p_clips[i + 2];
  1594. bool loop = p_clips[i + 3];
  1595. if (from >= to)
  1596. continue;
  1597. Ref<Animation> new_anim = memnew(Animation);
  1598. for (int j = 0; j < default_anim->get_track_count(); j++) {
  1599. List<float> keys;
  1600. int kc = default_anim->track_get_key_count(j);
  1601. int dtrack = -1;
  1602. for (int k = 0; k < kc; k++) {
  1603. float kt = default_anim->track_get_key_time(j, k);
  1604. if (kt >= from && kt < to) {
  1605. //found a key within range, so create track
  1606. if (dtrack == -1) {
  1607. new_anim->add_track(default_anim->track_get_type(j));
  1608. dtrack = new_anim->get_track_count() - 1;
  1609. new_anim->track_set_path(dtrack, default_anim->track_get_path(j));
  1610. if (kt > (from + 0.01) && k > 0) {
  1611. if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
  1612. Quat q;
  1613. Vector3 p;
  1614. Vector3 s;
  1615. default_anim->transform_track_interpolate(j, from, &p, &q, &s);
  1616. new_anim->transform_track_insert_key(dtrack, 0, p, q, s);
  1617. }
  1618. }
  1619. }
  1620. if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
  1621. Quat q;
  1622. Vector3 p;
  1623. Vector3 s;
  1624. default_anim->transform_track_get_key(j, k, &p, &q, &s);
  1625. new_anim->transform_track_insert_key(dtrack, kt - from, p, q, s);
  1626. }
  1627. }
  1628. if (dtrack != -1 && kt >= to) {
  1629. if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
  1630. Quat q;
  1631. Vector3 p;
  1632. Vector3 s;
  1633. default_anim->transform_track_interpolate(j, to, &p, &q, &s);
  1634. new_anim->transform_track_insert_key(dtrack, to - from, p, q, s);
  1635. }
  1636. }
  1637. }
  1638. if (dtrack == -1 && p_bake_all) {
  1639. new_anim->add_track(default_anim->track_get_type(j));
  1640. dtrack = new_anim->get_track_count() - 1;
  1641. new_anim->track_set_path(dtrack, default_anim->track_get_path(j));
  1642. if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
  1643. Quat q;
  1644. Vector3 p;
  1645. Vector3 s;
  1646. default_anim->transform_track_interpolate(j, from, &p, &q, &s);
  1647. new_anim->transform_track_insert_key(dtrack, 0, p, q, s);
  1648. default_anim->transform_track_interpolate(j, to, &p, &q, &s);
  1649. new_anim->transform_track_insert_key(dtrack, to - from, p, q, s);
  1650. }
  1651. }
  1652. }
  1653. new_anim->set_loop(loop);
  1654. new_anim->set_length(to - from);
  1655. anim->add_animation(name, new_anim);
  1656. }
  1657. anim->remove_animation("default"); //remove default (no longer needed)
  1658. }
  1659. void EditorSceneImportPlugin::_filter_anim_tracks(Ref<Animation> anim, Set<String> &keep) {
  1660. Ref<Animation> a = anim;
  1661. ERR_FAIL_COND(!a.is_valid());
  1662. print_line("From Anim " + anim->get_name() + ":");
  1663. for (int j = 0; j < a->get_track_count(); j++) {
  1664. String path = a->track_get_path(j);
  1665. if (!keep.has(path)) {
  1666. print_line("Remove: " + path);
  1667. a->remove_track(j);
  1668. j--;
  1669. }
  1670. }
  1671. }
  1672. void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String &p_text) {
  1673. if (!scene->has_node(String("AnimationPlayer")))
  1674. return;
  1675. Node *n = scene->get_node(String("AnimationPlayer"));
  1676. ERR_FAIL_COND(!n);
  1677. AnimationPlayer *anim = n->cast_to<AnimationPlayer>();
  1678. ERR_FAIL_COND(!anim);
  1679. Vector<String> strings = p_text.split("\n");
  1680. for (int i = 0; i < strings.size(); i++) {
  1681. strings[i] = strings[i].strip_edges();
  1682. }
  1683. List<StringName> anim_names;
  1684. anim->get_animation_list(&anim_names);
  1685. for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) {
  1686. String name = E->get();
  1687. bool valid_for_this = false;
  1688. bool valid = false;
  1689. Set<String> keep;
  1690. Set<String> keep_local;
  1691. for (int i = 0; i < strings.size(); i++) {
  1692. if (strings[i].begins_with("@")) {
  1693. valid_for_this = false;
  1694. for (Set<String>::Element *F = keep_local.front(); F; F = F->next()) {
  1695. keep.insert(F->get());
  1696. }
  1697. keep_local.clear();
  1698. Vector<String> filters = strings[i].substr(1, strings[i].length()).split(",");
  1699. for (int j = 0; j < filters.size(); j++) {
  1700. String fname = filters[j].strip_edges();
  1701. if (fname == "")
  1702. continue;
  1703. int fc = fname[0];
  1704. bool plus;
  1705. if (fc == '+')
  1706. plus = true;
  1707. else if (fc == '-')
  1708. plus = false;
  1709. else
  1710. continue;
  1711. String filter = fname.substr(1, fname.length()).strip_edges();
  1712. if (!name.matchn(filter))
  1713. continue;
  1714. valid_for_this = plus;
  1715. }
  1716. if (valid_for_this)
  1717. valid = true;
  1718. } else if (valid_for_this) {
  1719. Ref<Animation> a = anim->get_animation(name);
  1720. if (!a.is_valid())
  1721. continue;
  1722. for (int j = 0; j < a->get_track_count(); j++) {
  1723. String path = a->track_get_path(j);
  1724. String tname = strings[i];
  1725. if (tname == "")
  1726. continue;
  1727. int fc = tname[0];
  1728. bool plus;
  1729. if (fc == '+')
  1730. plus = true;
  1731. else if (fc == '-')
  1732. plus = false;
  1733. else
  1734. continue;
  1735. String filter = tname.substr(1, tname.length()).strip_edges();
  1736. if (!path.matchn(filter))
  1737. continue;
  1738. if (plus)
  1739. keep_local.insert(path);
  1740. else if (!keep.has(path)) {
  1741. keep_local.erase(path);
  1742. }
  1743. }
  1744. }
  1745. }
  1746. if (valid) {
  1747. for (Set<String>::Element *F = keep_local.front(); F; F = F->next()) {
  1748. keep.insert(F->get());
  1749. }
  1750. print_line("FILTERING ANIM: " + String(E->get()));
  1751. _filter_anim_tracks(anim->get_animation(name), keep);
  1752. } else {
  1753. print_line("NOT FILTERING ANIM: " + String(E->get()));
  1754. }
  1755. }
  1756. }
  1757. void EditorSceneImportPlugin::_optimize_animations(Node *scene, float p_max_lin_error, float p_max_ang_error, float p_max_angle) {
  1758. if (!scene->has_node(String("AnimationPlayer")))
  1759. return;
  1760. Node *n = scene->get_node(String("AnimationPlayer"));
  1761. ERR_FAIL_COND(!n);
  1762. AnimationPlayer *anim = n->cast_to<AnimationPlayer>();
  1763. ERR_FAIL_COND(!anim);
  1764. List<StringName> anim_names;
  1765. anim->get_animation_list(&anim_names);
  1766. for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) {
  1767. Ref<Animation> a = anim->get_animation(E->get());
  1768. a->optimize(p_max_lin_error, p_max_ang_error, Math::deg2rad(p_max_angle));
  1769. }
  1770. }
  1771. void EditorSceneImportPlugin::_find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String, Ref<Material> > &materials, bool p_merge_anims, Map<String, Ref<Animation> > &merged_anims, Set<Ref<Mesh> > &tested_meshes) {
  1772. if (node != scene && node->get_owner() != scene)
  1773. return;
  1774. String path = scene->get_path_to(node);
  1775. if (p_merge_anims && node->cast_to<AnimationPlayer>()) {
  1776. AnimationPlayer *ap = node->cast_to<AnimationPlayer>();
  1777. List<StringName> anims;
  1778. ap->get_animation_list(&anims);
  1779. for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
  1780. Ref<Animation> anim = ap->get_animation(E->get());
  1781. Ref<Animation> clone;
  1782. bool has_user_tracks = false;
  1783. for (int i = 0; i < anim->get_track_count(); i++) {
  1784. if (!anim->track_is_imported(i)) {
  1785. has_user_tracks = true;
  1786. break;
  1787. }
  1788. }
  1789. if (has_user_tracks) {
  1790. clone = anim->duplicate();
  1791. for (int i = 0; i < clone->get_track_count(); i++) {
  1792. if (clone->track_is_imported(i)) {
  1793. clone->remove_track(i);
  1794. i--;
  1795. }
  1796. }
  1797. merged_anims[path + "::" + String(E->get())] = clone;
  1798. }
  1799. }
  1800. }
  1801. if (p_merge_material && node->cast_to<MeshInstance>()) {
  1802. MeshInstance *mi = node->cast_to<MeshInstance>();
  1803. Ref<Mesh> mesh = mi->get_mesh();
  1804. if (mesh.is_valid() && mesh->get_name() != String() && !tested_meshes.has(mesh)) {
  1805. for (int i = 0; i < mesh->get_surface_count(); i++) {
  1806. Ref<Material> material = mesh->surface_get_material(i);
  1807. if (material.is_valid()) {
  1808. String sname = mesh->surface_get_name(i);
  1809. if (sname == "")
  1810. sname = "surf_" + itos(i);
  1811. sname = mesh->get_name() + ":surf:" + sname;
  1812. materials[sname] = material;
  1813. }
  1814. }
  1815. tested_meshes.insert(mesh);
  1816. }
  1817. if (mesh.is_valid()) {
  1818. for (int i = 0; i < mesh->get_surface_count(); i++) {
  1819. Ref<Material> material = mi->get_surface_material(i);
  1820. if (material.is_valid()) {
  1821. String sname = mesh->surface_get_name(i);
  1822. if (sname == "")
  1823. sname = "surf_" + itos(i);
  1824. sname = path + ":inst_surf:" + sname;
  1825. materials[sname] = material;
  1826. }
  1827. }
  1828. }
  1829. Ref<Material> override = mi->get_material_override();
  1830. if (override.is_valid()) {
  1831. materials[path + ":override"] = override;
  1832. }
  1833. }
  1834. for (int i = 0; i < node->get_child_count(); i++) {
  1835. _find_resources_to_merge(scene, node->get_child(i), p_merge_material, materials, p_merge_anims, merged_anims, tested_meshes);
  1836. }
  1837. }
  1838. void EditorSceneImportPlugin::_merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String, Ref<Animation> > &merged_anims, Set<Ref<Mesh> > &tested_meshes) {
  1839. if (node != scene && node->get_owner() != scene)
  1840. return;
  1841. String path = scene->get_path_to(node);
  1842. print_line("at path: " + path);
  1843. if (node->cast_to<AnimationPlayer>()) {
  1844. AnimationPlayer *ap = node->cast_to<AnimationPlayer>();
  1845. List<StringName> anims;
  1846. ap->get_animation_list(&anims);
  1847. for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
  1848. Ref<Animation> anim = ap->get_animation(E->get());
  1849. String anim_path = path + "::" + String(E->get());
  1850. if (merged_anims.has(anim_path)) {
  1851. Ref<Animation> user_tracks = merged_anims[anim_path];
  1852. for (int i = 0; i < user_tracks->get_track_count(); i++) {
  1853. int idx = anim->get_track_count();
  1854. anim->add_track(user_tracks->track_get_type(i));
  1855. anim->track_set_path(idx, user_tracks->track_get_path(i));
  1856. anim->track_set_interpolation_type(idx, user_tracks->track_get_interpolation_type(i));
  1857. for (int j = 0; j < user_tracks->track_get_key_count(i); j++) {
  1858. float ofs = user_tracks->track_get_key_time(i, j);
  1859. float trans = user_tracks->track_get_key_transition(i, j);
  1860. Variant value = user_tracks->track_get_key_value(i, j);
  1861. anim->track_insert_key(idx, ofs, value, trans);
  1862. }
  1863. }
  1864. }
  1865. }
  1866. }
  1867. if (node->cast_to<MeshInstance>()) {
  1868. MeshInstance *mi = node->cast_to<MeshInstance>();
  1869. Ref<Mesh> mesh = mi->get_mesh();
  1870. if (mesh.is_valid() && mesh->get_name() != String() && !tested_meshes.has(mesh)) {
  1871. for (int i = 0; i < mesh->get_surface_count(); i++) {
  1872. String sname = mesh->surface_get_name(i);
  1873. if (sname == "")
  1874. sname = "surf_" + itos(i);
  1875. sname = mesh->get_name() + ":surf:" + sname;
  1876. if (materials.has(sname)) {
  1877. mesh->surface_set_material(i, materials[sname]);
  1878. }
  1879. }
  1880. tested_meshes.insert(mesh);
  1881. }
  1882. if (mesh.is_valid()) {
  1883. for (int i = 0; i < mesh->get_surface_count(); i++) {
  1884. String sname = mesh->surface_get_name(i);
  1885. if (sname == "")
  1886. sname = "surf_" + itos(i);
  1887. sname = path + ":inst_surf:" + sname;
  1888. if (materials.has(sname)) {
  1889. mi->set_surface_material(i, materials[sname]);
  1890. }
  1891. }
  1892. }
  1893. String opath = path + ":override";
  1894. if (materials.has(opath)) {
  1895. mi->set_material_override(materials[opath]);
  1896. }
  1897. }
  1898. for (int i = 0; i < node->get_child_count(); i++) {
  1899. _merge_found_resources(scene, node->get_child(i), p_merge_material, materials, p_merge_anims, merged_anims, tested_meshes);
  1900. }
  1901. }
  1902. Error EditorSceneImportPlugin::import2(Node *scene, const String &p_dest_path, const Ref<ResourceImportMetadata> &p_from) {
  1903. Error err = OK;
  1904. Ref<ResourceImportMetadata> from = p_from;
  1905. String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0));
  1906. int animation_flags = p_from->get_option("animation_flags");
  1907. Array animation_clips = p_from->get_option("animation_clips");
  1908. String animation_filter = p_from->get_option("animation_filters");
  1909. int scene_flags = from->get_option("flags");
  1910. float anim_optimizer_linerr = 0.05;
  1911. float anim_optimizer_angerr = 0.01;
  1912. float anim_optimizer_maxang = 22;
  1913. if (from->has_option("animation_optimizer_linear_error"))
  1914. anim_optimizer_linerr = from->get_option("animation_optimizer_linear_error");
  1915. if (from->has_option("animation_optimizer_angular_error"))
  1916. anim_optimizer_angerr = from->get_option("animation_optimizer_angular_error");
  1917. if (from->has_option("animation_optimizer_max_angle"))
  1918. anim_optimizer_maxang = from->get_option("animation_optimizer_max_angle");
  1919. EditorProgress progress("import", TTR("Import Scene"), 104);
  1920. progress.step(TTR("Importing Scene.."), 2);
  1921. from->set_source_md5(0, FileAccess::get_md5(src_path));
  1922. from->set_editor(get_name());
  1923. from->set_option("reimport", false);
  1924. String target_res_path = p_dest_path.get_base_dir();
  1925. Map<Ref<Mesh>, Ref<Shape> > collision_map;
  1926. Map<Ref<ImageTexture>, TextureRole> imagemap;
  1927. scene = _fix_node(scene, scene, collision_map, scene_flags, imagemap);
  1928. if (animation_flags & EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
  1929. _optimize_animations(scene, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_maxang);
  1930. if (animation_clips.size())
  1931. _create_clips(scene, animation_clips, animation_flags & EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
  1932. _filter_tracks(scene, animation_filter);
  1933. if (scene_flags & (SCENE_FLAG_MERGE_KEEP_MATERIALS | SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS) && FileAccess::exists(p_dest_path)) {
  1934. //must merge!
  1935. print_line("MUST MERGE");
  1936. Ref<PackedScene> pscene = ResourceLoader::load(p_dest_path, "PackedScene", true);
  1937. if (pscene.is_valid()) {
  1938. Node *instance = pscene->instance();
  1939. if (instance) {
  1940. Map<String, Ref<Animation> > merged_anims;
  1941. Map<String, Ref<Material> > merged_materials;
  1942. Set<Ref<Mesh> > tested_meshes;
  1943. _find_resources_to_merge(instance, instance, scene_flags & SCENE_FLAG_MERGE_KEEP_MATERIALS, merged_materials, scene_flags & SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS, merged_anims, tested_meshes);
  1944. tested_meshes.clear();
  1945. _merge_found_resources(scene, scene, scene_flags & SCENE_FLAG_MERGE_KEEP_MATERIALS, merged_materials, scene_flags & SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS, merged_anims, tested_meshes);
  1946. memdelete(instance);
  1947. }
  1948. }
  1949. }
  1950. /// BEFORE ANYTHING, RUN SCRIPT
  1951. progress.step(TTR("Running Custom Script.."), 2);
  1952. String post_import_script_path = from->get_option("post_import_script");
  1953. Ref<EditorScenePostImport> post_import_script;
  1954. if (post_import_script_path != "") {
  1955. post_import_script_path = post_import_script_path;
  1956. Ref<Script> scr = ResourceLoader::load(post_import_script_path);
  1957. if (!scr.is_valid()) {
  1958. EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path);
  1959. } else {
  1960. post_import_script = Ref<EditorScenePostImport>(memnew(EditorScenePostImport));
  1961. post_import_script->set_script(scr.get_ref_ptr());
  1962. if (!post_import_script->get_script_instance()) {
  1963. EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):") + " " + post_import_script_path);
  1964. post_import_script.unref();
  1965. return ERR_CANT_CREATE;
  1966. }
  1967. }
  1968. }
  1969. if (post_import_script.is_valid()) {
  1970. scene = post_import_script->post_import(scene);
  1971. if (!scene) {
  1972. EditorNode::add_io_error(TTR("Error running post-import script:") + " " + post_import_script_path);
  1973. return err;
  1974. }
  1975. }
  1976. /// IMPORT IMAGES
  1977. int idx = 0;
  1978. int image_format = from->get_option("texture_format");
  1979. int image_flags = from->get_option("texture_flags");
  1980. float image_quality = from->get_option("texture_quality");
  1981. int texture_action = from->get_option("texture_action");
  1982. for (Map<Ref<ImageTexture>, TextureRole>::Element *E = imagemap.front(); E; E = E->next()) {
  1983. //texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff
  1984. //but not yet..
  1985. Ref<ImageTexture> texture = E->key();
  1986. ERR_CONTINUE(!texture.is_valid());
  1987. String path = texture->get_path();
  1988. String fname = path.get_file();
  1989. String target_path;
  1990. progress.step(TTR("Import Image:") + " " + fname, 3 + (idx)*100 / imagemap.size());
  1991. idx++;
  1992. switch (texture_action) {
  1993. case 1:
  1994. target_path = Globals::get_singleton()->get("editor/import_shared_textures");
  1995. target_path = target_path.plus_file(fname.basename() + ".tex");
  1996. break;
  1997. case 2:
  1998. target_path = path.basename() + ".tex";
  1999. break;
  2000. case 3:
  2001. target_path = path;
  2002. break;
  2003. default:
  2004. target_path = target_res_path.plus_file(fname.basename() + ".tex");
  2005. break;
  2006. }
  2007. if (!target_path.begins_with("res://")) {
  2008. EditorNode::add_io_error(vformat(TTR("Couldn't localize path: %s (already local)"), target_path));
  2009. continue;
  2010. }
  2011. if (texture_action == 3) {
  2012. texture->set_path(target_path);
  2013. } else {
  2014. if (path == target_path) {
  2015. EditorNode::add_io_error(TTR("Can't import a file over itself:") + " " + target_path);
  2016. continue;
  2017. }
  2018. target_path = target_path.basename() + ".tex";
  2019. Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata);
  2020. uint32_t flags = image_flags;
  2021. if (E->get() == TEXTURE_ROLE_DIFFUSE && scene_flags & SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES)
  2022. flags |= EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR;
  2023. if (E->get() == TEXTURE_ROLE_NORMALMAP && scene_flags & SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY)
  2024. flags |= EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_NORMAL_TO_XY;
  2025. imd->set_option("flags", flags);
  2026. imd->set_option("format", image_format);
  2027. imd->set_option("quality", image_quality);
  2028. imd->set_option("atlas", false);
  2029. imd->add_source(EditorImportPlugin::validate_source_path(path));
  2030. if (FileAccess::exists(target_path)) {
  2031. Ref<ResourceImportMetadata> rimdex = ResourceLoader::load_import_metadata(target_path);
  2032. if (rimdex.is_valid()) {
  2033. //make sure the options are the same, otherwise re-import
  2034. List<String> opts;
  2035. imd->get_options(&opts);
  2036. bool differ = false;
  2037. for (List<String>::Element *E = opts.front(); E; E = E->next()) {
  2038. if (!(rimdex->get_option(E->get()) == imd->get_option(E->get()))) {
  2039. differ = true;
  2040. break;
  2041. }
  2042. }
  2043. if (!differ) {
  2044. texture->set_path(target_path);
  2045. continue; //already imported
  2046. }
  2047. }
  2048. }
  2049. Error err = EditorTextureImportPlugin::get_singleton()->import(target_path, imd);
  2050. }
  2051. }
  2052. progress.step(TTR("Saving.."), 104);
  2053. Ref<PackedScene> packer = memnew(PackedScene);
  2054. packer->pack(scene);
  2055. //packer->set_path(p_dest_path); do not take over, let the changed files reload themselves
  2056. packer->set_import_metadata(from);
  2057. print_line("Saving to: " + p_dest_path);
  2058. err = ResourceSaver::save(p_dest_path, packer); //do not take over, let the changed files reload themselves
  2059. //EditorFileSystem::get_singleton()->update_resource(packer);
  2060. memdelete(scene);
  2061. /*
  2062. scene->set_filename(p_dest_path);
  2063. if (r_scene) {
  2064. *r_scene=scene;
  2065. } else {
  2066. memdelete(scene);
  2067. }
  2068. String sp;
  2069. if (p_post_import.is_valid() && !p_post_import->get_script().is_null()) {
  2070. Ref<Script> scr = p_post_import->get_script();
  2071. if (scr.is_valid())
  2072. sp=scr->get_path();
  2073. }
  2074. String op=_getrelpath(p_path,p_dest_path);
  2075. */
  2076. EditorNode::get_singleton()->reload_scene(p_dest_path);
  2077. return err;
  2078. }
  2079. Error EditorSceneImportPlugin::import(const String &p_dest_path, const Ref<ResourceImportMetadata> &p_from) {
  2080. Node *n = NULL;
  2081. Error err = import1(p_from, &n);
  2082. if (err != OK) {
  2083. if (n) {
  2084. memdelete(n);
  2085. }
  2086. return err;
  2087. }
  2088. return import2(n, p_dest_path, p_from);
  2089. }
  2090. void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter> &p_importer) {
  2091. importers.push_back(p_importer);
  2092. }
  2093. void EditorSceneImportPlugin::import_from_drop(const Vector<String> &p_drop, const String &p_dest_path) {
  2094. List<String> extensions;
  2095. for (int i = 0; i < importers.size(); i++) {
  2096. importers[i]->get_extensions(&extensions);
  2097. }
  2098. //bool warn_compatible=false;
  2099. for (int i = 0; i < p_drop.size(); i++) {
  2100. String extension = p_drop[i].extension().to_lower();
  2101. for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
  2102. if (E->get() == extension) {
  2103. dialog->popup_import(String());
  2104. dialog->setup_popup(p_drop[i], p_dest_path);
  2105. return;
  2106. }
  2107. }
  2108. }
  2109. }
  2110. EditorSceneImportPlugin::EditorSceneImportPlugin(EditorNode *p_editor) {
  2111. dialog = memnew(EditorSceneImportDialog(p_editor, this));
  2112. p_editor->get_gui_base()->add_child(dialog);
  2113. }
  2114. ///////////////////////////////
  2115. String EditorSceneAnimationImportPlugin::get_name() const {
  2116. return "anim_3d";
  2117. }
  2118. String EditorSceneAnimationImportPlugin::get_visible_name() const {
  2119. return TTR("3D Scene Animation");
  2120. }
  2121. void EditorSceneAnimationImportPlugin::import_dialog(const String &p_from) {
  2122. }
  2123. Error EditorSceneAnimationImportPlugin::import(const String &p_path, const Ref<ResourceImportMetadata> &p_from) {
  2124. return OK;
  2125. }
  2126. EditorSceneAnimationImportPlugin::EditorSceneAnimationImportPlugin(EditorNode *p_editor) {
  2127. }