collada.cpp 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385
  1. /**************************************************************************/
  2. /* collada.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "collada.h"
  31. #include <stdio.h>
  32. //#define DEBUG_DEFAULT_ANIMATION
  33. //#define DEBUG_COLLADA
  34. #ifdef DEBUG_COLLADA
  35. #define COLLADA_PRINT(m_what) print_line(m_what)
  36. #else
  37. #define COLLADA_PRINT(m_what)
  38. #endif
  39. #define COLLADA_IMPORT_SCALE_SCENE
  40. /* HELPERS */
  41. String Collada::Effect::get_texture_path(const String &p_source, Collada &p_state) const {
  42. const String &image = p_source;
  43. ERR_FAIL_COND_V(!p_state.state.image_map.has(image), "");
  44. return p_state.state.image_map[image].path;
  45. }
  46. Transform3D Collada::get_root_transform() const {
  47. Transform3D unit_scale_transform;
  48. #ifndef COLLADA_IMPORT_SCALE_SCENE
  49. unit_scale_transform.scale(Vector3(state.unit_scale, state.unit_scale, state.unit_scale));
  50. #endif
  51. return unit_scale_transform;
  52. }
  53. void Collada::Vertex::fix_unit_scale(const Collada &p_state) {
  54. #ifdef COLLADA_IMPORT_SCALE_SCENE
  55. vertex *= p_state.state.unit_scale;
  56. #endif
  57. }
  58. static String _uri_to_id(const String &p_uri) {
  59. if (p_uri.begins_with("#")) {
  60. return p_uri.substr(1, p_uri.size() - 1);
  61. } else {
  62. return p_uri;
  63. }
  64. }
  65. /** HELPER FUNCTIONS **/
  66. Transform3D Collada::fix_transform(const Transform3D &p_transform) {
  67. Transform3D tr = p_transform;
  68. #ifndef NO_UP_AXIS_SWAP
  69. if (state.up_axis != Vector3::AXIS_Y) {
  70. for (int i = 0; i < 3; i++) {
  71. SWAP(tr.basis[1][i], tr.basis[state.up_axis][i]);
  72. }
  73. for (int i = 0; i < 3; i++) {
  74. SWAP(tr.basis[i][1], tr.basis[i][state.up_axis]);
  75. }
  76. SWAP(tr.origin[1], tr.origin[state.up_axis]);
  77. tr.basis[state.up_axis][0] = -tr.basis[state.up_axis][0];
  78. tr.basis[state.up_axis][1] = -tr.basis[state.up_axis][1];
  79. tr.basis[0][state.up_axis] = -tr.basis[0][state.up_axis];
  80. tr.basis[1][state.up_axis] = -tr.basis[1][state.up_axis];
  81. tr.origin[state.up_axis] = -tr.origin[state.up_axis];
  82. }
  83. #endif
  84. //tr.scale(Vector3(state.unit_scale.unit_scale.unit_scale));
  85. return tr;
  86. //return state.matrix_fix * p_transform;
  87. }
  88. static Transform3D _read_transform_from_array(const Vector<float> &p_array, int p_ofs = 0) {
  89. Transform3D tr;
  90. // i wonder why collada matrices are transposed, given that's opposed to opengl..
  91. tr.basis.rows[0][0] = p_array[0 + p_ofs];
  92. tr.basis.rows[0][1] = p_array[1 + p_ofs];
  93. tr.basis.rows[0][2] = p_array[2 + p_ofs];
  94. tr.basis.rows[1][0] = p_array[4 + p_ofs];
  95. tr.basis.rows[1][1] = p_array[5 + p_ofs];
  96. tr.basis.rows[1][2] = p_array[6 + p_ofs];
  97. tr.basis.rows[2][0] = p_array[8 + p_ofs];
  98. tr.basis.rows[2][1] = p_array[9 + p_ofs];
  99. tr.basis.rows[2][2] = p_array[10 + p_ofs];
  100. tr.origin.x = p_array[3 + p_ofs];
  101. tr.origin.y = p_array[7 + p_ofs];
  102. tr.origin.z = p_array[11 + p_ofs];
  103. return tr;
  104. }
  105. /* STRUCTURES */
  106. Transform3D Collada::Node::compute_transform(const Collada &p_state) const {
  107. Transform3D xform;
  108. for (int i = 0; i < xform_list.size(); i++) {
  109. Transform3D xform_step;
  110. const XForm &xf = xform_list[i];
  111. switch (xf.op) {
  112. case XForm::OP_ROTATE: {
  113. if (xf.data.size() >= 4) {
  114. xform_step.rotate(Vector3(xf.data[0], xf.data[1], xf.data[2]), Math::deg_to_rad(xf.data[3]));
  115. }
  116. } break;
  117. case XForm::OP_SCALE: {
  118. if (xf.data.size() >= 3) {
  119. xform_step.scale(Vector3(xf.data[0], xf.data[1], xf.data[2]));
  120. }
  121. } break;
  122. case XForm::OP_TRANSLATE: {
  123. if (xf.data.size() >= 3) {
  124. xform_step.origin = Vector3(xf.data[0], xf.data[1], xf.data[2]);
  125. }
  126. } break;
  127. case XForm::OP_MATRIX: {
  128. if (xf.data.size() >= 16) {
  129. xform_step = _read_transform_from_array(xf.data, 0);
  130. }
  131. } break;
  132. default: {
  133. }
  134. }
  135. xform = xform * xform_step;
  136. }
  137. #ifdef COLLADA_IMPORT_SCALE_SCENE
  138. xform.origin *= p_state.state.unit_scale;
  139. #endif
  140. return xform;
  141. }
  142. Transform3D Collada::Node::get_transform() const {
  143. return default_transform;
  144. }
  145. Transform3D Collada::Node::get_global_transform() const {
  146. if (parent) {
  147. return parent->get_global_transform() * default_transform;
  148. } else {
  149. return default_transform;
  150. }
  151. }
  152. Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
  153. ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
  154. int i = 0;
  155. for (i = 0; i < keys.size(); i++) {
  156. if (keys[i].time > p_time) {
  157. break;
  158. }
  159. }
  160. if (i == 0) {
  161. return keys[0].data;
  162. }
  163. if (i == keys.size()) {
  164. return keys[keys.size() - 1].data;
  165. }
  166. switch (keys[i].interp_type) {
  167. case INTERP_BEZIER: //wait for bezier
  168. case INTERP_LINEAR: {
  169. float c = (p_time - keys[i - 1].time) / (keys[i].time - keys[i - 1].time);
  170. if (keys[i].data.size() == 16) {
  171. //interpolate a matrix
  172. Transform3D src = _read_transform_from_array(keys[i - 1].data);
  173. Transform3D dst = _read_transform_from_array(keys[i].data);
  174. Transform3D interp = c < 0.001 ? src : src.interpolate_with(dst, c);
  175. Vector<float> ret;
  176. ret.resize(16);
  177. Transform3D tr;
  178. // i wonder why collada matrices are transposed, given that's opposed to opengl..
  179. ret.write[0] = interp.basis.rows[0][0];
  180. ret.write[1] = interp.basis.rows[0][1];
  181. ret.write[2] = interp.basis.rows[0][2];
  182. ret.write[4] = interp.basis.rows[1][0];
  183. ret.write[5] = interp.basis.rows[1][1];
  184. ret.write[6] = interp.basis.rows[1][2];
  185. ret.write[8] = interp.basis.rows[2][0];
  186. ret.write[9] = interp.basis.rows[2][1];
  187. ret.write[10] = interp.basis.rows[2][2];
  188. ret.write[3] = interp.origin.x;
  189. ret.write[7] = interp.origin.y;
  190. ret.write[11] = interp.origin.z;
  191. ret.write[12] = 0;
  192. ret.write[13] = 0;
  193. ret.write[14] = 0;
  194. ret.write[15] = 1;
  195. return ret;
  196. } else {
  197. Vector<float> dest;
  198. dest.resize(keys[i].data.size());
  199. for (int j = 0; j < dest.size(); j++) {
  200. dest.write[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
  201. }
  202. return dest;
  203. //interpolate one by one
  204. }
  205. } break;
  206. }
  207. ERR_FAIL_V(Vector<float>());
  208. }
  209. void Collada::_parse_asset(XMLParser &p_parser) {
  210. while (p_parser.read() == OK) {
  211. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  212. String name = p_parser.get_node_name();
  213. if (name == "up_axis") {
  214. p_parser.read();
  215. if (p_parser.get_node_data() == "X_UP") {
  216. state.up_axis = Vector3::AXIS_X;
  217. }
  218. if (p_parser.get_node_data() == "Y_UP") {
  219. state.up_axis = Vector3::AXIS_Y;
  220. }
  221. if (p_parser.get_node_data() == "Z_UP") {
  222. state.up_axis = Vector3::AXIS_Z;
  223. }
  224. COLLADA_PRINT("up axis: " + p_parser.get_node_data());
  225. } else if (name == "unit") {
  226. state.unit_scale = p_parser.get_named_attribute_value("meter").to_float();
  227. COLLADA_PRINT("unit scale: " + rtos(state.unit_scale));
  228. }
  229. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "asset") {
  230. break; //end of <asset>
  231. }
  232. }
  233. }
  234. void Collada::_parse_image(XMLParser &p_parser) {
  235. String id = p_parser.get_named_attribute_value("id");
  236. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  237. if (!p_parser.is_empty()) {
  238. p_parser.skip_section();
  239. }
  240. return;
  241. }
  242. Image image;
  243. if (state.version < State::Version(1, 4, 0)) {
  244. /* <1.4 */
  245. String path = p_parser.get_named_attribute_value("source").strip_edges();
  246. if (!path.contains("://") && path.is_relative_path()) {
  247. // path is relative to file being loaded, so convert to a resource path
  248. image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path.uri_decode()));
  249. }
  250. } else {
  251. while (p_parser.read() == OK) {
  252. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  253. String name = p_parser.get_node_name();
  254. if (name == "init_from") {
  255. p_parser.read();
  256. String path = p_parser.get_node_data().strip_edges().uri_decode();
  257. if (!path.contains("://") && path.is_relative_path()) {
  258. // path is relative to file being loaded, so convert to a resource path
  259. path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path));
  260. } else if (path.find("file:///") == 0) {
  261. path = path.replace_first("file:///", "");
  262. path = ProjectSettings::get_singleton()->localize_path(path);
  263. }
  264. image.path = path;
  265. } else if (name == "data") {
  266. ERR_PRINT("COLLADA Embedded image data not supported!");
  267. } else if (name == "extra" && !p_parser.is_empty()) {
  268. p_parser.skip_section();
  269. }
  270. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "image") {
  271. break; //end of <asset>
  272. }
  273. }
  274. }
  275. state.image_map[id] = image;
  276. }
  277. void Collada::_parse_material(XMLParser &p_parser) {
  278. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  279. if (!p_parser.is_empty()) {
  280. p_parser.skip_section();
  281. }
  282. return;
  283. }
  284. Material material;
  285. String id = p_parser.get_named_attribute_value("id");
  286. if (p_parser.has_attribute("name")) {
  287. material.name = p_parser.get_named_attribute_value("name");
  288. }
  289. if (state.version < State::Version(1, 4, 0)) {
  290. /* <1.4 */
  291. ERR_PRINT("Collada Materials < 1.4 are not supported (yet)");
  292. } else {
  293. while (p_parser.read() == OK) {
  294. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT && p_parser.get_node_name() == "instance_effect") {
  295. material.instance_effect = _uri_to_id(p_parser.get_named_attribute_value("url"));
  296. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "material") {
  297. break; //end of <asset>
  298. }
  299. }
  300. }
  301. state.material_map[id] = material;
  302. }
  303. //! reads floats from inside of xml element until end of xml element
  304. Vector<float> Collada::_read_float_array(XMLParser &p_parser) {
  305. if (p_parser.is_empty()) {
  306. return Vector<float>();
  307. }
  308. Vector<String> splitters;
  309. splitters.push_back(" ");
  310. splitters.push_back("\n");
  311. splitters.push_back("\r");
  312. splitters.push_back("\t");
  313. Vector<float> array;
  314. while (p_parser.read() == OK) {
  315. // TODO: check for comments inside the element
  316. // and ignore them.
  317. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  318. // parse float data
  319. String str = p_parser.get_node_data();
  320. array = str.split_floats_mk(splitters, false);
  321. //array=str.split_floats(" ",false);
  322. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
  323. break; // end parsing text
  324. }
  325. }
  326. return array;
  327. }
  328. Vector<String> Collada::_read_string_array(XMLParser &p_parser) {
  329. if (p_parser.is_empty()) {
  330. return Vector<String>();
  331. }
  332. Vector<String> array;
  333. while (p_parser.read() == OK) {
  334. // TODO: check for comments inside the element
  335. // and ignore them.
  336. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  337. // parse String data
  338. String str = p_parser.get_node_data();
  339. array = str.split_spaces();
  340. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
  341. break; // end parsing text
  342. }
  343. }
  344. return array;
  345. }
  346. Transform3D Collada::_read_transform(XMLParser &p_parser) {
  347. if (p_parser.is_empty()) {
  348. return Transform3D();
  349. }
  350. Vector<String> array;
  351. while (p_parser.read() == OK) {
  352. // TODO: check for comments inside the element
  353. // and ignore them.
  354. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  355. // parse float data
  356. String str = p_parser.get_node_data();
  357. array = str.split_spaces();
  358. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
  359. break; // end parsing text
  360. }
  361. }
  362. ERR_FAIL_COND_V(array.size() != 16, Transform3D());
  363. Vector<float> farr;
  364. farr.resize(16);
  365. for (int i = 0; i < 16; i++) {
  366. farr.write[i] = array[i].to_float();
  367. }
  368. return _read_transform_from_array(farr);
  369. }
  370. String Collada::_read_empty_draw_type(XMLParser &p_parser) {
  371. String empty_draw_type = "";
  372. if (p_parser.is_empty()) {
  373. return empty_draw_type;
  374. }
  375. while (p_parser.read() == OK) {
  376. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  377. empty_draw_type = p_parser.get_node_data();
  378. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
  379. break; // end parsing text
  380. }
  381. }
  382. return empty_draw_type;
  383. }
  384. Variant Collada::_parse_param(XMLParser &p_parser) {
  385. if (p_parser.is_empty()) {
  386. return Variant();
  387. }
  388. String from = p_parser.get_node_name();
  389. Variant data;
  390. while (p_parser.read() == OK) {
  391. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  392. if (p_parser.get_node_name() == "float") {
  393. p_parser.read();
  394. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  395. data = p_parser.get_node_data().to_float();
  396. }
  397. } else if (p_parser.get_node_name() == "float2") {
  398. Vector<float> v2 = _read_float_array(p_parser);
  399. if (v2.size() >= 2) {
  400. data = Vector2(v2[0], v2[1]);
  401. }
  402. } else if (p_parser.get_node_name() == "float3") {
  403. Vector<float> v3 = _read_float_array(p_parser);
  404. if (v3.size() >= 3) {
  405. data = Vector3(v3[0], v3[1], v3[2]);
  406. }
  407. } else if (p_parser.get_node_name() == "float4") {
  408. Vector<float> v4 = _read_float_array(p_parser);
  409. if (v4.size() >= 4) {
  410. data = Color(v4[0], v4[1], v4[2], v4[3]);
  411. }
  412. } else if (p_parser.get_node_name() == "sampler2D") {
  413. while (p_parser.read() == OK) {
  414. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  415. if (p_parser.get_node_name() == "source") {
  416. p_parser.read();
  417. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  418. data = p_parser.get_node_data();
  419. }
  420. }
  421. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "sampler2D") {
  422. break;
  423. }
  424. }
  425. } else if (p_parser.get_node_name() == "surface") {
  426. while (p_parser.read() == OK) {
  427. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  428. if (p_parser.get_node_name() == "init_from") {
  429. p_parser.read();
  430. if (p_parser.get_node_type() == XMLParser::NODE_TEXT) {
  431. data = p_parser.get_node_data();
  432. }
  433. }
  434. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "surface") {
  435. break;
  436. }
  437. }
  438. }
  439. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == from) {
  440. break;
  441. }
  442. }
  443. COLLADA_PRINT("newparam ending " + p_parser.get_node_name());
  444. return data;
  445. }
  446. void Collada::_parse_effect_material(XMLParser &p_parser, Effect &p_effect, String &p_id) {
  447. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  448. if (!p_parser.is_empty()) {
  449. p_parser.skip_section();
  450. }
  451. return;
  452. }
  453. while (p_parser.read() == OK) {
  454. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  455. // first come the tags we descend, but ignore the top-levels
  456. COLLADA_PRINT("node name: " + p_parser.get_node_name());
  457. if (!p_parser.is_empty() &&
  458. (p_parser.get_node_name() == "profile_COMMON" ||
  459. p_parser.get_node_name() == "technique" ||
  460. p_parser.get_node_name() == "extra")) {
  461. _parse_effect_material(p_parser, p_effect, p_id); // try again
  462. } else if (p_parser.get_node_name() == "newparam") {
  463. String name = p_parser.get_named_attribute_value("sid");
  464. Variant value = _parse_param(p_parser);
  465. p_effect.params[name] = value;
  466. COLLADA_PRINT("param: " + name + " value:" + String(value));
  467. } else if (p_parser.get_node_name() == "constant" ||
  468. p_parser.get_node_name() == "lambert" ||
  469. p_parser.get_node_name() == "phong" ||
  470. p_parser.get_node_name() == "blinn") {
  471. COLLADA_PRINT("shade model: " + p_parser.get_node_name());
  472. while (p_parser.read() == OK) {
  473. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  474. String what = p_parser.get_node_name();
  475. if (what == "emission" ||
  476. what == "diffuse" ||
  477. what == "specular" ||
  478. what == "reflective") {
  479. // color or texture types
  480. while (p_parser.read() == OK) {
  481. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  482. if (p_parser.get_node_name() == "color") {
  483. Vector<float> colorarr = _read_float_array(p_parser);
  484. COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
  485. if (colorarr.size() >= 3) {
  486. // alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
  487. Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
  488. if (what == "diffuse") {
  489. p_effect.diffuse.color = color;
  490. }
  491. if (what == "specular") {
  492. p_effect.specular.color = color;
  493. }
  494. if (what == "emission") {
  495. p_effect.emission.color = color;
  496. }
  497. COLLADA_PRINT(what + " color: " + color);
  498. }
  499. } else if (p_parser.get_node_name() == "texture") {
  500. String sampler = p_parser.get_named_attribute_value("texture");
  501. if (!p_effect.params.has(sampler)) {
  502. ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + p_id).utf8().get_data());
  503. } else {
  504. String surface = p_effect.params[sampler];
  505. if (!p_effect.params.has(surface)) {
  506. ERR_PRINT(String("Couldn't find surface: " + surface + " in material:" + p_id).utf8().get_data());
  507. } else {
  508. String uri = p_effect.params[surface];
  509. if (what == "diffuse") {
  510. p_effect.diffuse.texture = uri;
  511. } else if (what == "specular") {
  512. p_effect.specular.texture = uri;
  513. } else if (what == "emission") {
  514. p_effect.emission.texture = uri;
  515. } else if (what == "bump") {
  516. if (p_parser.has_attribute("bumptype") && p_parser.get_named_attribute_value("bumptype") != "NORMALMAP") {
  517. WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
  518. }
  519. p_effect.bump.texture = uri;
  520. }
  521. COLLADA_PRINT(what + " texture: " + uri);
  522. }
  523. }
  524. } else if (!p_parser.is_empty()) {
  525. p_parser.skip_section();
  526. }
  527. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == what) {
  528. break;
  529. }
  530. }
  531. } else if (what == "shininess") {
  532. p_effect.shininess = _parse_param(p_parser);
  533. }
  534. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END &&
  535. (p_parser.get_node_name() == "constant" ||
  536. p_parser.get_node_name() == "lambert" ||
  537. p_parser.get_node_name() == "phong" ||
  538. p_parser.get_node_name() == "blinn")) {
  539. break;
  540. }
  541. }
  542. } else if (p_parser.get_node_name() == "double_sided" || p_parser.get_node_name() == "show_double_sided") { // colladamax / google earth
  543. // 3DS Max / Google Earth double sided extension
  544. p_parser.read();
  545. p_effect.found_double_sided = true;
  546. p_effect.double_sided = p_parser.get_node_data().to_int();
  547. COLLADA_PRINT("double sided: " + itos(p_parser.get_node_data().to_int()));
  548. } else if (p_parser.get_node_name() == "unshaded") {
  549. p_parser.read();
  550. p_effect.unshaded = p_parser.get_node_data().to_int();
  551. } else if (p_parser.get_node_name() == "bump") {
  552. // color or texture types
  553. while (p_parser.read() == OK) {
  554. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  555. if (p_parser.get_node_name() == "texture") {
  556. String sampler = p_parser.get_named_attribute_value("texture");
  557. if (!p_effect.params.has(sampler)) {
  558. ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + p_id).utf8().get_data());
  559. } else {
  560. String surface = p_effect.params[sampler];
  561. if (!p_effect.params.has(surface)) {
  562. ERR_PRINT(String("Couldn't find surface: " + surface + " in material:" + p_id).utf8().get_data());
  563. } else {
  564. String uri = p_effect.params[surface];
  565. if (p_parser.has_attribute("bumptype") && p_parser.get_named_attribute_value("bumptype") != "NORMALMAP") {
  566. WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
  567. }
  568. p_effect.bump.texture = uri;
  569. COLLADA_PRINT(" bump: " + uri);
  570. }
  571. }
  572. } else if (!p_parser.is_empty()) {
  573. p_parser.skip_section();
  574. }
  575. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "bump") {
  576. break;
  577. }
  578. }
  579. } else if (!p_parser.is_empty()) {
  580. p_parser.skip_section();
  581. }
  582. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END &&
  583. (p_parser.get_node_name() == "effect" ||
  584. p_parser.get_node_name() == "profile_COMMON" ||
  585. p_parser.get_node_name() == "technique" ||
  586. p_parser.get_node_name() == "extra")) {
  587. break;
  588. }
  589. }
  590. }
  591. void Collada::_parse_effect(XMLParser &p_parser) {
  592. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  593. if (!p_parser.is_empty()) {
  594. p_parser.skip_section();
  595. }
  596. return;
  597. }
  598. String id = p_parser.get_named_attribute_value("id");
  599. Effect effect;
  600. if (p_parser.has_attribute("name")) {
  601. effect.name = p_parser.get_named_attribute_value("name");
  602. }
  603. _parse_effect_material(p_parser, effect, id);
  604. state.effect_map[id] = effect;
  605. COLLADA_PRINT("Effect ID:" + id);
  606. }
  607. void Collada::_parse_camera(XMLParser &p_parser) {
  608. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  609. if (!p_parser.is_empty()) {
  610. p_parser.skip_section();
  611. }
  612. return;
  613. }
  614. String id = p_parser.get_named_attribute_value("id");
  615. state.camera_data_map[id] = CameraData();
  616. CameraData &camera = state.camera_data_map[id];
  617. while (p_parser.read() == OK) {
  618. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  619. String name = p_parser.get_node_name();
  620. if (name == "perspective") {
  621. camera.mode = CameraData::MODE_PERSPECTIVE;
  622. } else if (name == "orthographic") {
  623. camera.mode = CameraData::MODE_ORTHOGONAL;
  624. } else if (name == "xfov") {
  625. p_parser.read();
  626. camera.perspective.x_fov = p_parser.get_node_data().to_float();
  627. } else if (name == "yfov") {
  628. p_parser.read();
  629. camera.perspective.y_fov = p_parser.get_node_data().to_float();
  630. } else if (name == "xmag") {
  631. p_parser.read();
  632. camera.orthogonal.x_mag = p_parser.get_node_data().to_float();
  633. } else if (name == "ymag") {
  634. p_parser.read();
  635. camera.orthogonal.y_mag = p_parser.get_node_data().to_float();
  636. } else if (name == "aspect_ratio") {
  637. p_parser.read();
  638. camera.aspect = p_parser.get_node_data().to_float();
  639. } else if (name == "znear") {
  640. p_parser.read();
  641. camera.z_near = p_parser.get_node_data().to_float();
  642. } else if (name == "zfar") {
  643. p_parser.read();
  644. camera.z_far = p_parser.get_node_data().to_float();
  645. }
  646. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "camera") {
  647. break; //end of <asset>
  648. }
  649. }
  650. COLLADA_PRINT("Camera ID:" + id);
  651. }
  652. void Collada::_parse_light(XMLParser &p_parser) {
  653. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  654. if (!p_parser.is_empty()) {
  655. p_parser.skip_section();
  656. }
  657. return;
  658. }
  659. String id = p_parser.get_named_attribute_value("id");
  660. state.light_data_map[id] = LightData();
  661. LightData &light = state.light_data_map[id];
  662. while (p_parser.read() == OK) {
  663. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  664. String name = p_parser.get_node_name();
  665. if (name == "ambient") {
  666. light.mode = LightData::MODE_AMBIENT;
  667. } else if (name == "directional") {
  668. light.mode = LightData::MODE_DIRECTIONAL;
  669. } else if (name == "point") {
  670. light.mode = LightData::MODE_OMNI;
  671. } else if (name == "spot") {
  672. light.mode = LightData::MODE_SPOT;
  673. } else if (name == "color") {
  674. p_parser.read();
  675. Vector<float> colorarr = _read_float_array(p_parser);
  676. COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
  677. if (colorarr.size() >= 4) {
  678. // alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
  679. Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
  680. light.color = color;
  681. }
  682. } else if (name == "constant_attenuation") {
  683. p_parser.read();
  684. light.constant_att = p_parser.get_node_data().to_float();
  685. } else if (name == "linear_attenuation") {
  686. p_parser.read();
  687. light.linear_att = p_parser.get_node_data().to_float();
  688. } else if (name == "quadratic_attenuation") {
  689. p_parser.read();
  690. light.quad_att = p_parser.get_node_data().to_float();
  691. } else if (name == "falloff_angle") {
  692. p_parser.read();
  693. light.spot_angle = p_parser.get_node_data().to_float();
  694. } else if (name == "falloff_exponent") {
  695. p_parser.read();
  696. light.spot_exp = p_parser.get_node_data().to_float();
  697. }
  698. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "light") {
  699. break; //end of <asset>
  700. }
  701. }
  702. COLLADA_PRINT("Light ID:" + id);
  703. }
  704. void Collada::_parse_curve_geometry(XMLParser &p_parser, String p_id, String p_name) {
  705. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  706. if (!p_parser.is_empty()) {
  707. p_parser.skip_section();
  708. }
  709. return;
  710. }
  711. //load everything into a pre dictionary
  712. state.curve_data_map[p_id] = CurveData();
  713. CurveData &curvedata = state.curve_data_map[p_id];
  714. curvedata.name = p_name;
  715. String closed = p_parser.get_named_attribute_value_safe("closed").to_lower();
  716. curvedata.closed = closed == "true" || closed == "1";
  717. COLLADA_PRINT("curve name: " + p_name);
  718. String current_source;
  719. // handles geometry node and the curve children in this loop
  720. // read sources with arrays and accessor for each curve
  721. if (p_parser.is_empty()) {
  722. return;
  723. }
  724. while (p_parser.read() == OK) {
  725. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  726. String section = p_parser.get_node_name();
  727. if (section == "source") {
  728. String id = p_parser.get_named_attribute_value("id");
  729. curvedata.sources[id] = CurveData::Source();
  730. current_source = id;
  731. COLLADA_PRINT("source data: " + id);
  732. } else if (section == "float_array" || section == "array") {
  733. // create a new array and read it.
  734. if (curvedata.sources.has(current_source)) {
  735. curvedata.sources[current_source].array = _read_float_array(p_parser);
  736. COLLADA_PRINT("section: " + current_source + " read " + itos(curvedata.sources[current_source].array.size()) + " values.");
  737. }
  738. } else if (section == "Name_array") {
  739. // create a new array and read it.
  740. if (curvedata.sources.has(current_source)) {
  741. curvedata.sources[current_source].sarray = _read_string_array(p_parser);
  742. COLLADA_PRINT("section: " + current_source + " read " + itos(curvedata.sources[current_source].array.size()) + " values.");
  743. }
  744. } else if (section == "technique_common") {
  745. //skip it
  746. } else if (section == "accessor") { // child of source (below a technique tag)
  747. if (curvedata.sources.has(current_source)) {
  748. curvedata.sources[current_source].stride = p_parser.get_named_attribute_value("stride").to_int();
  749. COLLADA_PRINT("section: " + current_source + " stride " + itos(curvedata.sources[current_source].stride));
  750. }
  751. } else if (section == "control_vertices") {
  752. while (p_parser.read() == OK) {
  753. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  754. if (p_parser.get_node_name() == "input") {
  755. String semantic = p_parser.get_named_attribute_value("semantic");
  756. String source = _uri_to_id(p_parser.get_named_attribute_value("source"));
  757. curvedata.control_vertices[semantic] = source;
  758. COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
  759. }
  760. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == section) {
  761. break;
  762. }
  763. }
  764. } else if (!p_parser.is_empty()) {
  765. p_parser.skip_section();
  766. }
  767. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "spline") {
  768. break;
  769. }
  770. }
  771. }
  772. void Collada::_parse_mesh_geometry(XMLParser &p_parser, String p_id, String p_name) {
  773. if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
  774. if (!p_parser.is_empty()) {
  775. p_parser.skip_section();
  776. }
  777. return;
  778. }
  779. //load everything into a pre dictionary
  780. state.mesh_data_map[p_id] = MeshData();
  781. MeshData &meshdata = state.mesh_data_map[p_id];
  782. meshdata.name = p_name;
  783. COLLADA_PRINT("mesh name: " + p_name);
  784. String current_source;
  785. // handles geometry node and the mesh children in this loop
  786. // read sources with arrays and accessor for each mesh
  787. if (p_parser.is_empty()) {
  788. return;
  789. }
  790. while (p_parser.read() == OK) {
  791. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  792. String section = p_parser.get_node_name();
  793. if (section == "source") {
  794. String id = p_parser.get_named_attribute_value("id");
  795. meshdata.sources[id] = MeshData::Source();
  796. current_source = id;
  797. COLLADA_PRINT("source data: " + id);
  798. } else if (section == "float_array" || section == "array") {
  799. // create a new array and read it.
  800. if (meshdata.sources.has(current_source)) {
  801. meshdata.sources[current_source].array = _read_float_array(p_parser);
  802. COLLADA_PRINT("section: " + current_source + " read " + itos(meshdata.sources[current_source].array.size()) + " values.");
  803. }
  804. } else if (section == "technique_common") {
  805. //skip it
  806. } else if (section == "accessor") { // child of source (below a technique tag)
  807. if (meshdata.sources.has(current_source)) {
  808. meshdata.sources[current_source].stride = p_parser.get_named_attribute_value("stride").to_int();
  809. COLLADA_PRINT("section: " + current_source + " stride " + itos(meshdata.sources[current_source].stride));
  810. }
  811. } else if (section == "vertices") {
  812. MeshData::Vertices vert;
  813. String id = p_parser.get_named_attribute_value("id");
  814. int last_ref = 0;
  815. while (p_parser.read() == OK) {
  816. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  817. if (p_parser.get_node_name() == "input") {
  818. String semantic = p_parser.get_named_attribute_value("semantic");
  819. String source = _uri_to_id(p_parser.get_named_attribute_value("source"));
  820. if (semantic == "TEXCOORD") {
  821. semantic = "TEXCOORD" + itos(last_ref++);
  822. }
  823. vert.sources[semantic] = source;
  824. COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
  825. }
  826. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == section) {
  827. break;
  828. }
  829. }
  830. meshdata.vertices[id] = vert;
  831. } else if (section == "triangles" || section == "polylist" || section == "polygons") {
  832. bool polygons = (section == "polygons");
  833. if (polygons) {
  834. WARN_PRINT("Primitive type \"polygons\" is not well supported (concave shapes may fail). To ensure that the geometry is properly imported, please re-export using \"triangles\" or \"polylist\".");
  835. }
  836. MeshData::Primitives prim;
  837. if (p_parser.has_attribute("material")) {
  838. prim.material = p_parser.get_named_attribute_value("material");
  839. }
  840. prim.count = p_parser.get_named_attribute_value("count").to_int();
  841. prim.vertex_size = 0;
  842. int last_ref = 0;
  843. while (p_parser.read() == OK) {
  844. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  845. if (p_parser.get_node_name() == "input") {
  846. String semantic = p_parser.get_named_attribute_value("semantic");
  847. String source = _uri_to_id(p_parser.get_named_attribute_value("source"));
  848. if (semantic == "TEXCOORD") {
  849. semantic = "TEXCOORD" + itos(last_ref++);
  850. }
  851. int offset = p_parser.get_named_attribute_value("offset").to_int();
  852. MeshData::Primitives::SourceRef sref;
  853. sref.source = source;
  854. sref.offset = offset;
  855. prim.sources[semantic] = sref;
  856. prim.vertex_size = MAX(prim.vertex_size, offset + 1);
  857. COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source + " offset: " + itos(offset));
  858. } else if (p_parser.get_node_name() == "p") { //indices
  859. Vector<float> values = _read_float_array(p_parser);
  860. if (polygons) {
  861. ERR_CONTINUE(prim.vertex_size == 0);
  862. prim.polygons.push_back(values.size() / prim.vertex_size);
  863. int from = prim.indices.size();
  864. prim.indices.resize(from + values.size());
  865. for (int i = 0; i < values.size(); i++) {
  866. prim.indices.write[from + i] = values[i];
  867. }
  868. } else if (prim.vertex_size > 0) {
  869. prim.indices = values;
  870. }
  871. COLLADA_PRINT("read " + itos(values.size()) + " index values");
  872. } else if (p_parser.get_node_name() == "vcount") { // primitive
  873. Vector<float> values = _read_float_array(p_parser);
  874. prim.polygons = values;
  875. COLLADA_PRINT("read " + itos(values.size()) + " polygon values");
  876. }
  877. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == section) {
  878. break;
  879. }
  880. }
  881. meshdata.primitives.push_back(prim);
  882. } else if (p_parser.get_node_name() == "double_sided") {
  883. p_parser.read();
  884. meshdata.found_double_sided = true;
  885. meshdata.double_sided = p_parser.get_node_data().to_int();
  886. } else if (p_parser.get_node_name() == "polygons") {
  887. ERR_PRINT("Primitive type \"polygons\" not supported, re-export using \"polylist\" or \"triangles\".");
  888. } else if (!p_parser.is_empty()) {
  889. p_parser.skip_section();
  890. }
  891. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "mesh") {
  892. break;
  893. }
  894. }
  895. }
  896. void Collada::_parse_skin_controller(XMLParser &p_parser, String p_id) {
  897. state.skin_controller_data_map[p_id] = SkinControllerData();
  898. SkinControllerData &skindata = state.skin_controller_data_map[p_id];
  899. skindata.base = _uri_to_id(p_parser.get_named_attribute_value("source"));
  900. String current_source;
  901. while (p_parser.read() == OK) {
  902. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  903. String section = p_parser.get_node_name();
  904. if (section == "bind_shape_matrix") {
  905. skindata.bind_shape = _read_transform(p_parser);
  906. #ifdef COLLADA_IMPORT_SCALE_SCENE
  907. skindata.bind_shape.origin *= state.unit_scale;
  908. #endif
  909. COLLADA_PRINT("skeleton bind shape transform: " + skindata.bind_shape);
  910. } else if (section == "source") {
  911. String id = p_parser.get_named_attribute_value("id");
  912. skindata.sources[id] = SkinControllerData::Source();
  913. current_source = id;
  914. COLLADA_PRINT("source data: " + id);
  915. } else if (section == "float_array" || section == "array") {
  916. // create a new array and read it.
  917. if (skindata.sources.has(current_source)) {
  918. skindata.sources[current_source].array = _read_float_array(p_parser);
  919. COLLADA_PRINT("section: " + current_source + " read " + itos(skindata.sources[current_source].array.size()) + " values.");
  920. }
  921. } else if (section == "Name_array" || section == "IDREF_array") {
  922. // create a new array and read it.
  923. if (section == "IDREF_array") {
  924. skindata.use_idrefs = true;
  925. }
  926. if (skindata.sources.has(current_source)) {
  927. skindata.sources[current_source].sarray = _read_string_array(p_parser);
  928. if (section == "IDREF_array") {
  929. Vector<String> sa = skindata.sources[current_source].sarray;
  930. for (int i = 0; i < sa.size(); i++) {
  931. state.idref_joints.insert(sa[i]);
  932. }
  933. }
  934. COLLADA_PRINT("section: " + current_source + " read " + itos(skindata.sources[current_source].array.size()) + " values.");
  935. }
  936. } else if (section == "technique_common") {
  937. //skip it
  938. } else if (section == "accessor") { // child of source (below a technique tag)
  939. if (skindata.sources.has(current_source)) {
  940. int stride = 1;
  941. if (p_parser.has_attribute("stride")) {
  942. stride = p_parser.get_named_attribute_value("stride").to_int();
  943. }
  944. skindata.sources[current_source].stride = stride;
  945. COLLADA_PRINT("section: " + current_source + " stride " + itos(skindata.sources[current_source].stride));
  946. }
  947. } else if (section == "joints") {
  948. SkinControllerData::Joints joint;
  949. while (p_parser.read() == OK) {
  950. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  951. if (p_parser.get_node_name() == "input") {
  952. String semantic = p_parser.get_named_attribute_value("semantic");
  953. String source = _uri_to_id(p_parser.get_named_attribute_value("source"));
  954. joint.sources[semantic] = source;
  955. COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
  956. }
  957. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == section) {
  958. break;
  959. }
  960. }
  961. skindata.joints = joint;
  962. } else if (section == "vertex_weights") {
  963. SkinControllerData::Weights weights;
  964. weights.count = p_parser.get_named_attribute_value("count").to_int();
  965. while (p_parser.read() == OK) {
  966. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  967. if (p_parser.get_node_name() == "input") {
  968. String semantic = p_parser.get_named_attribute_value("semantic");
  969. String source = _uri_to_id(p_parser.get_named_attribute_value("source"));
  970. int offset = p_parser.get_named_attribute_value("offset").to_int();
  971. SkinControllerData::Weights::SourceRef sref;
  972. sref.source = source;
  973. sref.offset = offset;
  974. weights.sources[semantic] = sref;
  975. COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source + " offset: " + itos(offset));
  976. } else if (p_parser.get_node_name() == "v") { //indices
  977. Vector<float> values = _read_float_array(p_parser);
  978. weights.indices = values;
  979. COLLADA_PRINT("read " + itos(values.size()) + " index values");
  980. } else if (p_parser.get_node_name() == "vcount") { // weightsitive
  981. Vector<float> values = _read_float_array(p_parser);
  982. weights.sets = values;
  983. COLLADA_PRINT("read " + itos(values.size()) + " polygon values");
  984. }
  985. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == section) {
  986. break;
  987. }
  988. }
  989. skindata.weights = weights;
  990. }
  991. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "skin") {
  992. break;
  993. }
  994. }
  995. /* STORE REST MATRICES */
  996. Vector<Transform3D> rests;
  997. ERR_FAIL_COND(!skindata.joints.sources.has("JOINT"));
  998. ERR_FAIL_COND(!skindata.joints.sources.has("INV_BIND_MATRIX"));
  999. String joint_arr = skindata.joints.sources["JOINT"];
  1000. String ibm = skindata.joints.sources["INV_BIND_MATRIX"];
  1001. ERR_FAIL_COND(!skindata.sources.has(joint_arr));
  1002. ERR_FAIL_COND(!skindata.sources.has(ibm));
  1003. SkinControllerData::Source &joint_source = skindata.sources[joint_arr];
  1004. SkinControllerData::Source &ibm_source = skindata.sources[ibm];
  1005. ERR_FAIL_COND(joint_source.sarray.size() != ibm_source.array.size() / 16);
  1006. for (int i = 0; i < joint_source.sarray.size(); i++) {
  1007. String name = joint_source.sarray[i];
  1008. Transform3D xform = _read_transform_from_array(ibm_source.array, i * 16); //<- this is a mistake, it must be applied to vertices
  1009. xform.affine_invert(); // inverse for rest, because it's an inverse
  1010. #ifdef COLLADA_IMPORT_SCALE_SCENE
  1011. xform.origin *= state.unit_scale;
  1012. #endif
  1013. skindata.bone_rest_map[name] = xform;
  1014. }
  1015. }
  1016. void Collada::_parse_morph_controller(XMLParser &p_parser, String p_id) {
  1017. state.morph_controller_data_map[p_id] = MorphControllerData();
  1018. MorphControllerData &morphdata = state.morph_controller_data_map[p_id];
  1019. morphdata.mesh = _uri_to_id(p_parser.get_named_attribute_value("source"));
  1020. morphdata.mode = p_parser.get_named_attribute_value("method");
  1021. String current_source;
  1022. while (p_parser.read() == OK) {
  1023. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1024. String section = p_parser.get_node_name();
  1025. if (section == "source") {
  1026. String id = p_parser.get_named_attribute_value("id");
  1027. morphdata.sources[id] = MorphControllerData::Source();
  1028. current_source = id;
  1029. COLLADA_PRINT("source data: " + id);
  1030. } else if (section == "float_array" || section == "array") {
  1031. // create a new array and read it.
  1032. if (morphdata.sources.has(current_source)) {
  1033. morphdata.sources[current_source].array = _read_float_array(p_parser);
  1034. COLLADA_PRINT("section: " + current_source + " read " + itos(morphdata.sources[current_source].array.size()) + " values.");
  1035. }
  1036. } else if (section == "Name_array" || section == "IDREF_array") {
  1037. // create a new array and read it.
  1038. if (morphdata.sources.has(current_source)) {
  1039. morphdata.sources[current_source].sarray = _read_string_array(p_parser);
  1040. COLLADA_PRINT("section: " + current_source + " read " + itos(morphdata.sources[current_source].array.size()) + " values.");
  1041. }
  1042. } else if (section == "technique_common") {
  1043. //skip it
  1044. } else if (section == "accessor") { // child of source (below a technique tag)
  1045. if (morphdata.sources.has(current_source)) {
  1046. int stride = 1;
  1047. if (p_parser.has_attribute("stride")) {
  1048. stride = p_parser.get_named_attribute_value("stride").to_int();
  1049. }
  1050. morphdata.sources[current_source].stride = stride;
  1051. COLLADA_PRINT("section: " + current_source + " stride " + itos(morphdata.sources[current_source].stride));
  1052. }
  1053. } else if (section == "targets") {
  1054. while (p_parser.read() == OK) {
  1055. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1056. if (p_parser.get_node_name() == "input") {
  1057. String semantic = p_parser.get_named_attribute_value("semantic");
  1058. String source = _uri_to_id(p_parser.get_named_attribute_value("source"));
  1059. morphdata.targets[semantic] = source;
  1060. COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
  1061. }
  1062. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == section) {
  1063. break;
  1064. }
  1065. }
  1066. }
  1067. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "morph") {
  1068. break;
  1069. }
  1070. }
  1071. if (morphdata.targets.has("MORPH_WEIGHT")) {
  1072. state.morph_name_map[morphdata.targets["MORPH_WEIGHT"]] = p_id;
  1073. }
  1074. }
  1075. void Collada::_parse_controller(XMLParser &p_parser) {
  1076. String id = p_parser.get_named_attribute_value("id");
  1077. if (p_parser.is_empty()) {
  1078. return;
  1079. }
  1080. while (p_parser.read() == OK) {
  1081. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1082. String section = p_parser.get_node_name();
  1083. if (section == "skin") {
  1084. _parse_skin_controller(p_parser, id);
  1085. } else if (section == "morph") {
  1086. _parse_morph_controller(p_parser, id);
  1087. }
  1088. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "controller") {
  1089. break;
  1090. }
  1091. }
  1092. }
  1093. Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &p_parser) {
  1094. String type = p_parser.get_node_name();
  1095. NodeGeometry *geom = memnew(NodeGeometry);
  1096. geom->controller = type == "instance_controller";
  1097. geom->source = _uri_to_id(p_parser.get_named_attribute_value_safe("url"));
  1098. if (p_parser.is_empty()) { //nothing else to parse...
  1099. return geom;
  1100. }
  1101. // try to find also many materials and skeletons!
  1102. while (p_parser.read() == OK) {
  1103. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1104. if (p_parser.get_node_name() == "instance_material") {
  1105. String symbol = p_parser.get_named_attribute_value("symbol");
  1106. String target = _uri_to_id(p_parser.get_named_attribute_value("target"));
  1107. NodeGeometry::Material mat;
  1108. mat.target = target;
  1109. geom->material_map[symbol] = mat;
  1110. COLLADA_PRINT("uses material: '" + target + "' on primitive'" + symbol + "'");
  1111. } else if (p_parser.get_node_name() == "skeleton") {
  1112. p_parser.read();
  1113. String uri = _uri_to_id(p_parser.get_node_data());
  1114. if (!uri.is_empty()) {
  1115. geom->skeletons.push_back(uri);
  1116. }
  1117. }
  1118. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == type) {
  1119. break;
  1120. }
  1121. }
  1122. if (geom->controller) {
  1123. if (geom->skeletons.is_empty()) {
  1124. //XSI style
  1125. if (state.skin_controller_data_map.has(geom->source)) {
  1126. SkinControllerData *skin = &state.skin_controller_data_map[geom->source];
  1127. //case where skeletons reference bones with IDREF (XSI)
  1128. ERR_FAIL_COND_V(!skin->joints.sources.has("JOINT"), geom);
  1129. String joint_arr = skin->joints.sources["JOINT"];
  1130. ERR_FAIL_COND_V(!skin->sources.has(joint_arr), geom);
  1131. Collada::SkinControllerData::Source &joint_source = skin->sources[joint_arr];
  1132. geom->skeletons = joint_source.sarray; //quite crazy, but should work.
  1133. }
  1134. }
  1135. }
  1136. return geom;
  1137. }
  1138. Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &p_parser) {
  1139. NodeCamera *cam = memnew(NodeCamera);
  1140. cam->camera = _uri_to_id(p_parser.get_named_attribute_value_safe("url"));
  1141. if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
  1142. cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
  1143. }
  1144. if (p_parser.is_empty()) { //nothing else to parse...
  1145. return cam;
  1146. }
  1147. while (p_parser.read() == OK) {
  1148. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "instance_camera") {
  1149. break;
  1150. }
  1151. }
  1152. return cam;
  1153. }
  1154. Collada::Node *Collada::_parse_visual_instance_light(XMLParser &p_parser) {
  1155. NodeLight *cam = memnew(NodeLight);
  1156. cam->light = _uri_to_id(p_parser.get_named_attribute_value_safe("url"));
  1157. if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
  1158. cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
  1159. }
  1160. if (p_parser.is_empty()) { //nothing else to parse...
  1161. return cam;
  1162. }
  1163. while (p_parser.read() == OK) {
  1164. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "instance_light") {
  1165. break;
  1166. }
  1167. }
  1168. return cam;
  1169. }
  1170. Collada::Node *Collada::_parse_visual_node_instance_data(XMLParser &p_parser) {
  1171. String instance_type = p_parser.get_node_name();
  1172. if (instance_type == "instance_geometry" || instance_type == "instance_controller") {
  1173. return _parse_visual_instance_geometry(p_parser);
  1174. } else if (instance_type == "instance_camera") {
  1175. return _parse_visual_instance_camera(p_parser);
  1176. } else if (instance_type == "instance_light") {
  1177. return _parse_visual_instance_light(p_parser);
  1178. }
  1179. if (p_parser.is_empty()) { //nothing else to parse...
  1180. return nullptr;
  1181. }
  1182. while (p_parser.read() == OK) {
  1183. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == instance_type) {
  1184. break;
  1185. }
  1186. }
  1187. return nullptr;
  1188. }
  1189. Collada::Node *Collada::_parse_visual_scene_node(XMLParser &p_parser) {
  1190. String name;
  1191. String id = p_parser.get_named_attribute_value_safe("id");
  1192. bool found_name = false;
  1193. if (id.is_empty()) {
  1194. id = "%NODEID%" + itos(Math::rand());
  1195. } else {
  1196. found_name = true;
  1197. }
  1198. Vector<Node::XForm> xform_list;
  1199. Vector<Node *> children;
  1200. String empty_draw_type = "";
  1201. Node *node = nullptr;
  1202. name = p_parser.has_attribute("name") ? p_parser.get_named_attribute_value_safe("name") : p_parser.get_named_attribute_value_safe("id");
  1203. if (name.is_empty()) {
  1204. name = id;
  1205. } else {
  1206. found_name = true;
  1207. }
  1208. if ((p_parser.has_attribute("type") && p_parser.get_named_attribute_value("type") == "JOINT") || state.idref_joints.has(name)) {
  1209. // handle a bone
  1210. NodeJoint *joint = memnew(NodeJoint);
  1211. if (p_parser.has_attribute("sid")) { //bones may not have sid
  1212. joint->sid = p_parser.get_named_attribute_value("sid");
  1213. //state.bone_map[joint->sid]=joint;
  1214. } else if (state.idref_joints.has(name)) {
  1215. joint->sid = name; //kind of a cheat but..
  1216. } else if (p_parser.has_attribute("name")) {
  1217. joint->sid = p_parser.get_named_attribute_value_safe("name");
  1218. }
  1219. if (!joint->sid.is_empty()) {
  1220. state.sid_to_node_map[joint->sid] = id;
  1221. }
  1222. node = joint;
  1223. }
  1224. while (p_parser.read() == OK) {
  1225. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1226. String section = p_parser.get_node_name();
  1227. if (section == "translate") {
  1228. Node::XForm xf;
  1229. if (p_parser.has_attribute("sid")) {
  1230. xf.id = p_parser.get_named_attribute_value("sid");
  1231. }
  1232. xf.op = Node::XForm::OP_TRANSLATE;
  1233. Vector<float> xlt = _read_float_array(p_parser);
  1234. xf.data = xlt;
  1235. xform_list.push_back(xf);
  1236. } else if (section == "rotate") {
  1237. Node::XForm xf;
  1238. if (p_parser.has_attribute("sid")) {
  1239. xf.id = p_parser.get_named_attribute_value("sid");
  1240. }
  1241. xf.op = Node::XForm::OP_ROTATE;
  1242. Vector<float> rot = _read_float_array(p_parser);
  1243. xf.data = rot;
  1244. xform_list.push_back(xf);
  1245. } else if (section == "scale") {
  1246. Node::XForm xf;
  1247. if (p_parser.has_attribute("sid")) {
  1248. xf.id = p_parser.get_named_attribute_value("sid");
  1249. }
  1250. xf.op = Node::XForm::OP_SCALE;
  1251. Vector<float> scale = _read_float_array(p_parser);
  1252. xf.data = scale;
  1253. xform_list.push_back(xf);
  1254. } else if (section == "matrix") {
  1255. Node::XForm xf;
  1256. if (p_parser.has_attribute("sid")) {
  1257. xf.id = p_parser.get_named_attribute_value("sid");
  1258. }
  1259. xf.op = Node::XForm::OP_MATRIX;
  1260. Vector<float> matrix = _read_float_array(p_parser);
  1261. xf.data = matrix;
  1262. String mtx;
  1263. for (int i = 0; i < matrix.size(); i++) {
  1264. mtx += " " + rtos(matrix[i]);
  1265. }
  1266. xform_list.push_back(xf);
  1267. } else if (section == "visibility") {
  1268. Node::XForm xf;
  1269. if (p_parser.has_attribute("sid")) {
  1270. xf.id = p_parser.get_named_attribute_value("sid");
  1271. }
  1272. xf.op = Node::XForm::OP_VISIBILITY;
  1273. Vector<float> visible = _read_float_array(p_parser);
  1274. xf.data = visible;
  1275. xform_list.push_back(xf);
  1276. } else if (section == "empty_draw_type") {
  1277. empty_draw_type = _read_empty_draw_type(p_parser);
  1278. } else if (section == "technique" || section == "extra") {
  1279. } else if (section != "node") {
  1280. //usually what defines the type of node
  1281. if (section.begins_with("instance_")) {
  1282. if (!node) {
  1283. node = _parse_visual_node_instance_data(p_parser);
  1284. } else {
  1285. ERR_PRINT("Multiple instance_* not supported.");
  1286. }
  1287. }
  1288. } else {
  1289. /* Found a child node!! what to do..*/
  1290. Node *child = _parse_visual_scene_node(p_parser);
  1291. children.push_back(child);
  1292. }
  1293. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "node") {
  1294. break;
  1295. }
  1296. }
  1297. if (!node) {
  1298. node = memnew(Node); //generic node, nothing of relevance found
  1299. }
  1300. node->noname = !found_name;
  1301. node->xform_list = xform_list;
  1302. node->children = children;
  1303. for (int i = 0; i < children.size(); i++) {
  1304. node->children[i]->parent = node;
  1305. }
  1306. node->name = name;
  1307. node->id = id;
  1308. node->empty_draw_type = empty_draw_type;
  1309. if (node->children.size() == 1) {
  1310. if (node->children[0]->noname && !node->noname) {
  1311. node->children[0]->name = node->name;
  1312. node->name = node->name + "-base";
  1313. }
  1314. }
  1315. node->default_transform = node->compute_transform(*this);
  1316. state.scene_map[id] = node;
  1317. return node;
  1318. }
  1319. void Collada::_parse_visual_scene(XMLParser &p_parser) {
  1320. String id = p_parser.get_named_attribute_value("id");
  1321. if (p_parser.is_empty()) {
  1322. return;
  1323. }
  1324. state.visual_scene_map[id] = VisualScene();
  1325. VisualScene &vscene = state.visual_scene_map[id];
  1326. if (p_parser.has_attribute("name")) {
  1327. vscene.name = p_parser.get_named_attribute_value("name");
  1328. }
  1329. while (p_parser.read() == OK) {
  1330. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1331. String section = p_parser.get_node_name();
  1332. if (section == "node") {
  1333. vscene.root_nodes.push_back(_parse_visual_scene_node(p_parser));
  1334. }
  1335. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "visual_scene") {
  1336. break;
  1337. }
  1338. }
  1339. COLLADA_PRINT("Scene ID:" + id);
  1340. }
  1341. void Collada::_parse_animation(XMLParser &p_parser) {
  1342. if (!(state.import_flags & IMPORT_FLAG_ANIMATION)) {
  1343. if (!p_parser.is_empty()) {
  1344. p_parser.skip_section();
  1345. }
  1346. return;
  1347. }
  1348. HashMap<String, Vector<float>> float_sources;
  1349. HashMap<String, Vector<String>> string_sources;
  1350. HashMap<String, int> source_strides;
  1351. HashMap<String, HashMap<String, String>> samplers;
  1352. HashMap<String, Vector<String>> source_param_names;
  1353. HashMap<String, Vector<String>> source_param_types;
  1354. String id = "";
  1355. if (p_parser.has_attribute("id")) {
  1356. id = p_parser.get_named_attribute_value("id");
  1357. }
  1358. String current_source;
  1359. String current_sampler;
  1360. Vector<String> channel_sources;
  1361. Vector<String> channel_targets;
  1362. while (p_parser.read() == OK) {
  1363. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1364. String name = p_parser.get_node_name();
  1365. if (name == "source") {
  1366. current_source = p_parser.get_named_attribute_value("id");
  1367. source_param_names[current_source] = Vector<String>();
  1368. source_param_types[current_source] = Vector<String>();
  1369. } else if (name == "float_array") {
  1370. if (!current_source.is_empty()) {
  1371. float_sources[current_source] = _read_float_array(p_parser);
  1372. }
  1373. } else if (name == "Name_array") {
  1374. if (!current_source.is_empty()) {
  1375. string_sources[current_source] = _read_string_array(p_parser);
  1376. }
  1377. } else if (name == "accessor") {
  1378. if (!current_source.is_empty() && p_parser.has_attribute("stride")) {
  1379. source_strides[current_source] = p_parser.get_named_attribute_value("stride").to_int();
  1380. }
  1381. } else if (name == "sampler") {
  1382. current_sampler = p_parser.get_named_attribute_value("id");
  1383. samplers[current_sampler] = HashMap<String, String>();
  1384. } else if (name == "param") {
  1385. if (p_parser.has_attribute("name")) {
  1386. source_param_names[current_source].push_back(p_parser.get_named_attribute_value("name"));
  1387. } else {
  1388. source_param_names[current_source].push_back("");
  1389. }
  1390. if (p_parser.has_attribute("type")) {
  1391. source_param_types[current_source].push_back(p_parser.get_named_attribute_value("type"));
  1392. } else {
  1393. source_param_types[current_source].push_back("");
  1394. }
  1395. } else if (name == "input") {
  1396. if (!current_sampler.is_empty()) {
  1397. samplers[current_sampler][p_parser.get_named_attribute_value("semantic")] = p_parser.get_named_attribute_value("source");
  1398. }
  1399. } else if (name == "channel") {
  1400. channel_sources.push_back(p_parser.get_named_attribute_value("source"));
  1401. channel_targets.push_back(p_parser.get_named_attribute_value("target"));
  1402. }
  1403. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "animation") {
  1404. break; //end of <asset>
  1405. }
  1406. }
  1407. for (int i = 0; i < channel_sources.size(); i++) {
  1408. String source = _uri_to_id(channel_sources[i]);
  1409. String target = channel_targets[i];
  1410. ERR_CONTINUE(!samplers.has(source));
  1411. HashMap<String, String> &sampler = samplers[source];
  1412. ERR_CONTINUE(!sampler.has("INPUT")); //no input semantic? wtf?
  1413. String input_id = _uri_to_id(sampler["INPUT"]);
  1414. COLLADA_PRINT("input id is " + input_id);
  1415. ERR_CONTINUE(!float_sources.has(input_id));
  1416. ERR_CONTINUE(!sampler.has("OUTPUT"));
  1417. String output_id = _uri_to_id(sampler["OUTPUT"]);
  1418. ERR_CONTINUE(!float_sources.has(output_id));
  1419. ERR_CONTINUE(!source_param_names.has(output_id));
  1420. Vector<String> &names = source_param_names[output_id];
  1421. for (int l = 0; l < names.size(); l++) {
  1422. String name = names[l];
  1423. Vector<float> &time_keys = float_sources[input_id];
  1424. int key_count = time_keys.size();
  1425. AnimationTrack track; //begin crating track
  1426. track.id = id;
  1427. track.keys.resize(key_count);
  1428. for (int j = 0; j < key_count; j++) {
  1429. track.keys.write[j].time = time_keys[j];
  1430. state.animation_length = MAX(state.animation_length, time_keys[j]);
  1431. }
  1432. //now read actual values
  1433. int stride = 1;
  1434. if (source_strides.has(output_id)) {
  1435. stride = source_strides[output_id];
  1436. }
  1437. int output_len = stride / names.size();
  1438. ERR_CONTINUE(output_len == 0);
  1439. ERR_CONTINUE(!float_sources.has(output_id));
  1440. Vector<float> &output = float_sources[output_id];
  1441. ERR_CONTINUE_MSG((output.size() / stride) != key_count, "Wrong number of keys in output.");
  1442. for (int j = 0; j < key_count; j++) {
  1443. track.keys.write[j].data.resize(output_len);
  1444. for (int k = 0; k < output_len; k++) {
  1445. track.keys.write[j].data.write[k] = output[l + j * stride + k]; //super weird but should work:
  1446. }
  1447. }
  1448. if (sampler.has("INTERPOLATION")) {
  1449. String interp_id = _uri_to_id(sampler["INTERPOLATION"]);
  1450. ERR_CONTINUE(!string_sources.has(interp_id));
  1451. Vector<String> &interps = string_sources[interp_id];
  1452. ERR_CONTINUE(interps.size() != key_count);
  1453. for (int j = 0; j < key_count; j++) {
  1454. if (interps[j] == "BEZIER") {
  1455. track.keys.write[j].interp_type = AnimationTrack::INTERP_BEZIER;
  1456. } else {
  1457. track.keys.write[j].interp_type = AnimationTrack::INTERP_LINEAR;
  1458. }
  1459. }
  1460. }
  1461. if (sampler.has("IN_TANGENT") && sampler.has("OUT_TANGENT")) {
  1462. //bezier control points..
  1463. String intangent_id = _uri_to_id(sampler["IN_TANGENT"]);
  1464. ERR_CONTINUE(!float_sources.has(intangent_id));
  1465. Vector<float> &intangents = float_sources[intangent_id];
  1466. ERR_CONTINUE(intangents.size() != key_count * 2 * names.size());
  1467. String outangent_id = _uri_to_id(sampler["OUT_TANGENT"]);
  1468. ERR_CONTINUE(!float_sources.has(outangent_id));
  1469. Vector<float> &outangents = float_sources[outangent_id];
  1470. ERR_CONTINUE(outangents.size() != key_count * 2 * names.size());
  1471. for (int j = 0; j < key_count; j++) {
  1472. track.keys.write[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
  1473. track.keys.write[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
  1474. }
  1475. }
  1476. if (target.contains("/")) { //transform component
  1477. track.target = target.get_slicec('/', 0);
  1478. track.param = target.get_slicec('/', 1);
  1479. if (track.param.contains(".")) {
  1480. track.component = track.param.get_slice(".", 1).to_upper();
  1481. }
  1482. track.param = track.param.get_slice(".", 0);
  1483. if (names.size() > 1 && track.component.is_empty()) {
  1484. //this is a guess because the collada spec is ambiguous here...
  1485. //i suppose if you have many names (outputs) you can't use a component and i should abide to that.
  1486. track.component = name;
  1487. }
  1488. } else {
  1489. track.target = target;
  1490. }
  1491. state.animation_tracks.push_back(track);
  1492. if (!state.referenced_tracks.has(target)) {
  1493. state.referenced_tracks[target] = Vector<int>();
  1494. }
  1495. state.referenced_tracks[target].push_back(state.animation_tracks.size() - 1);
  1496. if (!id.is_empty()) {
  1497. if (!state.by_id_tracks.has(id)) {
  1498. state.by_id_tracks[id] = Vector<int>();
  1499. }
  1500. state.by_id_tracks[id].push_back(state.animation_tracks.size() - 1);
  1501. }
  1502. COLLADA_PRINT("loaded animation with " + itos(key_count) + " keys");
  1503. }
  1504. }
  1505. }
  1506. void Collada::_parse_animation_clip(XMLParser &p_parser) {
  1507. if (!(state.import_flags & IMPORT_FLAG_ANIMATION)) {
  1508. if (!p_parser.is_empty()) {
  1509. p_parser.skip_section();
  1510. }
  1511. return;
  1512. }
  1513. AnimationClip clip;
  1514. if (p_parser.has_attribute("name")) {
  1515. clip.name = p_parser.get_named_attribute_value("name");
  1516. } else if (p_parser.has_attribute("id")) {
  1517. clip.name = p_parser.get_named_attribute_value("id");
  1518. }
  1519. if (p_parser.has_attribute("start")) {
  1520. clip.begin = p_parser.get_named_attribute_value("start").to_float();
  1521. }
  1522. if (p_parser.has_attribute("end")) {
  1523. clip.end = p_parser.get_named_attribute_value("end").to_float();
  1524. }
  1525. while (p_parser.read() == OK) {
  1526. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1527. String name = p_parser.get_node_name();
  1528. if (name == "instance_animation") {
  1529. String url = _uri_to_id(p_parser.get_named_attribute_value("url"));
  1530. clip.tracks.push_back(url);
  1531. }
  1532. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "animation_clip") {
  1533. break; //end of <asset>
  1534. }
  1535. }
  1536. state.animation_clips.push_back(clip);
  1537. }
  1538. void Collada::_parse_scene(XMLParser &p_parser) {
  1539. if (p_parser.is_empty()) {
  1540. return;
  1541. }
  1542. while (p_parser.read() == OK) {
  1543. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1544. String name = p_parser.get_node_name();
  1545. if (name == "instance_visual_scene") {
  1546. state.root_visual_scene = _uri_to_id(p_parser.get_named_attribute_value("url"));
  1547. } else if (name == "instance_physics_scene") {
  1548. state.root_physics_scene = _uri_to_id(p_parser.get_named_attribute_value("url"));
  1549. }
  1550. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "scene") {
  1551. break; //end of <asset>
  1552. }
  1553. }
  1554. }
  1555. void Collada::_parse_library(XMLParser &p_parser) {
  1556. if (p_parser.is_empty()) {
  1557. return;
  1558. }
  1559. while (p_parser.read() == OK) {
  1560. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1561. String name = p_parser.get_node_name();
  1562. COLLADA_PRINT("library name is: " + name);
  1563. if (name == "image") {
  1564. _parse_image(p_parser);
  1565. } else if (name == "material") {
  1566. _parse_material(p_parser);
  1567. } else if (name == "effect") {
  1568. _parse_effect(p_parser);
  1569. } else if (name == "camera") {
  1570. _parse_camera(p_parser);
  1571. } else if (name == "light") {
  1572. _parse_light(p_parser);
  1573. } else if (name == "geometry") {
  1574. String id = p_parser.get_named_attribute_value("id");
  1575. String name2 = p_parser.get_named_attribute_value_safe("name");
  1576. while (p_parser.read() == OK) {
  1577. if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1578. if (p_parser.get_node_name() == "mesh") {
  1579. state.mesh_name_map[id] = (!name2.is_empty()) ? name2 : id;
  1580. _parse_mesh_geometry(p_parser, id, name2);
  1581. } else if (p_parser.get_node_name() == "spline") {
  1582. state.mesh_name_map[id] = (!name2.is_empty()) ? name2 : id;
  1583. _parse_curve_geometry(p_parser, id, name2);
  1584. } else if (!p_parser.is_empty()) {
  1585. p_parser.skip_section();
  1586. }
  1587. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name() == "geometry") {
  1588. break;
  1589. }
  1590. }
  1591. } else if (name == "controller") {
  1592. _parse_controller(p_parser);
  1593. } else if (name == "animation") {
  1594. _parse_animation(p_parser);
  1595. } else if (name == "animation_clip") {
  1596. _parse_animation_clip(p_parser);
  1597. } else if (name == "visual_scene") {
  1598. COLLADA_PRINT("visual scene");
  1599. _parse_visual_scene(p_parser);
  1600. } else if (!p_parser.is_empty()) {
  1601. p_parser.skip_section();
  1602. }
  1603. } else if (p_parser.get_node_type() == XMLParser::NODE_ELEMENT_END && p_parser.get_node_name().begins_with("library_")) {
  1604. break; //end of <asset>
  1605. }
  1606. }
  1607. }
  1608. void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
  1609. if (p_node->type == Node::TYPE_JOINT) {
  1610. NodeJoint *nj = static_cast<NodeJoint *>(p_node);
  1611. nj->owner = p_owner;
  1612. for (int i = 0; i < nj->children.size(); i++) {
  1613. _joint_set_owner(nj->children.write[i], p_owner);
  1614. }
  1615. }
  1616. }
  1617. void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton) {
  1618. Node *node = *p_node;
  1619. if (node->type == Node::TYPE_JOINT) {
  1620. if (!p_skeleton) {
  1621. // ohohohoohoo it's a joint node, time to work!
  1622. NodeSkeleton *sk = memnew(NodeSkeleton);
  1623. *p_node = sk;
  1624. sk->children.push_back(node);
  1625. sk->parent = node->parent;
  1626. node->parent = sk;
  1627. p_skeleton = sk;
  1628. }
  1629. NodeJoint *nj = static_cast<NodeJoint *>(node);
  1630. nj->owner = p_skeleton;
  1631. } else {
  1632. p_skeleton = nullptr;
  1633. }
  1634. for (int i = 0; i < node->children.size(); i++) {
  1635. _create_skeletons(&node->children.write[i], p_skeleton);
  1636. }
  1637. }
  1638. bool Collada::_remove_node(Node *p_parent, Node *p_node) {
  1639. for (int i = 0; i < p_parent->children.size(); i++) {
  1640. if (p_parent->children[i] == p_node) {
  1641. p_parent->children.remove_at(i);
  1642. return true;
  1643. }
  1644. if (_remove_node(p_parent->children[i], p_node)) {
  1645. return true;
  1646. }
  1647. }
  1648. return false;
  1649. }
  1650. void Collada::_remove_node(VisualScene *p_vscene, Node *p_node) {
  1651. for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
  1652. if (p_vscene->root_nodes[i] == p_node) {
  1653. p_vscene->root_nodes.remove_at(i);
  1654. return;
  1655. }
  1656. if (_remove_node(p_vscene->root_nodes[i], p_node)) {
  1657. return;
  1658. }
  1659. }
  1660. ERR_PRINT("ERROR: Not found node to remove?");
  1661. }
  1662. void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
  1663. if (p_node->type == Node::TYPE_GEOMETRY) {
  1664. NodeGeometry *gnode = static_cast<NodeGeometry *>(p_node);
  1665. if (gnode->controller) {
  1666. // recount skeletons used
  1667. HashSet<NodeSkeleton *> skeletons;
  1668. for (int i = 0; i < gnode->skeletons.size(); i++) {
  1669. String nodeid = gnode->skeletons[i];
  1670. ERR_CONTINUE(!state.scene_map.has(nodeid)); //weird, it should have it...
  1671. NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]);
  1672. ERR_CONTINUE(!nj); //broken collada
  1673. ERR_CONTINUE(!nj->owner); //weird, node should have a skeleton owner
  1674. skeletons.insert(nj->owner);
  1675. }
  1676. if (skeletons.size() > 1) {
  1677. //do the merger!!
  1678. HashSet<NodeSkeleton *>::Iterator E = skeletons.begin();
  1679. NodeSkeleton *base = *E;
  1680. for (++E; E; ++E) {
  1681. NodeSkeleton *merged = *E;
  1682. _remove_node(p_vscene, merged);
  1683. for (int i = 0; i < merged->children.size(); i++) {
  1684. _joint_set_owner(merged->children[i], base);
  1685. base->children.push_back(merged->children[i]);
  1686. merged->children[i]->parent = base;
  1687. }
  1688. merged->children.clear(); //take children from it
  1689. memdelete(merged);
  1690. }
  1691. }
  1692. }
  1693. }
  1694. for (int i = 0; i < p_node->children.size(); i++) {
  1695. _merge_skeletons(p_vscene, p_node->children[i]);
  1696. }
  1697. }
  1698. void Collada::_merge_skeletons2(VisualScene *p_vscene) {
  1699. for (KeyValue<String, SkinControllerData> &E : state.skin_controller_data_map) {
  1700. SkinControllerData &cd = E.value;
  1701. NodeSkeleton *skeleton = nullptr;
  1702. for (const KeyValue<String, Transform3D> &F : cd.bone_rest_map) {
  1703. String name;
  1704. if (!state.sid_to_node_map.has(F.key)) {
  1705. continue;
  1706. }
  1707. name = state.sid_to_node_map[F.key];
  1708. ERR_CONTINUE(!state.scene_map.has(name));
  1709. Node *node = state.scene_map[name];
  1710. ERR_CONTINUE(node->type != Node::TYPE_JOINT);
  1711. NodeSkeleton *sk = nullptr;
  1712. while (node && !sk) {
  1713. if (node->type == Node::TYPE_SKELETON) {
  1714. sk = static_cast<NodeSkeleton *>(node);
  1715. }
  1716. node = node->parent;
  1717. }
  1718. ERR_CONTINUE(!sk);
  1719. if (!skeleton) {
  1720. skeleton = sk;
  1721. continue;
  1722. }
  1723. if (skeleton != sk) {
  1724. //whoa.. wtf, merge.
  1725. _remove_node(p_vscene, sk);
  1726. for (int i = 0; i < sk->children.size(); i++) {
  1727. _joint_set_owner(sk->children[i], skeleton);
  1728. skeleton->children.push_back(sk->children[i]);
  1729. sk->children[i]->parent = skeleton;
  1730. }
  1731. sk->children.clear(); //take children from it
  1732. memdelete(sk);
  1733. }
  1734. }
  1735. }
  1736. }
  1737. bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
  1738. Node *node = p_node;
  1739. if (node->type == Node::TYPE_SKELETON && node->parent && node->parent->type == Node::TYPE_NODE && node->parent->children.size() == 1) {
  1740. //replace parent by this...
  1741. Node *parent = node->parent;
  1742. //i wonder if this is alright.. i think it is since created skeleton (first joint) is already animated by bone..
  1743. node->id = parent->id;
  1744. node->name = parent->name;
  1745. node->xform_list = parent->xform_list;
  1746. node->default_transform = parent->default_transform;
  1747. state.scene_map[node->id] = node;
  1748. node->parent = parent->parent;
  1749. if (parent->parent) {
  1750. Node *gp = parent->parent;
  1751. bool found = false;
  1752. for (int i = 0; i < gp->children.size(); i++) {
  1753. if (gp->children[i] == parent) {
  1754. gp->children.write[i] = node;
  1755. found = true;
  1756. break;
  1757. }
  1758. }
  1759. if (!found) {
  1760. ERR_PRINT("BUG");
  1761. }
  1762. } else {
  1763. bool found = false;
  1764. for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
  1765. if (p_vscene->root_nodes[i] == parent) {
  1766. p_vscene->root_nodes.write[i] = node;
  1767. found = true;
  1768. break;
  1769. }
  1770. }
  1771. if (!found) {
  1772. ERR_PRINT("BUG");
  1773. }
  1774. }
  1775. parent->children.clear();
  1776. memdelete(parent);
  1777. return true;
  1778. }
  1779. for (int i = 0; i < node->children.size(); i++) {
  1780. if (_optimize_skeletons(p_vscene, node->children[i])) {
  1781. return false; //stop processing, go up
  1782. }
  1783. }
  1784. return false;
  1785. }
  1786. bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, List<Node *> *p_mgeom) {
  1787. // Bind Shape Matrix scales the bones and makes them gigantic, so the matrix then shrinks the model?
  1788. // Solution: apply the Bind Shape Matrix to the VERTICES, and if the object comes scaled, it seems to be left alone!
  1789. if (p_node->type == Node::TYPE_GEOMETRY) {
  1790. NodeGeometry *ng = static_cast<NodeGeometry *>(p_node);
  1791. if (ng->ignore_anim) {
  1792. return false; //already made child of skeleton and processeg
  1793. }
  1794. if (ng->controller && ng->skeletons.size()) {
  1795. String nodeid = ng->skeletons[0];
  1796. ERR_FAIL_COND_V(!state.scene_map.has(nodeid), false); //weird, it should have it...
  1797. NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]);
  1798. ERR_FAIL_COND_V(!nj, false);
  1799. ERR_FAIL_COND_V(!nj->owner, false); //weird, node should have a skeleton owner
  1800. NodeSkeleton *sk = nj->owner;
  1801. Node *p = sk->parent;
  1802. bool node_is_parent_of_skeleton = false;
  1803. while (p) {
  1804. if (p == p_node) {
  1805. node_is_parent_of_skeleton = true;
  1806. break;
  1807. }
  1808. p = p->parent; // try again
  1809. }
  1810. ERR_FAIL_COND_V(node_is_parent_of_skeleton, false);
  1811. //this should be correct
  1812. ERR_FAIL_COND_V(!state.skin_controller_data_map.has(ng->source), false);
  1813. SkinControllerData &skin = state.skin_controller_data_map[ng->source];
  1814. Transform3D skel_inv = sk->get_global_transform().affine_inverse();
  1815. p_node->default_transform = skel_inv * (skin.bind_shape /* p_node->get_global_transform()*/); // i honestly have no idea what to do with a previous model xform.. most exporters ignore it
  1816. //make rests relative to the skeleton (they seem to be always relative to world)
  1817. for (KeyValue<String, Transform3D> &E : skin.bone_rest_map) {
  1818. E.value = skel_inv * E.value; //make the bone rest local to the skeleton
  1819. state.bone_rest_map[E.key] = E.value; // make it remember where the bone is globally, now that it's relative
  1820. }
  1821. //but most exporters seem to work only if i do this..
  1822. //p_node->default_transform = p_node->get_global_transform();
  1823. //p_node->default_transform=Transform3D(); //this seems to be correct, because bind shape makes the object local to the skeleton
  1824. p_node->ignore_anim = true; // collada may animate this later, if it does, then this is not supported (redo your original asset and don't animate the base mesh)
  1825. p_node->parent = sk;
  1826. //sk->children.push_back(0,p_node); //avoid INFINITE loop
  1827. p_mgeom->push_back(p_node);
  1828. return true;
  1829. }
  1830. }
  1831. for (int i = 0; i < p_node->children.size(); i++) {
  1832. if (_move_geometry_to_skeletons(p_vscene, p_node->children[i], p_mgeom)) {
  1833. p_node->children.remove_at(i);
  1834. i--;
  1835. }
  1836. }
  1837. return false;
  1838. }
  1839. void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
  1840. if (p_node->type == Node::TYPE_GEOMETRY) {
  1841. NodeGeometry *nj = static_cast<NodeGeometry *>(p_node);
  1842. if (nj->controller) {
  1843. String base = nj->source;
  1844. while (!base.is_empty() && !state.mesh_data_map.has(base)) {
  1845. if (state.skin_controller_data_map.has(base)) {
  1846. SkinControllerData &sk = state.skin_controller_data_map[base];
  1847. base = sk.base;
  1848. } else if (state.morph_controller_data_map.has(base)) {
  1849. state.morph_ownership_map[base] = nj->id;
  1850. break;
  1851. } else {
  1852. ERR_FAIL_MSG("Invalid scene.");
  1853. }
  1854. }
  1855. }
  1856. }
  1857. for (int i = 0; i < p_node->children.size(); i++) {
  1858. _find_morph_nodes(p_vscene, p_node->children[i]);
  1859. }
  1860. }
  1861. void Collada::_optimize() {
  1862. for (KeyValue<String, VisualScene> &E : state.visual_scene_map) {
  1863. VisualScene &vs = E.value;
  1864. for (int i = 0; i < vs.root_nodes.size(); i++) {
  1865. _create_skeletons(&vs.root_nodes.write[i]);
  1866. }
  1867. for (int i = 0; i < vs.root_nodes.size(); i++) {
  1868. _merge_skeletons(&vs, vs.root_nodes[i]);
  1869. }
  1870. _merge_skeletons2(&vs);
  1871. for (int i = 0; i < vs.root_nodes.size(); i++) {
  1872. _optimize_skeletons(&vs, vs.root_nodes[i]);
  1873. }
  1874. for (int i = 0; i < vs.root_nodes.size(); i++) {
  1875. List<Node *> mgeom;
  1876. if (_move_geometry_to_skeletons(&vs, vs.root_nodes[i], &mgeom)) {
  1877. vs.root_nodes.remove_at(i);
  1878. i--;
  1879. }
  1880. while (!mgeom.is_empty()) {
  1881. Node *n = mgeom.front()->get();
  1882. n->parent->children.push_back(n);
  1883. mgeom.pop_front();
  1884. }
  1885. }
  1886. for (int i = 0; i < vs.root_nodes.size(); i++) {
  1887. _find_morph_nodes(&vs, vs.root_nodes[i]);
  1888. }
  1889. }
  1890. }
  1891. int Collada::get_uv_channel(String p_name) {
  1892. if (!channel_map.has(p_name)) {
  1893. ERR_FAIL_COND_V(channel_map.size() == 2, 0);
  1894. channel_map[p_name] = channel_map.size();
  1895. }
  1896. return channel_map[p_name];
  1897. }
  1898. Error Collada::load(const String &p_path, int p_flags) {
  1899. Ref<XMLParser> parserr = memnew(XMLParser);
  1900. XMLParser &parser = *parserr.ptr();
  1901. Error err = parser.open(p_path);
  1902. ERR_FAIL_COND_V_MSG(err, err, "Cannot open Collada file '" + p_path + "'.");
  1903. state.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
  1904. state.import_flags = p_flags;
  1905. /* Skip headers */
  1906. while ((err = parser.read()) == OK) {
  1907. if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
  1908. if (parser.get_node_name() == "COLLADA") {
  1909. break;
  1910. } else if (!parser.is_empty()) {
  1911. parser.skip_section(); // unknown section, likely headers
  1912. }
  1913. }
  1914. }
  1915. ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CORRUPT, "Corrupted Collada file '" + p_path + "'.");
  1916. /* Start loading Collada */
  1917. {
  1918. //version
  1919. String version = parser.get_named_attribute_value("version");
  1920. state.version.major = version.get_slice(".", 0).to_int();
  1921. state.version.minor = version.get_slice(".", 1).to_int();
  1922. state.version.rev = version.get_slice(".", 2).to_int();
  1923. COLLADA_PRINT("Collada VERSION: " + version);
  1924. }
  1925. while ((err = parser.read()) == OK) {
  1926. /* Read all the main sections.. */
  1927. if (parser.get_node_type() != XMLParser::NODE_ELEMENT) {
  1928. continue; //no idea what this may be, but skipping anyway
  1929. }
  1930. String section = parser.get_node_name();
  1931. COLLADA_PRINT("section: " + section);
  1932. if (section == "asset") {
  1933. _parse_asset(parser);
  1934. } else if (section.begins_with("library_")) {
  1935. _parse_library(parser);
  1936. } else if (section == "scene") {
  1937. _parse_scene(parser);
  1938. } else if (!parser.is_empty()) {
  1939. parser.skip_section(); // unknown section, likely headers
  1940. }
  1941. }
  1942. _optimize();
  1943. return OK;
  1944. }
  1945. Collada::Collada() {
  1946. }