collada.cpp 74 KB

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