dae.js 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903
  1. /**
  2. * @author Tim Knip / http://www.floorplanner.com/ / tim at floorplanner.com
  3. */
  4. var DAE = (function() {
  5. var COLLADA = null;
  6. var scene = null;
  7. var daeScene;
  8. var sources = {};
  9. var images = {};
  10. var animations = {};
  11. var controllers = {};
  12. var geometries = {};
  13. var materials = {};
  14. var effects = {};
  15. var visualScenes;
  16. var flip_uv = true;
  17. var readyCallbackFunc = null;
  18. var baseUrl;
  19. var morphs;
  20. var skins;
  21. var preferredShading = THREE.SmoothShading;
  22. function load(url, readyCallback) {
  23. if (document.implementation && document.implementation.createDocument) {
  24. var namespaceURL = "http://www.collada.org/2005/11/COLLADASchema";
  25. var rootTagName = "COLLADA";
  26. var xmldoc = document.implementation.createDocument(namespaceURL, rootTagName, null);
  27. var me = this;
  28. url += "?rnd=" + Math.random();
  29. var req = new XMLHttpRequest();
  30. if(req.overrideMimeType) {
  31. // need this? yes... if extension is other then *.xml :-S
  32. req.overrideMimeType("text/xml");
  33. }
  34. req.onreadystatechange = function() {
  35. if(req.readyState == 4) {
  36. if(req.status == 0 || req.status == 200) {
  37. readyCallbackFunc = readyCallback;
  38. parse(req.responseXML, undefined, url);
  39. }
  40. }
  41. }
  42. req.open("GET", url, true);
  43. req.send(null);
  44. } else {
  45. alert("Don't know how to parse XML!");
  46. }
  47. }
  48. function parse(doc, callBack, url) {
  49. COLLADA = doc;
  50. callBack = callBack || readyCallbackFunc;
  51. if (url !== undefined) {
  52. var parts = url.split('/');
  53. parts.pop();
  54. baseUrl = parts.join('/') + '/';
  55. }
  56. images = parseLib("//dae:library_images/dae:image", _Image, "image");
  57. materials = parseLib("//dae:library_materials/dae:material", Material, "material");
  58. effects = parseLib("//dae:library_effects/dae:effect", Effect, "effect");
  59. geometries = parseLib("//dae:library_geometries/dae:geometry", Geometry, "geometry");
  60. controllers = parseLib("//dae:library_controllers/dae:controller", Controller, "controller");
  61. animations = parseLib("//dae:library_animations/dae:animation", Animation, "animation");
  62. visualScenes = parseLib(".//dae:library_visual_scenes/dae:visual_scene", VisualScene, "visual_scene");
  63. morphs = [];
  64. skins = [];
  65. daeScene = parseScene();
  66. scene = new THREE.Object3D();
  67. for (var i = 0; i < daeScene.nodes.length; i++) {
  68. scene.addChild(createSceneGraph(daeScene.nodes[i]));
  69. }
  70. createAnimations();
  71. var result = {
  72. scene: scene,
  73. morphs: morphs,
  74. skins: skins,
  75. dae: {
  76. images: images,
  77. materials: materials,
  78. effects: effects,
  79. geometries: geometries,
  80. controllers: controllers,
  81. animations: animations,
  82. visualScenes: visualScenes,
  83. scene: daeScene
  84. }
  85. };
  86. if (callBack) {
  87. callBack(result);
  88. }
  89. return result;
  90. }
  91. function setPreferredShading(shading) {
  92. preferredShading = shading;
  93. }
  94. function parseLib(q, classSpec, prefix) {
  95. var elements = COLLADA.evaluate(q,
  96. COLLADA,
  97. _nsResolver,
  98. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  99. null);
  100. var lib = {};
  101. var element = elements.iterateNext();
  102. var i = 0;
  103. while (element) {
  104. var daeElement = (new classSpec()).parse(element);
  105. if (daeElement.id.length == 0) daeElement.id = prefix + (i++);
  106. lib[daeElement.id] = daeElement;
  107. element = elements.iterateNext();
  108. }
  109. return lib;
  110. }
  111. function parseScene() {
  112. var sceneElement = COLLADA.evaluate(".//dae:scene/dae:instance_visual_scene",
  113. COLLADA,
  114. _nsResolver,
  115. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  116. null).iterateNext();
  117. if (sceneElement) {
  118. var url = sceneElement.getAttribute('url').replace(/^#/, '');
  119. return visualScenes[url];
  120. } else {
  121. return null;
  122. }
  123. }
  124. function createAnimations() {
  125. calcAnimationBounds();
  126. for (animation_id in animations) {
  127. createAnimation(animations[animation_id]);
  128. }
  129. }
  130. function createAnimation(animation) {
  131. }
  132. function calcAnimationBounds() {
  133. var start = 1000000;
  134. var end = -start;
  135. for (id in animations) {
  136. var animation = animations[id];
  137. for (var i = 0; i < animation.sampler.length; i++) {
  138. var sampler = animation.sampler[i];
  139. sampler.create();
  140. start = Math.min(start, sampler.startTime);
  141. end = Math.max(end, sampler.endTime);
  142. }
  143. }
  144. return {start:start, end:end}
  145. }
  146. function createMorph(geometry, ctrl) {
  147. var morphCtrl = ctrl instanceof InstanceController ? controllers[ctrl.url] : ctrl;
  148. if (!morphCtrl || !morphCtrl.morph) {
  149. console.log("could not find morph controller!");
  150. return;
  151. }
  152. var morph = morphCtrl.morph;
  153. for (var i = 0; i < morph.targets.length; i++) {
  154. var target_id = morph.targets[i];
  155. var daeGeometry = geometries[target_id];
  156. if (!daeGeometry.mesh ||
  157. !daeGeometry.mesh.primitives ||
  158. !daeGeometry.mesh.primitives.length) {
  159. continue;
  160. }
  161. var target = daeGeometry.mesh.primitives[0].geometry;
  162. if (target.vertices.length === geometry.vertices.length) {
  163. geometry.morphTargets.push( { name: "target_1", vertices: target.vertices } );
  164. }
  165. }
  166. geometry.morphTargets.push( { name: "target_Z", vertices: geometry.vertices } );
  167. }
  168. function createSkin(geometry, ctrl, applyBindShape) {
  169. var skinCtrl = controllers[ctrl.url];
  170. if (!skinCtrl || !skinCtrl.skin) {
  171. console.log("could not find skin controller!");
  172. return;
  173. }
  174. if (!ctrl.skeleton || !ctrl.skeleton.length) {
  175. console.log("could not find the skeleton for the skin!");
  176. return;
  177. }
  178. var skin = skinCtrl.skin;
  179. var skeleton = daeScene.getChildById(ctrl.skeleton[0]);
  180. var hierarchy = [];
  181. applyBindShape = applyBindShape !== undefined ? applyBindShape : true;
  182. var bones = [];
  183. geometry.skinWeights = [];
  184. geometry.skinIndices = [];
  185. createBones(geometry.bones, skin, hierarchy, skeleton, null, -1);
  186. createWeights(skin, geometry.bones, geometry.skinIndices, geometry.skinWeights);
  187. /*
  188. geometry.animation = {
  189. name: 'take_001',
  190. fps: 30,
  191. length: 2,
  192. JIT: true,
  193. hierarchy: hierarchy
  194. };
  195. */
  196. if (applyBindShape) {
  197. for (var i = 0; i < geometry.vertices.length; i++) {
  198. skin.bindShapeMatrix.multiplyVector3(geometry.vertices[i].position);
  199. }
  200. }
  201. }
  202. function createSceneGraph(node, parent) {
  203. var obj = new THREE.Object3D();
  204. var skinned = false;
  205. var skinController;
  206. var morphController;
  207. var i;
  208. obj.name = node.id || "";
  209. obj.matrixAutoUpdate = false;
  210. obj.matrix = node.matrix;
  211. // FIXME: controllers
  212. for (i =0; i < node.controllers.length; i++) {
  213. var controller = controllers[node.controllers[i].url];
  214. switch (controller.type) {
  215. case 'skin':
  216. if (geometries[controller.skin.source]) {
  217. var inst_geom = new InstanceGeometry();
  218. inst_geom.url = controller.skin.source;
  219. inst_geom.instance_material = node.controllers[i].instance_material;
  220. node.geometries.push(inst_geom);
  221. skinned = true;
  222. skinController = node.controllers[i];
  223. } else if (controllers[controller.skin.source]) {
  224. // urgh: controller can be chained
  225. // handle the most basic case...
  226. var second = controllers[controller.skin.source];
  227. morphController = second;
  228. // skinController = node.controllers[i];
  229. if (second.morph && geometries[second.morph.source]) {
  230. var inst_geom = new InstanceGeometry();
  231. inst_geom.url = second.morph.source;
  232. inst_geom.instance_material = node.controllers[i].instance_material;
  233. node.geometries.push(inst_geom);
  234. }
  235. }
  236. break;
  237. case 'morph':
  238. if (geometries[controller.morph.source]) {
  239. var inst_geom = new InstanceGeometry();
  240. inst_geom.url = controller.morph.source;
  241. inst_geom.instance_material = node.controllers[i].instance_material;
  242. node.geometries.push(inst_geom);
  243. morphController = node.controllers[i];
  244. }
  245. console.log("DAE: morph-controller partially supported.")
  246. default:
  247. break;
  248. }
  249. }
  250. // FIXME: multi-material mesh?
  251. // geometries
  252. for (i = 0; i < node.geometries.length; i++) {
  253. var instance_geometry = node.geometries[i];
  254. var instance_materials = instance_geometry.instance_material;
  255. var geometry = geometries[instance_geometry.url];
  256. var used_materials = {};
  257. var num_materials = 0;
  258. var first_material;
  259. if (geometry) {
  260. if (!geometry.mesh || !geometry.mesh.primitives)
  261. continue;
  262. if (obj.name.length == 0) {
  263. obj.name = geometry.id;
  264. }
  265. // collect used fx for this geometry-instance
  266. if (instance_materials) {
  267. for (j = 0; j < instance_materials.length; j++) {
  268. var inst_material = instance_materials[j];
  269. var effect_id = materials[inst_material.target].instance_effect.url;
  270. var shader = effects[effect_id].shader;
  271. shader.material.opacity = !shader.material.opacity ? 1 : shader.material.opacity;
  272. used_materials[inst_material.symbol] = shader.material;
  273. first_material = shader.material;
  274. num_materials++;
  275. }
  276. }
  277. var mesh;
  278. var material = first_material || new THREE.MeshLambertMaterial({ color: 0xdddddd, shading: THREE.FlatShading });
  279. var geom = geometry.mesh.geometry3js;
  280. if (num_materials > 1) {
  281. material = new THREE.MeshFaceMaterial();
  282. for (j = 0; j < geom.faces.length; j++) {
  283. var face = geom.faces[j];
  284. face.materials = [ used_materials[face.daeMaterial] ];
  285. }
  286. }
  287. if (skinController !== undefined) {
  288. mesh = new THREE.SkinnedMesh( geom, material );
  289. mesh.skeleton = skinController.skeleton;
  290. mesh.skinController = controllers[skinController.url];
  291. mesh.name = 'skin_' + skins.length;
  292. skins.push(mesh);
  293. } else if (morphController !== undefined) {
  294. createMorph(geom, morphController);
  295. material.morphTargets = true;
  296. mesh = new THREE.Mesh( geom, material );
  297. mesh.name = 'morph_' + morphs.length;
  298. morphs.push(mesh);
  299. } else {
  300. mesh = new THREE.Mesh( geom, material );
  301. }
  302. obj.addChild(mesh);
  303. }
  304. }
  305. for (i = 0; i < node.nodes.length; i++) {
  306. obj.addChild(createSceneGraph(node.nodes[i], node));
  307. }
  308. return obj;
  309. }
  310. function getJointId(skin, id) {
  311. for (var i = 0; i < skin.joints.length; i++) {
  312. if (skin.joints[i] == id) {
  313. return i;
  314. }
  315. }
  316. }
  317. function getLibraryNode(id) {
  318. return COLLADA.evaluate(".//dae:library_nodes//dae:node[@id='"+id+"']",
  319. COLLADA,
  320. _nsResolver,
  321. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  322. null).iterateNext();
  323. }
  324. function getChannelsForNode(node) {
  325. var channels = [];
  326. var startTime = 1000000;
  327. var endTime = -1000000;
  328. for (var id in animations) {
  329. var animation = animations[id];
  330. for (var i = 0; i < animation.channel.length; i++) {
  331. var channel = animation.channel[i];
  332. var sampler = animation.sampler[i];
  333. var id = channel.target.split('/')[0];
  334. if (id == node.id) {
  335. sampler.create();
  336. channel.sampler = sampler;
  337. startTime = Math.min(startTime, sampler.startTime);
  338. endTime = Math.max(endTime, sampler.endTime);
  339. channels.push(channel);
  340. }
  341. }
  342. }
  343. if (channels.length) {
  344. node.startTime = startTime;
  345. node.endTime = endTime;
  346. }
  347. return channels;
  348. }
  349. function calcFrameDuration(node) {
  350. var minT = 10000000;
  351. for (i = 0; i < node.channels.length; i++) {
  352. var sampler = node.channels[i].sampler;
  353. for (var j = 0; j < sampler.input.length - 1; j++) {
  354. var t0 = sampler.input[j];
  355. var t1 = sampler.input[j+1];
  356. minT = Math.min(minT, t1 - t0);
  357. }
  358. }
  359. return minT;
  360. }
  361. function calcMatrixAt(node, t) {
  362. var animated = {};
  363. var i, j;
  364. for (i = 0; i < node.channels.length; i++) {
  365. var channel = node.channels[i];
  366. animated[ channel.sid ] = channel;
  367. }
  368. var matrix = new THREE.Matrix4();
  369. for (i = 0; i < node.transforms.length; i++) {
  370. var transform = node.transforms[i];
  371. var channel = animated[transform.sid];
  372. if (channel !== undefined) {
  373. var sampler = channel.sampler;
  374. var value;
  375. for (var j = 0; j < sampler.input.length - 1; j++) {
  376. if (sampler.input[j+1] > t) {
  377. value = sampler.output[j];
  378. //console.log(value.flatten)
  379. break;
  380. }
  381. }
  382. if (value !== undefined) {
  383. if (value instanceof THREE.Matrix4) {
  384. matrix = matrix.multiply(matrix, value);
  385. } else {
  386. // FIXME: handle other types
  387. matrix = matrix.multiply(matrix, transform.matrix);
  388. }
  389. } else {
  390. matrix = matrix.multiply(matrix, transform.matrix);
  391. }
  392. } else {
  393. matrix = matrix.multiply(matrix, transform.matrix);
  394. }
  395. }
  396. return matrix;
  397. }
  398. function bakeAnimations(node) {
  399. if (node.channels && node.channels.length) {
  400. var frameDuration = calcFrameDuration(node);
  401. var t, matrix;
  402. var keys = [];
  403. for (t = node.startTime; t < node.endTime; t += frameDuration) {
  404. matrix = calcMatrixAt(node, t);
  405. //keys.push({time: t, mat: matrix.flatten()})
  406. keys.push({
  407. time: t,
  408. pos: [matrix.n14, matrix.n24, matrix.n34],
  409. rotq: [0, 0, 0, 1],
  410. scl: [1,1,1]
  411. });
  412. }
  413. node.keys = keys;
  414. }
  415. }
  416. function _Image() {
  417. this.id = "";
  418. this.init_from = "";
  419. }
  420. _Image.prototype.parse = function(element) {
  421. this.id = element.getAttribute('id');
  422. for (var i = 0; i < element.childNodes.length; i++) {
  423. var child = element.childNodes[i];
  424. if (child.nodeName == 'init_from') {
  425. this.init_from = child.textContent;
  426. }
  427. }
  428. return this;
  429. }
  430. function Controller() {
  431. this.id = "";
  432. this.name = "";
  433. this.type = "";
  434. this.skin = null;
  435. this.morph = null;
  436. }
  437. Controller.prototype.parse = function(element) {
  438. this.id = element.getAttribute('id');
  439. this.name = element.getAttribute('name');
  440. this.type = "none";
  441. for (var i = 0; i < element.childNodes.length; i++) {
  442. var child = element.childNodes[i];
  443. switch (child.nodeName) {
  444. case 'skin':
  445. this.skin = (new Skin()).parse(child);
  446. this.type = child.nodeName;
  447. break;
  448. case 'morph':
  449. this.morph = (new Morph()).parse(child);
  450. this.type = child.nodeName;
  451. break;
  452. default:
  453. break;
  454. }
  455. }
  456. return this;
  457. }
  458. function Morph() {
  459. this.method;
  460. this.source;
  461. this.targets;
  462. this.weights;
  463. }
  464. Morph.prototype.parse = function(element) {
  465. var sources = {};
  466. var inputs = [];
  467. var i;
  468. this.method = element.getAttribute('method');
  469. this.source = element.getAttribute('source').replace(/^#/, '');
  470. for (i = 0; i < element.childNodes.length; i++) {
  471. var child = element.childNodes[i];
  472. if (child.nodeType != 1) continue;
  473. switch (child.nodeName) {
  474. case 'source':
  475. var source = (new Source()).parse(child);
  476. sources[source.id] = source;
  477. break;
  478. case 'targets':
  479. inputs = this.parseInputs(child);
  480. break;
  481. default:
  482. console.log(child.nodeName);
  483. break;
  484. }
  485. }
  486. for (i = 0; i < inputs.length; i++) {
  487. var input = inputs[i];
  488. var source = sources[input.source];
  489. switch (input.semantic) {
  490. case 'MORPH_TARGET':
  491. this.targets = source.read();
  492. break;
  493. case 'MORPH_WEIGHT':
  494. this.weights = source.read();
  495. break;
  496. default:
  497. break;
  498. }
  499. }
  500. return this;
  501. }
  502. Morph.prototype.parseInputs = function(element) {
  503. var inputs = [];
  504. for (var i = 0; i < element.childNodes.length; i++) {
  505. var child = element.childNodes[i];
  506. if (child.nodeType != 1) continue;
  507. switch (child.nodeName) {
  508. case 'input':
  509. inputs.push((new Input()).parse(child));
  510. break;
  511. default:
  512. break;
  513. }
  514. }
  515. return inputs;
  516. }
  517. function Skin() {
  518. this.source = "";
  519. this.bindShapeMatrix = null;
  520. this.invBindMatrices = [];
  521. this.joints = [];
  522. this.weights = [];
  523. }
  524. Skin.prototype.parse = function(element) {
  525. var sources = {};
  526. var joints, weights;
  527. this.source = element.getAttribute('source').replace(/^#/, '');
  528. this.invBindMatrices = [];
  529. this.joints = [];
  530. this.weights = [];
  531. for (var i = 0; i < element.childNodes.length; i++) {
  532. var child = element.childNodes[i];
  533. if (child.nodeType != 1) continue;
  534. switch (child.nodeName) {
  535. case 'bind_shape_matrix':
  536. var f = _floats(child.textContent);
  537. this.bindShapeMatrix = new THREE.Matrix4();
  538. this.bindShapeMatrix.set(
  539. f[0], f[1], f[2], f[3],
  540. f[4], f[5], f[6], f[7],
  541. f[8], f[9], f[10], f[11],
  542. f[12], f[13], f[14], f[15]
  543. );
  544. break;
  545. case 'source':
  546. var src = new Source().parse(child);
  547. sources[src.id] = src;
  548. break;
  549. case 'joints':
  550. joints = child;
  551. break;
  552. case 'vertex_weights':
  553. weights = child;
  554. break;
  555. default:
  556. console.log(child.nodeName);
  557. break;
  558. }
  559. }
  560. this.parseJoints(joints, sources);
  561. this.parseWeights(weights, sources);
  562. return this;
  563. }
  564. Skin.prototype.parseJoints = function(element, sources) {
  565. for (var i = 0; i < element.childNodes.length; i++) {
  566. var child = element.childNodes[i];
  567. if (child.nodeType != 1) continue;
  568. switch (child.nodeName) {
  569. case 'input':
  570. var input = (new Input()).parse(child);
  571. var source = sources[input.source];
  572. if (input.semantic == 'JOINT') {
  573. this.joints = source.read();
  574. } else if (input.semantic == 'INV_BIND_MATRIX') {
  575. this.invBindMatrices = source.read();
  576. }
  577. break;
  578. default:
  579. break;
  580. }
  581. }
  582. }
  583. Skin.prototype.parseWeights = function(element, sources) {
  584. var v, vcount, inputs = [];
  585. for (var i = 0; i < element.childNodes.length; i++) {
  586. var child = element.childNodes[i];
  587. if (child.nodeType != 1) continue;
  588. switch (child.nodeName) {
  589. case 'input':
  590. inputs.push((new Input()).parse(child));
  591. break;
  592. case 'v':
  593. v = _ints(child.textContent);
  594. break;
  595. case 'vcount':
  596. vcount = _ints(child.textContent);
  597. break;
  598. default:
  599. break;
  600. }
  601. }
  602. var index = 0;
  603. for (var i = 0; i < vcount.length; i++) {
  604. var numBones = vcount[i];
  605. var vertex_weights = [];
  606. for (var j = 0; j < numBones; j++) {
  607. var influence = {};
  608. for (var k = 0; k < inputs.length; k++) {
  609. var input = inputs[k];
  610. var value = v[index + input.offset];
  611. switch (input.semantic) {
  612. case 'JOINT':
  613. influence.joint = value;//this.joints[value];
  614. break;
  615. case 'WEIGHT':
  616. influence.weight = sources[input.source].data[value];
  617. break;
  618. default:
  619. break;
  620. }
  621. }
  622. vertex_weights.push(influence);
  623. index += inputs.length;
  624. }
  625. for (var j = 0; j < vertex_weights.length; j++) {
  626. vertex_weights[j].index = i;
  627. }
  628. this.weights.push(vertex_weights);
  629. }
  630. }
  631. function VisualScene() {
  632. this.id = "";
  633. this.name = "";
  634. this.nodes = [];
  635. this.scene = new THREE.Object3D();
  636. }
  637. VisualScene.prototype.getChildById = function(id, recursive) {
  638. for (var i = 0; i < this.nodes.length; i++) {
  639. var node = this.nodes[i].getChildById(id, recursive);
  640. if (node) {
  641. return node;
  642. }
  643. }
  644. return null;
  645. }
  646. VisualScene.prototype.getChildBySid = function(sid, recursive) {
  647. for (var i = 0; i < this.nodes.length; i++) {
  648. var node = this.nodes[i].getChildBySid(sid, recursive);
  649. if (node) {
  650. return node;
  651. }
  652. }
  653. return null;
  654. }
  655. VisualScene.prototype.parse = function(element) {
  656. this.id = element.getAttribute('id');
  657. this.name = element.getAttribute('name');
  658. this.nodes = [];
  659. for (var i = 0; i < element.childNodes.length; i++) {
  660. var child = element.childNodes[i];
  661. if (child.nodeType != 1) continue;
  662. switch (child.nodeName) {
  663. case 'node':
  664. this.nodes.push((new Node()).parse(child));
  665. break;
  666. default:
  667. break;
  668. }
  669. }
  670. return this;
  671. }
  672. function Node() {
  673. this.id = "";
  674. this.name = "";
  675. this.sid = "";
  676. this.nodes = [];
  677. this.controllers = [];
  678. this.transforms = [];
  679. this.geometries = [];
  680. this.channels = [];
  681. this.matrix = new THREE.Matrix4();
  682. }
  683. Node.prototype.getChannelForTransform = function(transformSid) {
  684. for (var i = 0; i < this.channels.length; i++) {
  685. var channel = this.channels[i];
  686. var parts = channel.target.split('/');
  687. var id = parts.shift();
  688. var sid = parts.shift();
  689. var dotSyntax = (sid.indexOf(".") >= 0);
  690. var arrSyntax = (sid.indexOf("(") >= 0);
  691. var arrIndices;
  692. var member;
  693. if (dotSyntax) {
  694. parts = sid.split(".");
  695. sid = parts.shift();
  696. member = parts.shift();
  697. } else if (arrSyntax) {
  698. arrIndices = sid.split("(");
  699. sid = arrIndices.shift();
  700. for (var j = 0; j < arrIndices.length; j++) {
  701. arrIndices[j] = parseInt(arrIndices[j].replace(/\)/, ''));
  702. }
  703. }
  704. if (sid == transformSid) {
  705. channel.info = {sid:sid, dotSyntax:dotSyntax, arrSyntax:arrSyntax, arrIndices:arrIndices};
  706. return channel;
  707. }
  708. }
  709. return null;
  710. }
  711. Node.prototype.getChildById = function(id, recursive) {
  712. if (this.id == id) {
  713. return this;
  714. }
  715. if (recursive) {
  716. for (var i = 0; i < this.nodes.length; i++) {
  717. var n = this.nodes[i].getChildById(id, recursive);
  718. if (n) {
  719. return n;
  720. }
  721. }
  722. }
  723. return null;
  724. }
  725. Node.prototype.getChildBySid = function(sid, recursive) {
  726. if (this.sid == sid) {
  727. return this;
  728. }
  729. if (recursive) {
  730. for (var i = 0; i < this.nodes.length; i++) {
  731. var n = this.nodes[i].getChildBySid(sid, recursive);
  732. if (n) {
  733. return n;
  734. }
  735. }
  736. }
  737. return null;
  738. }
  739. Node.prototype.getTransformBySid = function(sid) {
  740. for (var i = 0; i < this.transforms.length; i++) {
  741. if (this.transforms[i].sid == sid) return this.transforms[i];
  742. }
  743. return null;
  744. }
  745. Node.prototype.parse = function(element) {
  746. var url;
  747. this.id = element.getAttribute('id');
  748. this.sid = element.getAttribute('sid');
  749. this.name = element.getAttribute('name');
  750. this.type = element.getAttribute('type');
  751. this.type = this.type == 'JOINT' ? this.type : 'NODE';
  752. this.nodes = [];
  753. this.transforms = [];
  754. this.geometries = [];
  755. this.controllers = [];
  756. this.matrix = new THREE.Matrix4();
  757. for (var i = 0; i < element.childNodes.length; i++) {
  758. var child = element.childNodes[i];
  759. if (child.nodeType != 1) continue;
  760. switch (child.nodeName) {
  761. case 'node':
  762. this.nodes.push((new Node()).parse(child));
  763. break;
  764. case 'instance_camera':
  765. break;
  766. case 'instance_controller':
  767. this.controllers.push((new InstanceController()).parse(child));
  768. break;
  769. case 'instance_geometry':
  770. this.geometries.push((new InstanceGeometry()).parse(child));
  771. break;
  772. case 'instance_light':
  773. break;
  774. case 'instance_node':
  775. url = child.getAttribute('url').replace(/^#/, '');
  776. var iNode = getLibraryNode(url);
  777. if (iNode) {
  778. this.nodes.push((new Node()).parse(iNode));
  779. }
  780. break;
  781. case 'rotate':
  782. case 'translate':
  783. case 'scale':
  784. case 'matrix':
  785. case 'lookat':
  786. case 'skew':
  787. this.transforms.push((new Transform()).parse(child));
  788. break;
  789. case 'extra':
  790. break;
  791. default:
  792. console.log(child.nodeName);
  793. break;
  794. }
  795. }
  796. this.channels = getChannelsForNode(this);
  797. bakeAnimations(this);
  798. this.updateMatrix();
  799. return this;
  800. }
  801. Node.prototype.updateMatrix = function() {
  802. this.matrix.identity();
  803. for (var i = 0; i < this.transforms.length; i++) {
  804. this.matrix.multiply(this.matrix, this.transforms[i].matrix);
  805. }
  806. }
  807. function Transform() {
  808. this.sid = "";
  809. this.type = "";
  810. this.data = [];
  811. this.matrix = new THREE.Matrix4();
  812. }
  813. Transform.prototype.parse = function(element) {
  814. this.sid = element.getAttribute('sid');
  815. this.type = element.nodeName;
  816. this.data = _floats(element.textContent);
  817. this.updateMatrix();
  818. return this;
  819. }
  820. Transform.prototype.updateMatrix = function() {
  821. var angle = 0;
  822. this.matrix.identity();
  823. switch (this.type) {
  824. case 'matrix':
  825. this.matrix.set(
  826. this.data[0], this.data[1], this.data[2], this.data[3],
  827. this.data[4], this.data[5], this.data[6], this.data[7],
  828. this.data[8], this.data[9], this.data[10], this.data[11],
  829. this.data[12], this.data[13], this.data[14], this.data[15]
  830. );
  831. break;
  832. case 'translate':
  833. this.matrix.setTranslation(this.data[0], this.data[1], this.data[2]);
  834. break;
  835. case 'rotate':
  836. angle = this.data[3] * (Math.PI / 180.0);
  837. this.matrix.setRotationAxis(new THREE.Vector3(this.data[0], this.data[1], this.data[2]), angle);
  838. break;
  839. case 'scale':
  840. this.matrix.setScale(this.data[0], this.data[1], this.data[2]);
  841. break;
  842. default:
  843. break;
  844. }
  845. return this.matrix;
  846. }
  847. function InstanceController() {
  848. this.url = "";
  849. this.skeleton = [];
  850. this.instance_material = [];
  851. }
  852. InstanceController.prototype.parse = function(element) {
  853. this.url = element.getAttribute('url').replace(/^#/, '');
  854. this.skeleton = [];
  855. this.instance_material = [];
  856. for (var i = 0; i < element.childNodes.length; i++) {
  857. var child = element.childNodes[i];
  858. if (child.nodeType != 1) continue;
  859. switch (child.nodeName) {
  860. case 'skeleton':
  861. this.skeleton.push(child.textContent.replace(/^#/, ''));
  862. break;
  863. case 'bind_material':
  864. var instances = COLLADA.evaluate(".//dae:instance_material",
  865. child,
  866. _nsResolver,
  867. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  868. null);
  869. if (instances) {
  870. var instance = instances.iterateNext();
  871. while (instance) {
  872. this.instance_material.push((new InstanceMaterial()).parse(instance));
  873. instance = instances.iterateNext();
  874. }
  875. }
  876. break;
  877. case 'extra':
  878. break;
  879. default:
  880. break;
  881. }
  882. }
  883. return this;
  884. }
  885. function InstanceMaterial() {
  886. this.symbol = "";
  887. this.target = "";
  888. }
  889. InstanceMaterial.prototype.parse = function(element) {
  890. this.symbol = element.getAttribute('symbol');
  891. this.target = element.getAttribute('target').replace(/^#/, '');
  892. return this;
  893. }
  894. function InstanceGeometry() {
  895. this.url = "";
  896. this.instance_material = [];
  897. }
  898. InstanceGeometry.prototype.parse = function(element) {
  899. this.url = element.getAttribute('url').replace(/^#/, '');
  900. this.instance_material = [];
  901. for (var i = 0; i < element.childNodes.length; i++) {
  902. var child = element.childNodes[i];
  903. if (child.nodeType != 1) continue;
  904. if (child.nodeName == 'bind_material') {
  905. var instances = COLLADA.evaluate(".//dae:instance_material",
  906. child,
  907. _nsResolver,
  908. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  909. null);
  910. if (instances) {
  911. var instance = instances.iterateNext();
  912. while (instance) {
  913. this.instance_material.push((new InstanceMaterial()).parse(instance));
  914. instance = instances.iterateNext();
  915. }
  916. }
  917. break;
  918. }
  919. }
  920. return this;
  921. }
  922. function Geometry() {
  923. this.id = "";
  924. this.mesh = null;
  925. }
  926. Geometry.prototype.parse = function(element) {
  927. this.id = element.getAttribute('id');
  928. for (var i = 0; i < element.childNodes.length; i++) {
  929. var child = element.childNodes[i];
  930. switch (child.nodeName) {
  931. case 'mesh':
  932. this.mesh = (new Mesh(this)).parse(child);
  933. break;
  934. default:
  935. break;
  936. }
  937. }
  938. return this;
  939. }
  940. function Mesh(geometry) {
  941. this.geometry = geometry.id;
  942. this.primitives = [];
  943. this.vertices = null;
  944. this.geometry3js;
  945. }
  946. Mesh.prototype.parse = function(element) {
  947. this.primitives = [];
  948. var i, j;
  949. for (i = 0; i < element.childNodes.length; i++) {
  950. var child = element.childNodes[i];
  951. switch (child.nodeName) {
  952. case 'source':
  953. _source(child);
  954. break;
  955. case 'vertices':
  956. this.vertices = (new Vertices()).parse(child);
  957. break;
  958. case 'triangles':
  959. this.primitives.push((new Triangles().parse(child)));
  960. break;
  961. case 'polygons':
  962. console.warn('polygon holes not yet supported!');
  963. case 'polylist':
  964. this.primitives.push((new Polylist().parse(child)));
  965. break;
  966. default:
  967. break;
  968. }
  969. }
  970. var vertex_store = {};
  971. function get_vertex(v, index) {
  972. var hash = _hash_vector3(v.position);
  973. if (vertex_store[hash] === undefined) {
  974. vertex_store[hash] = {v:v, index:index};
  975. }
  976. return vertex_store[hash];
  977. }
  978. this.geometry3js = new THREE.Geometry();
  979. var vertexData = sources[this.vertices.input['POSITION'].source].data;
  980. for (i = 0, j = 0; i < vertexData.length; i += 3, j++) {
  981. var v = new THREE.Vertex(new THREE.Vector3(vertexData[i], vertexData[i+1], vertexData[i+2]));
  982. get_vertex(v, j);
  983. this.geometry3js.vertices.push(v);
  984. }
  985. for (i = 0; i < this.primitives.length; i++) {
  986. primitive = this.primitives[i];
  987. primitive.setVertices(this.vertices);
  988. this.handlePrimitive(primitive, this.geometry3js, vertex_store);
  989. }
  990. this.geometry3js.computeCentroids();
  991. this.geometry3js.computeFaceNormals();
  992. this.geometry3js.computeVertexNormals();
  993. this.geometry3js.computeBoundingBox();
  994. return this;
  995. }
  996. Mesh.prototype.handlePrimitive = function(primitive, geom, vertex_store) {
  997. var i = 0, j, k, p = primitive.p, inputs = primitive.inputs;
  998. var input, index, idx32;
  999. var vcIndex = 0, vcount = 3;
  1000. var texture_sets = [];
  1001. for (j = 0; j < inputs.length; j++) {
  1002. input = inputs[j];
  1003. if (input.semantic == 'TEXCOORD') {
  1004. texture_sets.push(input.set);
  1005. }
  1006. }
  1007. while (i < p.length) {
  1008. var vs = [];
  1009. var ns = [];
  1010. var ts = {};
  1011. if (primitive.vcount) {
  1012. vcount = primitive.vcount[vcIndex++];
  1013. }
  1014. for (j = 0; j < vcount; j++) {
  1015. for (k = 0; k < inputs.length; k++) {
  1016. input = inputs[k];
  1017. source = sources[input.source];
  1018. index = p[i + (j*inputs.length) + input.offset];
  1019. numParams = source.accessor.params.length;
  1020. idx32 = index * numParams;
  1021. switch (input.semantic) {
  1022. case 'VERTEX':
  1023. var hash = _hash_vector3(geom.vertices[index].position);
  1024. vs.push(vertex_store[hash].index);
  1025. break;
  1026. case 'NORMAL':
  1027. ns.push(new THREE.Vector3(source.data[idx32+0], source.data[idx32+1], source.data[idx32+2]));
  1028. break;
  1029. case 'TEXCOORD':
  1030. if (ts[input.set] == undefined) ts[input.set] = [];
  1031. ts[input.set].push(new THREE.UV(source.data[idx32+0], source.data[idx32+1]));
  1032. break;
  1033. default:
  1034. break;
  1035. }
  1036. }
  1037. }
  1038. var face = new THREE.Face3(vs[0], vs[1], vs[2], [ns[0], ns[1], ns[2]]);
  1039. var uv;
  1040. face.daeMaterial = primitive.material;
  1041. geom.faces.push(face);
  1042. for (k = 0; k < texture_sets.length; k++) {
  1043. uv = ts[texture_sets[k]];
  1044. geom.faceVertexUvs[ k ].push( [uv[0], uv[1], uv[2]] );
  1045. }
  1046. if (vcount > 3) {
  1047. for (j = 2; j < vs.length -1; j++) {
  1048. face = new THREE.Face3(vs[0], vs[j], vs[j+1], [ns[0], ns[j], ns[j+1]]);
  1049. face.daeMaterial = primitive.material;
  1050. geom.faces.push(face);
  1051. for (k = 0; k < texture_sets.length; k++) {
  1052. uv = ts[texture_sets[k]];
  1053. geom.faceVertexUvs[ k ].push( [uv[0], uv[j], uv[j+1]] );
  1054. }
  1055. }
  1056. }
  1057. i += inputs.length * vcount;
  1058. }
  1059. }
  1060. function Polylist() {
  1061. }
  1062. Polylist.prototype = new Triangles();
  1063. Polylist.prototype.constructor = Polylist;
  1064. function Triangles(flip_uv) {
  1065. this.material = "";
  1066. this.count = 0;
  1067. this.inputs = [];
  1068. this.vcount;
  1069. this.p = [];
  1070. this.geometry = new THREE.Geometry();
  1071. }
  1072. Triangles.prototype.setVertices = function(vertices) {
  1073. for (var i = 0; i < this.inputs.length; i++) {
  1074. if (this.inputs[i].source == vertices.id) {
  1075. this.inputs[i].source = vertices.input['POSITION'].source;
  1076. }
  1077. }
  1078. }
  1079. Triangles.prototype.parse = function(element) {
  1080. this.inputs = [];
  1081. this.material = element.getAttribute('material');
  1082. this.count = _attr_as_int(element, 'count', 0);
  1083. for (var i = 0; i < element.childNodes.length; i++) {
  1084. var child = element.childNodes[i];
  1085. switch (child.nodeName) {
  1086. case 'input':
  1087. this.inputs.push((new Input()).parse(element.childNodes[i]));
  1088. break;
  1089. case 'vcount':
  1090. this.vcount = _ints(child.textContent);
  1091. break;
  1092. case 'p':
  1093. this.p = _ints(child.textContent);
  1094. break;
  1095. default:
  1096. break;
  1097. }
  1098. }
  1099. return this;
  1100. }
  1101. function Accessor() {
  1102. this.source = "";
  1103. this.count = 0;
  1104. this.stride = 0;
  1105. this.params = [];
  1106. }
  1107. Accessor.prototype.parse = function(element) {
  1108. this.params = [];
  1109. this.source = element.getAttribute('source');
  1110. this.count = _attr_as_int(element, 'count', 0);
  1111. this.stride = _attr_as_int(element, 'stride', 0);
  1112. for (var i = 0; i < element.childNodes.length; i++) {
  1113. var child = element.childNodes[i];
  1114. if (child.nodeName == 'param') {
  1115. var param = {};
  1116. param['name'] = child.getAttribute('name');
  1117. param['type'] = child.getAttribute('type');
  1118. this.params.push(param);
  1119. }
  1120. }
  1121. return this;
  1122. }
  1123. function Vertices() {
  1124. this.input = {};
  1125. }
  1126. Vertices.prototype.parse = function(element) {
  1127. this.id = element.getAttribute('id');
  1128. for (var i = 0; i < element.childNodes.length; i++) {
  1129. if (element.childNodes[i].nodeName == 'input') {
  1130. input = (new Input()).parse(element.childNodes[i]);
  1131. this.input[input.semantic] = input;
  1132. }
  1133. }
  1134. return this;
  1135. }
  1136. function Input() {
  1137. this.semantic = "";
  1138. this.offset = 0;
  1139. this.source = "";
  1140. this.set = 0;
  1141. }
  1142. Input.prototype.parse = function(element) {
  1143. this.semantic = element.getAttribute('semantic');
  1144. this.source = element.getAttribute('source').replace(/^#/, '');
  1145. this.set = _attr_as_int(element, 'set', -1);
  1146. this.offset = _attr_as_int(element, 'offset', 0);
  1147. if (this.semantic == 'TEXCOORD' && this.set < 0) {
  1148. this.set = 0;
  1149. }
  1150. return this;
  1151. }
  1152. function Source(id) {
  1153. this.id = id;
  1154. this.type = null;
  1155. }
  1156. Source.prototype.parse = function(element) {
  1157. this.id = element.getAttribute('id');
  1158. for (var i = 0; i < element.childNodes.length; i++) {
  1159. var child = element.childNodes[i];
  1160. switch (child.nodeName) {
  1161. case 'bool_array':
  1162. this.data = _bools(child.textContent);
  1163. this.type = child.nodeName;
  1164. break;
  1165. case 'float_array':
  1166. this.data = _floats(child.textContent);
  1167. this.type = child.nodeName;
  1168. break;
  1169. case 'int_array':
  1170. this.data = _ints(child.textContent);
  1171. this.type = child.nodeName;
  1172. break;
  1173. case 'IDREF_array':
  1174. case 'Name_array':
  1175. this.data = _strings(child.textContent);
  1176. this.type = child.nodeName;
  1177. break;
  1178. case 'technique_common':
  1179. for (var j = 0; j < child.childNodes.length; j++) {
  1180. if (child.childNodes[j].nodeName == 'accessor') {
  1181. this.accessor = (new Accessor()).parse(child.childNodes[j]);
  1182. break;
  1183. }
  1184. }
  1185. break;
  1186. default:
  1187. //console.log(child.nodeName);
  1188. break;
  1189. }
  1190. }
  1191. return this;
  1192. }
  1193. Source.prototype.read = function() {
  1194. var result = [];
  1195. //for (var i = 0; i < this.accessor.params.length; i++) {
  1196. var param = this.accessor.params[0];
  1197. //console.log(param.name + " " + param.type);
  1198. switch (param.type) {
  1199. case 'IDREF':
  1200. case 'Name':
  1201. case 'float':
  1202. return this.data;
  1203. case 'float4x4':
  1204. for (var j = 0; j < this.data.length; j += 16) {
  1205. var s = this.data.slice(j, j+16);
  1206. var m = new THREE.Matrix4();
  1207. m.set(
  1208. s[0], s[1], s[2], s[3],
  1209. s[4], s[5], s[6], s[7],
  1210. s[8], s[9], s[10], s[11],
  1211. s[12], s[13], s[14], s[15]
  1212. );
  1213. result.push(m);
  1214. }
  1215. break;
  1216. default:
  1217. console.log('Dae::Source:read dont know how to read ' + param.type);
  1218. break;
  1219. }
  1220. //}
  1221. return result;
  1222. }
  1223. function Material() {
  1224. this.id = "";
  1225. this.name = "";
  1226. this.instance_effect = null;
  1227. }
  1228. Material.prototype.parse = function(element) {
  1229. this.id = element.getAttribute('id');
  1230. this.name = element.getAttribute('name');
  1231. for (var i = 0; i < element.childNodes.length; i++) {
  1232. if (element.childNodes[i].nodeName == 'instance_effect') {
  1233. this.instance_effect = (new InstanceEffect()).parse(element.childNodes[i]);
  1234. break;
  1235. }
  1236. }
  1237. return this;
  1238. }
  1239. function ColorOrTexture() {
  1240. this.color = new THREE.Color(0);
  1241. this.color.setRGB(Math.random(), Math.random(), Math.random());
  1242. this.color.a = 1.0;
  1243. this.texture = null;
  1244. this.texcoord = null;
  1245. }
  1246. ColorOrTexture.prototype.isColor = function() {
  1247. return (this.texture == null);
  1248. }
  1249. ColorOrTexture.prototype.isTexture = function() {
  1250. return (this.texture != null);
  1251. }
  1252. ColorOrTexture.prototype.parse = function(element) {
  1253. for (var i = 0; i < element.childNodes.length; i++) {
  1254. var child = element.childNodes[i];
  1255. if (child.nodeType != 1) continue;
  1256. switch (child.nodeName) {
  1257. case 'color':
  1258. var rgba = _floats(child.textContent);
  1259. this.color = new THREE.Color(0);
  1260. this.color.setRGB(rgba[0], rgba[1], rgba[2]);
  1261. this.color.a = rgba[3];
  1262. break;
  1263. case 'texture':
  1264. this.texture = child.getAttribute('texture');
  1265. this.texcoord = child.getAttribute('texcoord');
  1266. break;
  1267. default:
  1268. break;
  1269. }
  1270. }
  1271. return this;
  1272. }
  1273. function Shader(type, effect) {
  1274. this.type = type;
  1275. this.effect = effect;
  1276. this.material;
  1277. }
  1278. Shader.prototype.parse = function(element) {
  1279. for (var i = 0; i < element.childNodes.length; i++) {
  1280. var child = element.childNodes[i];
  1281. if (child.nodeType != 1) continue;
  1282. switch (child.nodeName) {
  1283. case 'ambient':
  1284. case 'emission':
  1285. case 'diffuse':
  1286. case 'specular':
  1287. case 'transparent':
  1288. this[child.nodeName] = (new ColorOrTexture()).parse(child);
  1289. break;
  1290. case 'shininess':
  1291. case 'reflectivity':
  1292. case 'transparency':
  1293. var f = evaluateXPath(child, ".//dae:float");
  1294. if (f.length > 0)
  1295. this[child.nodeName] = parseFloat(f[0].textContent);
  1296. break;
  1297. default:
  1298. break;
  1299. }
  1300. }
  1301. this.create();
  1302. return this;
  1303. }
  1304. Shader.prototype.create = function() {
  1305. var props = {};
  1306. var transparent = (this['transparency'] !== undefined && this['transparency'] < 1.0);
  1307. for (var prop in this) {
  1308. switch (prop) {
  1309. case 'ambient':
  1310. case 'emission':
  1311. case 'diffuse':
  1312. case 'specular':
  1313. var cot = this[prop];
  1314. if (cot instanceof ColorOrTexture) {
  1315. if (cot.isTexture()) {
  1316. if (this.effect.sampler && this.effect.surface) {
  1317. if (this.effect.sampler.source == this.effect.surface.sid) {
  1318. var image = images[this.effect.surface.init_from];
  1319. if (image) {
  1320. props['map'] = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
  1321. props['map'].wrapS = THREE.RepeatWrapping;
  1322. props['map'].wrapT = THREE.RepeatWrapping;
  1323. props['map'].repeat.x = 1;
  1324. props['map'].repeat.y = -1;
  1325. }
  1326. }
  1327. }
  1328. } else {
  1329. if (prop == 'diffuse') {
  1330. props['color'] = cot.color.getHex();
  1331. } else if (!transparent){
  1332. props[prop] = cot.color.getHex();
  1333. }
  1334. }
  1335. }
  1336. break;
  1337. case 'shininess':
  1338. case 'reflectivity':
  1339. props[prop] = this[prop];
  1340. break;
  1341. case 'transparency':
  1342. if (transparent) {
  1343. props['transparent'] = true;
  1344. props['opacity'] = this[prop];
  1345. transparent = true;
  1346. }
  1347. break;
  1348. default:
  1349. break;
  1350. }
  1351. }
  1352. props['shading'] = preferredShading;
  1353. this.material = new THREE.MeshLambertMaterial(props);
  1354. switch (this.type) {
  1355. case 'constant':
  1356. case 'lambert':
  1357. break;
  1358. case 'phong':
  1359. case 'blinn':
  1360. default:
  1361. if (!transparent) {
  1362. this.material = new THREE.MeshPhongMaterial(props);
  1363. }
  1364. break;
  1365. }
  1366. return this.material;
  1367. }
  1368. function Surface(effect) {
  1369. this.effect = effect;
  1370. this.init_from;
  1371. this.format;
  1372. }
  1373. Surface.prototype.parse = function(element) {
  1374. for (var i = 0; i < element.childNodes.length; i++) {
  1375. var child = element.childNodes[i];
  1376. if (child.nodeType != 1) continue;
  1377. switch (child.nodeName) {
  1378. case 'init_from':
  1379. this.init_from = child.textContent;
  1380. break;
  1381. case 'format':
  1382. this.format = child.textContent;
  1383. break;
  1384. default:
  1385. console.log("unhandled Surface prop: " + child.nodeName);
  1386. break;
  1387. }
  1388. }
  1389. return this;
  1390. }
  1391. function Sampler2D(effect) {
  1392. this.effect = effect;
  1393. this.source;
  1394. this.wrap_s;
  1395. this.wrap_t;
  1396. this.minfilter;
  1397. this.magfilter;
  1398. this.mipfilter;
  1399. }
  1400. Sampler2D.prototype.parse = function(element) {
  1401. for (var i = 0; i < element.childNodes.length; i++) {
  1402. var child = element.childNodes[i];
  1403. if (child.nodeType != 1) continue;
  1404. switch (child.nodeName) {
  1405. case 'source':
  1406. this.source = child.textContent;
  1407. break;
  1408. case 'minfilter':
  1409. this.minfilter = child.textContent;
  1410. break;
  1411. case 'magfilter':
  1412. this.magfilter = child.textContent;
  1413. break;
  1414. case 'mipfilter':
  1415. this.mipfilter = child.textContent;
  1416. break;
  1417. case 'wrap_s':
  1418. this.wrap_s = child.textContent;
  1419. break;
  1420. case 'wrap_t':
  1421. this.wrap_t = child.textContent;
  1422. break;
  1423. default:
  1424. console.log("unhandled Sampler2D prop: " + child.nodeName);
  1425. break;
  1426. }
  1427. }
  1428. return this;
  1429. }
  1430. function Effect() {
  1431. this.id = "";
  1432. this.name = "";
  1433. this.shader = null;
  1434. this.surface;
  1435. this.sampler;
  1436. }
  1437. Effect.prototype.create = function() {
  1438. if (this.shader == null) {
  1439. return null;
  1440. }
  1441. }
  1442. Effect.prototype.parse = function(element) {
  1443. this.id = element.getAttribute('id');
  1444. this.name = element.getAttribute('name');
  1445. this.shader = null;
  1446. for (var i = 0; i < element.childNodes.length; i++) {
  1447. var child = element.childNodes[i];
  1448. if (child.nodeType != 1) continue;
  1449. switch (child.nodeName) {
  1450. case 'profile_COMMON':
  1451. this.parseTechnique(this.parseProfileCOMMON(child));
  1452. break;
  1453. default:
  1454. break;
  1455. }
  1456. }
  1457. return this;
  1458. }
  1459. Effect.prototype.parseNewparam = function(element) {
  1460. var sid = element.getAttribute('sid');
  1461. for (var i = 0; i < element.childNodes.length; i++) {
  1462. var child = element.childNodes[i];
  1463. if (child.nodeType != 1) continue;
  1464. switch (child.nodeName) {
  1465. case 'surface':
  1466. this.surface = (new Surface(this)).parse(child);
  1467. this.surface.sid = sid;
  1468. break;
  1469. case 'sampler2D':
  1470. this.sampler = (new Sampler2D(this)).parse(child);
  1471. this.sampler.sid = sid;
  1472. break;
  1473. case 'extra':
  1474. break;
  1475. default:
  1476. console.log(child.nodeName);
  1477. break;
  1478. }
  1479. }
  1480. }
  1481. Effect.prototype.parseProfileCOMMON = function(element) {
  1482. var technique;
  1483. for (var i = 0; i < element.childNodes.length; i++) {
  1484. var child = element.childNodes[i];
  1485. if (child.nodeType != 1) continue;
  1486. switch (child.nodeName) {
  1487. case 'profile_COMMON':
  1488. this.parseProfileCOMMON(child);
  1489. break;
  1490. case 'technique':
  1491. technique = child;
  1492. break;
  1493. case 'newparam':
  1494. this.parseNewparam(child);
  1495. break;
  1496. case 'extra':
  1497. break;
  1498. default:
  1499. console.log(child.nodeName);
  1500. break;
  1501. }
  1502. }
  1503. return technique;
  1504. }
  1505. Effect.prototype.parseTechnique= function(element) {
  1506. for (var i = 0; i < element.childNodes.length; i++) {
  1507. var child = element.childNodes[i];
  1508. if (child.nodeType != 1) continue;
  1509. switch (child.nodeName) {
  1510. case 'lambert':
  1511. case 'blinn':
  1512. case 'phong':
  1513. this.shader = (new Shader(child.nodeName, this)).parse(child);
  1514. break;
  1515. default:
  1516. break;
  1517. }
  1518. }
  1519. }
  1520. function InstanceEffect() {
  1521. this.url = "";
  1522. }
  1523. InstanceEffect.prototype.parse = function(element) {
  1524. this.url = element.getAttribute('url').replace(/^#/, '');
  1525. return this;
  1526. }
  1527. function Animation() {
  1528. this.id = "";
  1529. this.name = "";
  1530. this.source = {};
  1531. this.sampler = [];
  1532. this.channel = [];
  1533. }
  1534. Animation.prototype.parse = function(element) {
  1535. this.id = element.getAttribute('id');
  1536. this.name = element.getAttribute('name');
  1537. this.source = {};
  1538. for (var i = 0; i < element.childNodes.length; i++) {
  1539. var child = element.childNodes[i];
  1540. if (child.nodeType != 1) continue;
  1541. switch (child.nodeName) {
  1542. case 'source':
  1543. var src = (new Source()).parse(child);
  1544. this.source[src.id] = src;
  1545. break;
  1546. case 'sampler':
  1547. this.sampler.push((new Sampler(this)).parse(child));
  1548. break;
  1549. case 'channel':
  1550. this.channel.push((new Channel(this)).parse(child));
  1551. break;
  1552. default:
  1553. break;
  1554. }
  1555. }
  1556. return this;
  1557. }
  1558. function Channel(animation) {
  1559. this.animation = animation;
  1560. this.source = "";
  1561. this.target = "";
  1562. this.sid;
  1563. this.dotSyntax;
  1564. this.arrSyntax;
  1565. this.arrIndices;
  1566. this.member;
  1567. }
  1568. Channel.prototype.parse = function(element) {
  1569. this.source = element.getAttribute('source').replace(/^#/, '');
  1570. this.target = element.getAttribute('target');
  1571. var parts = this.target.split('/');
  1572. var id = parts.shift();
  1573. var sid = parts.shift();
  1574. var dotSyntax = (sid.indexOf(".") >= 0);
  1575. var arrSyntax = (sid.indexOf("(") >= 0);
  1576. var arrIndices;
  1577. var member;
  1578. if (dotSyntax) {
  1579. parts = sid.split(".");
  1580. sid = parts.shift();
  1581. member = parts.shift();
  1582. } else if (arrSyntax) {
  1583. arrIndices = sid.split("(");
  1584. sid = arrIndices.shift();
  1585. for (var j = 0; j < arrIndices.length; j++) {
  1586. arrIndices[j] = parseInt(arrIndices[j].replace(/\)/, ''));
  1587. }
  1588. }
  1589. this.sid = sid;
  1590. this.dotSyntax = dotSyntax;
  1591. this.arrSyntax = arrSyntax;
  1592. this.arrIndices = arrIndices;
  1593. this.member = member;
  1594. return this;
  1595. }
  1596. function Sampler(animation) {
  1597. this.id = "";
  1598. this.animation = animation;
  1599. this.inputs = [];
  1600. this.input;
  1601. this.output;
  1602. this.interpolation;
  1603. this.startTime;
  1604. this.endTime;
  1605. this.duration = 0;
  1606. }
  1607. Sampler.prototype.parse = function(element) {
  1608. this.id = element.getAttribute('id');
  1609. this.inputs = [];
  1610. for (var i = 0; i < element.childNodes.length; i++) {
  1611. var child = element.childNodes[i];
  1612. if (child.nodeType != 1) continue;
  1613. switch (child.nodeName) {
  1614. case 'input':
  1615. this.inputs.push((new Input()).parse(child));
  1616. break;
  1617. default:
  1618. break;
  1619. }
  1620. }
  1621. return this;
  1622. }
  1623. Sampler.prototype.create = function() {
  1624. for (var i = 0; i < this.inputs.length; i++) {
  1625. var input = this.inputs[i];
  1626. var source = this.animation.source[input.source];
  1627. switch (input.semantic) {
  1628. case 'INPUT':
  1629. this.input = source.read();
  1630. break;
  1631. case 'OUTPUT':
  1632. this.output = source.read();
  1633. break;
  1634. case 'INTERPOLATION':
  1635. this.interpolation = source.read();
  1636. break;
  1637. case 'IN_TANGENT':
  1638. break;
  1639. case 'OUT_TANGENT':
  1640. break;
  1641. default:
  1642. console.log(input.semantic);
  1643. break;
  1644. }
  1645. }
  1646. this.startTime = 0;
  1647. this.endTime = 0;
  1648. this.duration = 0;
  1649. if (this.input.length) {
  1650. this.startTime = 100000000;
  1651. this.endTime = -100000000;
  1652. for (var i = 0; i < this.input.length; i++) {
  1653. this.startTime = Math.min(this.startTime, this.input[i]);
  1654. this.endTime = Math.max(this.endTime, this.input[i]);
  1655. }
  1656. this.duration = this.endTime - this.startTime;
  1657. }
  1658. }
  1659. function _source(element) {
  1660. var id = element.getAttribute('id');
  1661. if (sources[id] != undefined) {
  1662. return sources[id];
  1663. }
  1664. sources[id] = (new Source(id)).parse(element);
  1665. return sources[id];
  1666. }
  1667. function _nsResolver (nsPrefix) {
  1668. if (nsPrefix == "dae") {
  1669. return "http://www.collada.org/2005/11/COLLADASchema";
  1670. }
  1671. return null;
  1672. }
  1673. function _bools ( str ) {
  1674. var raw = _strings(str);
  1675. var data = [];
  1676. var i;
  1677. for (i = 0; i < raw.length; i++) {
  1678. data.push((raw[i] == 'true' || raw[i] == '1') ? true : false);
  1679. }
  1680. return data;
  1681. }
  1682. function _floats ( str ) {
  1683. var raw = _strings(str);
  1684. var data = [];
  1685. var i;
  1686. for (i = 0; i < raw.length; i++) {
  1687. data.push( parseFloat(raw[i]) );
  1688. }
  1689. return data;
  1690. }
  1691. function _ints ( str ) {
  1692. var raw = _strings(str);
  1693. var data = [];
  1694. var i;
  1695. for (i = 0; i < raw.length; i++) {
  1696. data.push( parseInt(raw[i], 10) );
  1697. }
  1698. return data;
  1699. }
  1700. function _strings ( str ) {
  1701. return _trimString(str).split(/\s+/);
  1702. }
  1703. function _trimString ( str ) {
  1704. return str.replace(/^\s+/, "").replace(/\s+$/, "");
  1705. }
  1706. function _attr_as_float ( element, name, defaultValue ) {
  1707. if ( element.hasAttribute(name) ) {
  1708. return parseFloat(element.getAttribute(name));
  1709. } else {
  1710. return defaultValue;
  1711. }
  1712. }
  1713. function _attr_as_int ( element, name, defaultValue ) {
  1714. if ( element.hasAttribute(name) ) {
  1715. return parseInt(element.getAttribute(name), 10);
  1716. } else {
  1717. return defaultValue;
  1718. }
  1719. }
  1720. function _attr_as_string ( element, name, defaultValue ) {
  1721. if ( element.hasAttribute(name) ) {
  1722. return element.getAttribute(name);
  1723. } else {
  1724. return defaultValue;
  1725. }
  1726. }
  1727. function _format_float(f, num) {
  1728. if (f === undefined) {
  1729. var s = '0.';
  1730. while (s.length < num + 2) {
  1731. s += '0';
  1732. }
  1733. return s;
  1734. }
  1735. var parts = f.toString().split('.');
  1736. num = num || 2;
  1737. parts[1] = parts.length > 1 ? parts[1].substr(0, num) : "0";
  1738. while(parts[1].length < num) {
  1739. parts[1] += '0';
  1740. }
  1741. return parts.join('.');
  1742. }
  1743. function _hash_vertex(v, n, t0, t1, precision) {
  1744. precision = precision || 2;
  1745. var s = v instanceof THREE.Vertex ? _hash_vector3(v.position, precision) : _hash_vector3(v, precision);
  1746. if (n === undefined) {
  1747. s += '_0.00,0.00,0.00';
  1748. } else {
  1749. s += '_' + _hash_vector3(n, precision);
  1750. }
  1751. if (t0 === undefined) {
  1752. s += '_0.00,0.00';
  1753. } else {
  1754. s += '_' + _hash_uv(t0, precision);
  1755. }
  1756. if (t1 === undefined) {
  1757. s += '_0.00,0.00';
  1758. } else {
  1759. s += '_' + _hash_uv(t1, precision);
  1760. }
  1761. return s;
  1762. }
  1763. function _hash_uv(uv, num) {
  1764. var s = '';
  1765. s += _format_float(uv.u, num) + ',';
  1766. s += _format_float(uv.v, num);
  1767. return s;
  1768. }
  1769. function _hash_vector3(vec, num) {
  1770. var s = '';
  1771. s += _format_float(vec.x, num) + ',';
  1772. s += _format_float(vec.y, num) + ',';
  1773. s += _format_float(vec.z, num);
  1774. return s;
  1775. }
  1776. function evaluateXPath(node, query) {
  1777. var instances = COLLADA.evaluate(query,
  1778. node,
  1779. _nsResolver,
  1780. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  1781. null);
  1782. var inst = instances.iterateNext();
  1783. var result = [];
  1784. while (inst) {
  1785. result.push(inst);
  1786. inst = instances.iterateNext();
  1787. }
  1788. return result;
  1789. }
  1790. return {
  1791. load: load,
  1792. setPreferredShading: setPreferredShading,
  1793. geometries : geometries
  1794. };
  1795. })();