2
0

glTFLoader.js 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  1. /**
  2. * @author Tony Parisi / http://www.tonyparisi.com/
  3. */
  4. THREE.glTFLoader = function (showStatus) {
  5. this.meshesRequested = 0;
  6. this.meshesLoaded = 0;
  7. this.pendingMeshes = [];
  8. this.animationsRequested = 0;
  9. this.animationsLoaded = 0;
  10. this.animations = [];
  11. this.shadersRequested = 0;
  12. this.shadersLoaded = 0;
  13. this.shaders = {};
  14. THREE.Loader.call( this, showStatus );
  15. }
  16. THREE.glTFLoader.prototype = new THREE.Loader();
  17. THREE.glTFLoader.prototype.constructor = THREE.glTFLoader;
  18. THREE.glTFLoader.prototype.load = function( url, callback ) {
  19. var theLoader = this;
  20. // Utilities
  21. function RgbArraytoHex(colorArray) {
  22. if(!colorArray) return 0xFFFFFFFF;
  23. var r = Math.floor(colorArray[0] * 255),
  24. g = Math.floor(colorArray[1] * 255),
  25. b = Math.floor(colorArray[2] * 255),
  26. a = 255;
  27. var color = (a << 24) + (r << 16) + (g << 8) + b;
  28. return color;
  29. }
  30. function convertAxisAngleToQuaternion(rotations, count)
  31. {
  32. var q = new THREE.Quaternion;
  33. var axis = new THREE.Vector3;
  34. var euler = new THREE.Vector3;
  35. var i;
  36. for (i = 0; i < count; i++) {
  37. axis.set(rotations[i * 4], rotations[i * 4 + 1],
  38. rotations[i * 4 + 2]).normalize();
  39. var angle = rotations[i * 4 + 3];
  40. q.setFromAxisAngle(axis, angle);
  41. rotations[i * 4] = q.x;
  42. rotations[i * 4 + 1] = q.y;
  43. rotations[i * 4 + 2] = q.z;
  44. rotations[i * 4 + 3] = q.w;
  45. }
  46. }
  47. function componentsPerElementForGLType(glType) {
  48. switch (glType) {
  49. case WebGLRenderingContext.FLOAT :
  50. case WebGLRenderingContext.UNSIGNED_BYTE :
  51. case WebGLRenderingContext.UNSIGNED_SHORT :
  52. return 1;
  53. case WebGLRenderingContext.FLOAT_VEC2 :
  54. return 2;
  55. case WebGLRenderingContext.FLOAT_VEC3 :
  56. return 3;
  57. case WebGLRenderingContext.FLOAT_VEC4 :
  58. return 4;
  59. case WebGLRenderingContext.FLOAT_MAT4 :
  60. return 16;
  61. default:
  62. return null;
  63. }
  64. }
  65. function LoadTexture(src) {
  66. if(!src) { return null; }
  67. return THREE.ImageUtils.loadTexture(src);
  68. }
  69. // Geometry processing
  70. var ClassicGeometry = function() {
  71. this.geometry = new THREE.BufferGeometry;
  72. this.totalAttributes = 0;
  73. this.loadedAttributes = 0;
  74. this.indicesLoaded = false;
  75. this.finished = false;
  76. this.onload = null;
  77. this.uvs = null;
  78. this.indexArray = null;
  79. };
  80. ClassicGeometry.prototype.constructor = ClassicGeometry;
  81. ClassicGeometry.prototype.buildBufferGeometry = function() {
  82. // Build indexed mesh
  83. var geometry = this.geometry;
  84. geometry.attributes.index = {
  85. itemSize: 1,
  86. array : this.indexArray
  87. };
  88. var offset = {
  89. start: 0,
  90. index: 0,
  91. count: this.indexArray.length
  92. };
  93. geometry.offsets.push( offset );
  94. geometry.computeBoundingSphere();
  95. }
  96. ClassicGeometry.prototype.checkFinished = function() {
  97. if(this.indexArray && this.loadedAttributes === this.totalAttributes) {
  98. this.buildBufferGeometry();
  99. this.finished = true;
  100. if(this.onload) {
  101. this.onload();
  102. }
  103. }
  104. };
  105. // Delegate for processing index buffers
  106. var IndicesDelegate = function() {};
  107. IndicesDelegate.prototype.handleError = function(errorCode, info) {
  108. // FIXME: report error
  109. console.log("ERROR(IndicesDelegate):"+errorCode+":"+info);
  110. };
  111. IndicesDelegate.prototype.convert = function(resource, ctx) {
  112. return new Uint16Array(resource, 0, ctx.indices.count);
  113. };
  114. IndicesDelegate.prototype.resourceAvailable = function(glResource, ctx) {
  115. var geometry = ctx.geometry;
  116. geometry.indexArray = glResource;
  117. geometry.checkFinished();
  118. return true;
  119. };
  120. var indicesDelegate = new IndicesDelegate();
  121. var IndicesContext = function(indices, geometry) {
  122. this.indices = indices;
  123. this.geometry = geometry;
  124. };
  125. // Delegate for processing vertex attribute buffers
  126. var VertexAttributeDelegate = function() {};
  127. VertexAttributeDelegate.prototype.handleError = function(errorCode, info) {
  128. // FIXME: report error
  129. console.log("ERROR(VertexAttributeDelegate):"+errorCode+":"+info);
  130. };
  131. VertexAttributeDelegate.prototype.convert = function(resource, ctx) {
  132. return resource;
  133. };
  134. VertexAttributeDelegate.prototype.arrayResourceAvailable = function(glResource, ctx) {
  135. var geom = ctx.geometry;
  136. var attribute = ctx.attribute;
  137. var semantic = ctx.semantic;
  138. var floatArray;
  139. var i, l;
  140. //FIXME: Float32 is assumed here, but should be checked.
  141. if(semantic == "POSITION") {
  142. // TODO: Should be easy to take strides into account here
  143. floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
  144. for(i = 0, l = floatArray.length; i < l; i += 3) {
  145. geom.geometry.vertices.push( new THREE.Vector3( floatArray[i], floatArray[i+1], floatArray[i+2] ) );
  146. }
  147. } else if(semantic == "NORMAL") {
  148. geom.geometry.normals = [];
  149. floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
  150. for(i = 0, l = floatArray.length; i < l; i += 3) {
  151. geom.geometry.normals.push( new THREE.Vector3( floatArray[i], floatArray[i+1], floatArray[i+2] ) );
  152. }
  153. } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) {
  154. geom.uvs = [];
  155. floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
  156. for(i = 0, l = floatArray.length; i < l; i += 2) {
  157. geom.uvs.push( new THREE.Vector2( floatArray[i], 1.0 - floatArray[i+1] ) );
  158. }
  159. }
  160. else if (semantic == "WEIGHT") {
  161. nComponents = componentsPerElementForGLType(attribute.type);
  162. floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
  163. for(i = 0, l = floatArray.length; i < l; i += 4) {
  164. geom.geometry.skinWeights.push( new THREE.Vector4( floatArray[i], floatArray[i+1], floatArray[i+2], floatArray[i+3] ) );
  165. }
  166. }
  167. else if (semantic == "JOINT") {
  168. nComponents = componentsPerElementForGLType(attribute.type);
  169. floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
  170. for(i = 0, l = floatArray.length; i < l; i += 4) {
  171. geom.geometry.skinIndices.push( new THREE.Vector4( floatArray[i], floatArray[i+1], floatArray[i+2], floatArray[i+3] ) );
  172. }
  173. }
  174. }
  175. VertexAttributeDelegate.prototype.bufferResourceAvailable = function(glResource, ctx) {
  176. var geom = ctx.geometry;
  177. var attribute = ctx.attribute;
  178. var semantic = ctx.semantic;
  179. var floatArray;
  180. var i, l;
  181. var nComponents;
  182. //FIXME: Float32 is assumed here, but should be checked.
  183. if(semantic == "POSITION") {
  184. // TODO: Should be easy to take strides into account here
  185. floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
  186. geom.geometry.attributes.position = {
  187. itemSize: 3,
  188. array : floatArray
  189. };
  190. } else if(semantic == "NORMAL") {
  191. floatArray = new Float32Array(glResource, 0, attribute.count * componentsPerElementForGLType(attribute.type));
  192. geom.geometry.attributes.normal = {
  193. itemSize: 3,
  194. array : floatArray
  195. };
  196. } else if ((semantic == "TEXCOORD_0") || (semantic == "TEXCOORD" )) {
  197. nComponents = componentsPerElementForGLType(attribute.type);
  198. floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
  199. // N.B.: flip Y value... should we just set texture.flipY everywhere?
  200. for (i = 0; i < floatArray.length / 2; i++) {
  201. floatArray[i*2+1] = 1.0 - floatArray[i*2+1];
  202. }
  203. geom.geometry.attributes.uv = {
  204. itemSize: nComponents,
  205. array : floatArray
  206. };
  207. }
  208. else if (semantic == "WEIGHT") {
  209. nComponents = componentsPerElementForGLType(attribute.type);
  210. floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
  211. geom.geometry.attributes.skinWeight = {
  212. itemSize: nComponents,
  213. array : floatArray
  214. };
  215. }
  216. else if (semantic == "JOINT") {
  217. nComponents = componentsPerElementForGLType(attribute.type);
  218. floatArray = new Float32Array(glResource, 0, attribute.count * nComponents);
  219. geom.geometry.attributes.skinIndex = {
  220. itemSize: nComponents,
  221. array : floatArray
  222. };
  223. }
  224. }
  225. VertexAttributeDelegate.prototype.resourceAvailable = function(glResource, ctx) {
  226. this.bufferResourceAvailable(glResource, ctx);
  227. var geom = ctx.geometry;
  228. geom.loadedAttributes++;
  229. geom.checkFinished();
  230. return true;
  231. };
  232. var vertexAttributeDelegate = new VertexAttributeDelegate();
  233. var VertexAttributeContext = function(attribute, semantic, geometry) {
  234. this.attribute = attribute;
  235. this.semantic = semantic;
  236. this.geometry = geometry;
  237. };
  238. var Mesh = function() {
  239. this.primitives = [];
  240. this.materialsPending = [];
  241. this.loadedGeometry = 0;
  242. this.onCompleteCallbacks = [];
  243. };
  244. Mesh.prototype.addPrimitive = function(geometry, material) {
  245. var self = this;
  246. geometry.onload = function() {
  247. self.loadedGeometry++;
  248. self.checkComplete();
  249. };
  250. this.primitives.push({
  251. geometry: geometry,
  252. material: material,
  253. mesh: null
  254. });
  255. };
  256. Mesh.prototype.onComplete = function(callback) {
  257. this.onCompleteCallbacks.push(callback);
  258. this.checkComplete();
  259. };
  260. Mesh.prototype.checkComplete = function() {
  261. var self = this;
  262. if(this.onCompleteCallbacks.length && this.primitives.length == this.loadedGeometry) {
  263. this.onCompleteCallbacks.forEach(function(callback) {
  264. callback(self);
  265. });
  266. this.onCompleteCallbacks = [];
  267. }
  268. };
  269. Mesh.prototype.attachToNode = function(threeNode) {
  270. // Assumes that the geometry is complete
  271. this.primitives.forEach(function(primitive) {
  272. /*if(!primitive.mesh) {
  273. primitive.mesh = new THREE.Mesh(primitive.geometry, primitive.material);
  274. }*/
  275. var material = primitive.material;
  276. if (!(material instanceof THREE.Material)) {
  277. material = theLoader.createShaderMaterial(material);
  278. }
  279. var threeMesh = new THREE.Mesh(primitive.geometry.geometry, material);
  280. threeMesh.castShadow = true;
  281. threeNode.add(threeMesh);
  282. });
  283. };
  284. // Delayed-loaded material
  285. var Material = function(params) {
  286. this.params = params;
  287. };
  288. // Delegate for processing animation parameter buffers
  289. var AnimationParameterDelegate = function() {};
  290. AnimationParameterDelegate.prototype.handleError = function(errorCode, info) {
  291. // FIXME: report error
  292. console.log("ERROR(AnimationParameterDelegate):"+errorCode+":"+info);
  293. };
  294. AnimationParameterDelegate.prototype.convert = function(resource, ctx) {
  295. var parameter = ctx.parameter;
  296. var glResource = null;
  297. switch (parameter.type) {
  298. case WebGLRenderingContext.FLOAT :
  299. case WebGLRenderingContext.FLOAT_VEC2 :
  300. case WebGLRenderingContext.FLOAT_VEC3 :
  301. case WebGLRenderingContext.FLOAT_VEC4 :
  302. glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type));
  303. break;
  304. default:
  305. break;
  306. }
  307. return glResource;
  308. };
  309. AnimationParameterDelegate.prototype.resourceAvailable = function(glResource, ctx) {
  310. var animation = ctx.animation;
  311. var parameter = ctx.parameter;
  312. parameter.data = glResource;
  313. animation.handleParameterLoaded(parameter);
  314. return true;
  315. };
  316. var animationParameterDelegate = new AnimationParameterDelegate();
  317. var AnimationParameterContext = function(parameter, animation) {
  318. this.parameter = parameter;
  319. this.animation = animation;
  320. };
  321. // Animations
  322. var Animation = function() {
  323. // create Three.js keyframe here
  324. this.totalParameters = 0;
  325. this.loadedParameters = 0;
  326. this.parameters = {};
  327. this.finishedLoading = false;
  328. this.onload = null;
  329. };
  330. Animation.prototype.constructor = Animation;
  331. Animation.prototype.handleParameterLoaded = function(parameter) {
  332. this.parameters[parameter.name] = parameter;
  333. this.loadedParameters++;
  334. this.checkFinished();
  335. };
  336. Animation.prototype.checkFinished = function() {
  337. if(this.loadedParameters === this.totalParameters) {
  338. // Build animation
  339. this.finishedLoading = true;
  340. if (this.onload) {
  341. this.onload();
  342. }
  343. }
  344. };
  345. // Delegate for processing inverse bind matrices buffer
  346. var InverseBindMatricesDelegate = function() {};
  347. InverseBindMatricesDelegate.prototype.handleError = function(errorCode, info) {
  348. // FIXME: report error
  349. console.log("ERROR(InverseBindMatricesDelegate):"+errorCode+":"+info);
  350. };
  351. InverseBindMatricesDelegate.prototype.convert = function(resource, ctx) {
  352. var parameter = ctx.parameter;
  353. var glResource = null;
  354. switch (parameter.type) {
  355. case WebGLRenderingContext.FLOAT_MAT4 :
  356. glResource = new Float32Array(resource, 0, parameter.count * componentsPerElementForGLType(parameter.type));
  357. break;
  358. default:
  359. break;
  360. }
  361. return glResource;
  362. };
  363. InverseBindMatricesDelegate.prototype.resourceAvailable = function(glResource, ctx) {
  364. var skin = ctx.skin;
  365. skin.inverseBindMatrices = glResource;
  366. return true;
  367. };
  368. var inverseBindMatricesDelegate = new InverseBindMatricesDelegate();
  369. var InverseBindMatricesContext = function(param, skin) {
  370. this.parameter = param;
  371. this.skin = skin;
  372. };
  373. // Delegate for processing shaders from external files
  374. var ShaderDelegate = function() {};
  375. ShaderDelegate.prototype.handleError = function(errorCode, info) {
  376. // FIXME: report error
  377. console.log("ERROR(ShaderDelegate):"+errorCode+":"+info);
  378. };
  379. ShaderDelegate.prototype.convert = function(resource, ctx) {
  380. return resource;
  381. }
  382. ShaderDelegate.prototype.resourceAvailable = function(data, ctx) {
  383. theLoader.shadersLoaded++;
  384. theLoader.shaders[ctx.id] = data;
  385. return true;
  386. };
  387. var shaderDelegate = new ShaderDelegate();
  388. var ShaderContext = function(id, path) {
  389. this.id = id;
  390. this.path = path;
  391. };
  392. // Resource management
  393. var ResourceEntry = function(entryID, object, description) {
  394. this.entryID = entryID;
  395. this.object = object;
  396. this.description = description;
  397. };
  398. var Resources = function() {
  399. this._entries = {};
  400. };
  401. Resources.prototype.setEntry = function(entryID, object, description) {
  402. if (!entryID) {
  403. console.error("No EntryID provided, cannot store", description);
  404. return;
  405. }
  406. if (this._entries[entryID]) {
  407. console.warn("entry["+entryID+"] is being overwritten");
  408. }
  409. this._entries[entryID] = new ResourceEntry(entryID, object, description );
  410. };
  411. Resources.prototype.getEntry = function(entryID) {
  412. return this._entries[entryID];
  413. };
  414. Resources.prototype.clearEntries = function() {
  415. this._entries = {};
  416. };
  417. LoadDelegate = function() {
  418. }
  419. LoadDelegate.prototype.loadCompleted = function(callback, obj) {
  420. callback.call(Window, obj);
  421. }
  422. // Loader
  423. var ThreeGLTFLoader = Object.create(glTFParser, {
  424. load: {
  425. enumerable: true,
  426. value: function(userInfo, options) {
  427. this.resources = new Resources();
  428. this.cameras = [];
  429. this.lights = [];
  430. this.animations = [];
  431. this.joints = {};
  432. this.skeltons = {};
  433. THREE.GLTFLoaderUtils.init();
  434. glTFParser.load.call(this, userInfo, options);
  435. }
  436. },
  437. cameras: {
  438. enumerable: true,
  439. writable: true,
  440. value : []
  441. },
  442. lights: {
  443. enumerable: true,
  444. writable: true,
  445. value : []
  446. },
  447. animations: {
  448. enumerable: true,
  449. writable: true,
  450. value : []
  451. },
  452. // Implement WebGLTFLoader handlers
  453. handleBuffer: {
  454. value: function(entryID, description, userInfo) {
  455. this.resources.setEntry(entryID, null, description);
  456. description.type = "ArrayBuffer";
  457. return true;
  458. }
  459. },
  460. handleBufferView: {
  461. value: function(entryID, description, userInfo) {
  462. this.resources.setEntry(entryID, null, description);
  463. var buffer = this.resources.getEntry(description.buffer);
  464. description.type = "ArrayBufferView";
  465. var bufferViewEntry = this.resources.getEntry(entryID);
  466. bufferViewEntry.buffer = buffer;
  467. return true;
  468. }
  469. },
  470. handleShader: {
  471. value: function(entryID, description, userInfo) {
  472. this.resources.setEntry(entryID, null, description);
  473. var shaderRequest = {
  474. id : entryID,
  475. path : description.path,
  476. };
  477. var shaderContext = new ShaderContext(entryID, description.path);
  478. theLoader.shadersRequested++;
  479. THREE.GLTFLoaderUtils.getFile(shaderRequest, shaderDelegate, shaderContext);
  480. return true;
  481. }
  482. },
  483. handleProgram: {
  484. value: function(entryID, description, userInfo) {
  485. this.resources.setEntry(entryID, null, description);
  486. return true;
  487. }
  488. },
  489. handleTechnique: {
  490. value: function(entryID, description, userInfo) {
  491. this.resources.setEntry(entryID, null, description);
  492. return true;
  493. }
  494. },
  495. createShaderMaterial : {
  496. value: function(material) {
  497. var fragmentShader = theLoader.shaders[material.params.fragmentShader];
  498. if (!fragmentShader) {
  499. console.log("ERROR: Missing fragment shader definition:", material.params.fragmentShader);
  500. return new THREE.MeshPhongMaterial;
  501. }
  502. var vertexShader = theLoader.shaders[material.params.vertexShader];
  503. if (!fragmentShader) {
  504. console.log("ERROR: Missing vertex shader definition:", material.params.vertexShader);
  505. return new THREE.MeshPhongMaterial;
  506. }
  507. var uniforms = {};
  508. var shaderMaterial = new THREE.ShaderMaterial( {
  509. fragmentShader: fragmentShader,
  510. vertexShader: vertexShader,
  511. uniforms: uniforms,
  512. } );
  513. return new THREE.MeshPhongMaterial(material.params);
  514. }
  515. },
  516. createShaderParams : {
  517. value: function(materialId, values, params, instanceProgram) {
  518. var program = this.resources.getEntry(instanceProgram.program);
  519. if (program) {
  520. params.fragmentShader = program.description.fragmentShader;
  521. params.vertexShader = program.description.vertexShader;
  522. params.attributes = instanceProgram.attributes;
  523. params.uniforms = instanceProgram.uniforms;
  524. }
  525. }
  526. },
  527. threeJSMaterialType : {
  528. value: function(materialId, technique, values, params) {
  529. var materialType = THREE.MeshPhongMaterial;
  530. var defaultPass = null;
  531. if (technique && technique.description && technique.description.passes)
  532. defaultPass = technique.description.passes.defaultPass;
  533. if (defaultPass) {
  534. if (defaultPass.details && defaultPass.details.commonProfile) {
  535. var profile = technique.description.passes.defaultPass.details.commonProfile;
  536. if (profile)
  537. {
  538. switch (profile.lightingModel)
  539. {
  540. case 'Blinn' :
  541. case 'Phong' :
  542. materialType = THREE.MeshPhongMaterial;
  543. break;
  544. case 'Lambert' :
  545. materialType = THREE.MeshLambertMaterial;
  546. break;
  547. default :
  548. materialType = THREE.MeshBasicMaterial;
  549. break;
  550. }
  551. if (profile.extras && profile.extras.doubleSided)
  552. {
  553. params.side = THREE.DoubleSide;
  554. }
  555. }
  556. }
  557. else if (defaultPass.instanceProgram) {
  558. var instanceProgram = defaultPass.instanceProgram;
  559. this.createShaderParams(materialId, values, params, instanceProgram);
  560. var loadshaders = true;
  561. if (loadshaders) {
  562. materialType = Material;
  563. }
  564. }
  565. }
  566. var texturePath = null;
  567. var textureParams = null;
  568. var diffuse = values.diffuse;
  569. if (diffuse)
  570. {
  571. var texture = diffuse;
  572. if (texture) {
  573. var textureEntry = this.resources.getEntry(texture);
  574. if (textureEntry) {
  575. {
  576. var imageEntry = this.resources.getEntry(textureEntry.description.source);
  577. if (imageEntry) {
  578. texturePath = imageEntry.description.path;
  579. }
  580. var samplerEntry = this.resources.getEntry(textureEntry.description.sampler);
  581. if (samplerEntry) {
  582. textureParams = samplerEntry.description;
  583. }
  584. }
  585. }
  586. }
  587. }
  588. var texture = LoadTexture(texturePath);
  589. if (texture && textureParams) {
  590. if (textureParams.wrapS == WebGLRenderingContext.REPEAT)
  591. texture.wrapS = THREE.RepeatWrapping;
  592. if (textureParams.wrapT == WebGLRenderingContext.REPEAT)
  593. texture.wrapT = THREE.RepeatWrapping;
  594. if (textureParams.magFilter == WebGLRenderingContext.LINEAR)
  595. texture.magFilter = THREE.LinearFilter;
  596. // if (textureParams.minFilter == "LINEAR")
  597. // texture.minFilter = THREE.LinearFilter;
  598. params.map = texture;
  599. }
  600. var envMapPath = null;
  601. var envMapParams = null;
  602. var reflective = values.reflective;
  603. if (reflective)
  604. {
  605. var texture = reflective;
  606. if (texture) {
  607. var textureEntry = this.resources.getEntry(texture);
  608. if (textureEntry) {
  609. {
  610. var imageEntry = this.resources.getEntry(textureEntry.description.source);
  611. if (imageEntry) {
  612. envMapPath = imageEntry.description.path;
  613. }
  614. var samplerEntry = this.resources.getEntry(textureEntry.description.sampler);
  615. if (samplerEntry) {
  616. envMapParams = samplerEntry.description;
  617. }
  618. }
  619. }
  620. }
  621. }
  622. var texture = LoadTexture(envMapPath);
  623. if (texture && envMapParams) {
  624. if (envMapParams.wrapS == WebGLRenderingContext.REPEAT)
  625. texture.wrapS = THREE.RepeatWrapping;
  626. if (envMapParams.wrapT == WebGLRenderingContext.REPEAT)
  627. texture.wrapT = THREE.RepeatWrapping;
  628. if (envMapParams.magFilter == WebGLRenderingContext.LINEAR)
  629. texture.magFilter = THREE.LinearFilter;
  630. // if (envMapParams.minFilter == WebGLRenderingContext.LINEAR)
  631. // texture.minFilter = THREE.LinearFilter;
  632. params.envMap = texture;
  633. }
  634. var shininess = values.shininesss || values.shininess; // N.B.: typo in converter!
  635. if (shininess)
  636. {
  637. shininess = shininess;
  638. }
  639. var diffuseColor = !texturePath ? diffuse : null;
  640. var opacity = 1.0;
  641. if (values.hasOwnProperty("transparency"))
  642. {
  643. var USE_A_ONE = true; // for now, hack because file format isn't telling us
  644. opacity = USE_A_ONE ? values.transparency : (1.0 - values.transparency);
  645. }
  646. // if (diffuseColor) diffuseColor = [0, 1, 0];
  647. params.color = RgbArraytoHex(diffuseColor);
  648. params.opacity = opacity;
  649. params.transparent = opacity < 1.0;
  650. // hack hack hack
  651. if (texturePath && texturePath.toLowerCase().indexOf(".png") != -1)
  652. params.transparent = true;
  653. if (!(shininess === undefined))
  654. {
  655. params.shininess = shininess;
  656. }
  657. if (!(values.ambient === undefined) && !(typeof(values.ambient) == 'string'))
  658. {
  659. params.ambient = RgbArraytoHex(values.ambient);
  660. }
  661. if (!(values.emission === undefined))
  662. {
  663. params.emissive = RgbArraytoHex(values.emission);
  664. }
  665. if (!(values.specular === undefined))
  666. {
  667. params.specular = RgbArraytoHex(values.specular);
  668. }
  669. return materialType;
  670. }
  671. },
  672. handleMaterial: {
  673. value: function(entryID, description, userInfo) {
  674. //this should be rewritten using the meta datas that actually create the shader.
  675. //here we will infer what needs to be pass to Three.js by looking inside the technique parameters.
  676. var technique = this.resources.getEntry(description.instanceTechnique.technique);
  677. var materialParams = {};
  678. var values = description.instanceTechnique.values;
  679. var materialType = this.threeJSMaterialType(entryID, technique, values, materialParams);
  680. var material = new materialType(materialParams);
  681. this.resources.setEntry(entryID, material, description);
  682. return true;
  683. }
  684. },
  685. handleMesh: {
  686. value: function(entryID, description, userInfo) {
  687. var mesh = new Mesh();
  688. this.resources.setEntry(entryID, mesh, description);
  689. var primitivesDescription = description.primitives;
  690. if (!primitivesDescription) {
  691. //FIXME: not implemented in delegate
  692. console.log("MISSING_PRIMITIVES for mesh:"+ entryID);
  693. return false;
  694. }
  695. for (var i = 0 ; i < primitivesDescription.length ; i++) {
  696. var primitiveDescription = primitivesDescription[i];
  697. if (primitiveDescription.primitive === WebGLRenderingContext.TRIANGLES) {
  698. var geometry = new ClassicGeometry();
  699. var materialEntry = this.resources.getEntry(primitiveDescription.material);
  700. mesh.addPrimitive(geometry, materialEntry.object);
  701. var indices = this.resources.getEntry(primitiveDescription.indices);
  702. var bufferEntry = this.resources.getEntry(indices.description.bufferView);
  703. var indicesObject = {
  704. bufferView : bufferEntry,
  705. byteOffset : indices.description.byteOffset,
  706. count : indices.description.count,
  707. id : indices.entryID,
  708. type : indices.description.type
  709. };
  710. var indicesContext = new IndicesContext(indicesObject, geometry);
  711. var alreadyProcessedIndices = THREE.GLTFLoaderUtils.getBuffer(indicesObject, indicesDelegate, indicesContext);
  712. /*if(alreadyProcessedIndices) {
  713. indicesDelegate.resourceAvailable(alreadyProcessedIndices, indicesContext);
  714. }*/
  715. // Load Vertex Attributes
  716. var allAttributes = Object.keys(primitiveDescription.attributes);
  717. allAttributes.forEach( function(semantic) {
  718. geometry.totalAttributes++;
  719. var attribute;
  720. var attributeID = primitiveDescription.attributes[semantic];
  721. var attributeEntry = this.resources.getEntry(attributeID);
  722. if (!attributeEntry) {
  723. //let's just use an anonymous object for the attribute
  724. attribute = description.attributes[attributeID];
  725. attribute.id = attributeID;
  726. this.resources.setEntry(attributeID, attribute, attribute);
  727. var bufferEntry = this.resources.getEntry(attribute.bufferView);
  728. attributeEntry = this.resources.getEntry(attributeID);
  729. } else {
  730. attribute = attributeEntry.object;
  731. attribute.id = attributeID;
  732. var bufferEntry = this.resources.getEntry(attribute.bufferView);
  733. }
  734. var attributeObject = {
  735. bufferView : bufferEntry,
  736. byteOffset : attribute.byteOffset,
  737. byteStride : attribute.byteStride,
  738. count : attribute.count,
  739. max : attribute.max,
  740. min : attribute.min,
  741. type : attribute.type,
  742. id : attributeID
  743. };
  744. var attribContext = new VertexAttributeContext(attributeObject, semantic, geometry);
  745. var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(attributeObject, vertexAttributeDelegate, attribContext);
  746. /*if(alreadyProcessedAttribute) {
  747. vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
  748. }*/
  749. }, this);
  750. }
  751. }
  752. return true;
  753. }
  754. },
  755. handleCamera: {
  756. value: function(entryID, description, userInfo) {
  757. var camera;
  758. if (description.type == "perspective")
  759. {
  760. var znear = description.perspective.znear;
  761. var zfar = description.perspective.zfar;
  762. var yfov = description.perspective.yfov;
  763. var xfov = description.perspective.xfov;
  764. var aspect_ratio = description.perspective.aspect_ratio;
  765. if (!aspect_ratio)
  766. aspect_ratio = 1;
  767. if (yfov === undefined)
  768. {
  769. if (xfov)
  770. {
  771. // According to COLLADA spec...
  772. // aspect_ratio = xfov / yfov
  773. yfov = xfov / aspect_ratio;
  774. }
  775. }
  776. if (yfov)
  777. {
  778. camera = new THREE.PerspectiveCamera(yfov, aspect_ratio, znear, zfar);
  779. }
  780. }
  781. else
  782. {
  783. camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, znear, zfar );
  784. }
  785. if (camera)
  786. {
  787. this.resources.setEntry(entryID, camera, description);
  788. }
  789. return true;
  790. }
  791. },
  792. handleLight: {
  793. value: function(entryID, description, userInfo) {
  794. var light = null;
  795. var type = description.type;
  796. if (type && description[type])
  797. {
  798. var lparams = description[type];
  799. var color = RgbArraytoHex(lparams.color);
  800. switch (type) {
  801. case "directional" :
  802. light = new THREE.DirectionalLight(color);
  803. light.position.set(0, 0, 1);
  804. break;
  805. case "point" :
  806. light = new THREE.PointLight(color);
  807. break;
  808. case "spot " :
  809. light = new THREE.SpotLight(color);
  810. light.position.set(0, 0, 1);
  811. break;
  812. case "ambient" :
  813. light = new THREE.AmbientLight(color);
  814. break;
  815. }
  816. }
  817. if (light)
  818. {
  819. this.resources.setEntry(entryID, light, description);
  820. }
  821. return true;
  822. }
  823. },
  824. addPendingMesh: {
  825. value: function(mesh, threeNode) {
  826. theLoader.pendingMeshes.push({
  827. mesh: mesh,
  828. node: threeNode
  829. });
  830. }
  831. },
  832. handleNode: {
  833. value: function(entryID, description, userInfo) {
  834. var threeNode = null;
  835. if (description.jointId) {
  836. threeNode = new THREE.Bone();
  837. threeNode.jointId = description.jointId;
  838. this.joints[description.jointId] = entryID;
  839. }
  840. else {
  841. threeNode = new THREE.Object3D();
  842. }
  843. threeNode.name = description.name;
  844. this.resources.setEntry(entryID, threeNode, description);
  845. var m = description.matrix;
  846. if(m) {
  847. threeNode.applyMatrix(new THREE.Matrix4(
  848. m[0], m[4], m[8], m[12],
  849. m[1], m[5], m[9], m[13],
  850. m[2], m[6], m[10], m[14],
  851. m[3], m[7], m[11], m[15]
  852. ));
  853. threeNode.matrixAutoUpdate = false;
  854. threeNode.matrixWorldNeedsUpdate = true;
  855. }
  856. else {
  857. var t = description.translation;
  858. var r = description.rotation;
  859. var s = description.scale;
  860. var position = t ? new THREE.Vector3(t[0], t[1], t[2]) :
  861. new THREE.Vector3;
  862. if (r) {
  863. convertAxisAngleToQuaternion(r, 1);
  864. }
  865. var rotation = r ? new THREE.Quaternion(r[0], r[1], r[2], r[3]) :
  866. new THREE.Quaternion;
  867. var scale = s ? new THREE.Vector3(s[0], s[1], s[2]) :
  868. new THREE.Vector3;
  869. var matrix = new THREE.Matrix4;
  870. matrix.compose(position, rotation, scale);
  871. threeNode.matrixAutoUpdate = false;
  872. threeNode.matrixWorldNeedsUpdate = true;
  873. threeNode.applyMatrix(matrix);
  874. }
  875. var self = this;
  876. // Iterate through all node meshes and attach the appropriate objects
  877. //FIXME: decision needs to be made between these 2 ways, probably meshes will be discarded.
  878. var meshEntry;
  879. if (description.mesh) {
  880. meshEntry = this.resources.getEntry(description.mesh);
  881. theLoader.meshesRequested++;
  882. meshEntry.object.onComplete(function(mesh) {
  883. self.addPendingMesh(mesh, threeNode);
  884. theLoader.meshesLoaded++;
  885. theLoader.checkComplete();
  886. });
  887. }
  888. if (description.meshes) {
  889. description.meshes.forEach( function(meshID) {
  890. meshEntry = this.resources.getEntry(meshID);
  891. theLoader.meshesRequested++;
  892. meshEntry.object.onComplete(function(mesh) {
  893. self.addPendingMesh(mesh, threeNode);
  894. theLoader.meshesLoaded++;
  895. theLoader.checkComplete();
  896. });
  897. }, this);
  898. }
  899. if (description.instanceSkin) {
  900. var skinEntry = this.resources.getEntry(description.instanceSkin.skin);
  901. if (skinEntry) {
  902. var skin = skinEntry.object;
  903. description.instanceSkin.skin = skin;
  904. threeNode.instanceSkin = description.instanceSkin;
  905. var sources = description.instanceSkin.sources;
  906. skin.meshes = [];
  907. sources.forEach( function(meshID) {
  908. meshEntry = this.resources.getEntry(meshID);
  909. theLoader.meshesRequested++;
  910. meshEntry.object.onComplete(function(mesh) {
  911. skin.meshes.push(mesh);
  912. theLoader.meshesLoaded++;
  913. theLoader.checkComplete();
  914. });
  915. }, this);
  916. }
  917. }
  918. if (description.camera) {
  919. var cameraEntry = this.resources.getEntry(description.camera);
  920. if (cameraEntry) {
  921. threeNode.add(cameraEntry.object);
  922. this.cameras.push(cameraEntry.object);
  923. }
  924. }
  925. if (description.light) {
  926. var lightEntry = this.resources.getEntry(description.light);
  927. if (lightEntry) {
  928. threeNode.add(lightEntry.object);
  929. this.lights.push(lightEntry.object);
  930. }
  931. }
  932. return true;
  933. }
  934. },
  935. buildNodeHirerachy: {
  936. value: function(nodeEntryId, parentThreeNode) {
  937. var nodeEntry = this.resources.getEntry(nodeEntryId);
  938. var threeNode = nodeEntry.object;
  939. parentThreeNode.add(threeNode);
  940. var children = nodeEntry.description.children;
  941. if (children) {
  942. children.forEach( function(childID) {
  943. this.buildNodeHirerachy(childID, threeNode);
  944. }, this);
  945. }
  946. return threeNode;
  947. }
  948. },
  949. buildSkin: {
  950. value: function(node) {
  951. var skin = node.instanceSkin.skin;
  952. if (skin) {
  953. node.instanceSkin.skeletons.forEach(function(skeleton) {
  954. var nodeEntry = this.resources.getEntry(skeleton);
  955. if (nodeEntry) {
  956. var rootSkeleton = nodeEntry.object;
  957. var dobones = true;
  958. var i, len = skin.meshes.length;
  959. for (i = 0; i < len; i++) {
  960. var mesh = skin.meshes[i];
  961. var threeMesh = null;
  962. mesh.primitives.forEach(function(primitive) {
  963. var material = primitive.material;
  964. if (!(material instanceof THREE.Material)) {
  965. material = this.createShaderMaterial(material);
  966. }
  967. threeMesh = new THREE.SkinnedMesh(primitive.geometry.geometry, material, false);
  968. threeMesh.add(rootSkeleton);
  969. var geometry = primitive.geometry.geometry;
  970. var j;
  971. if (geometry.vertices) {
  972. for ( j = 0; j < geometry.vertices.length; j ++ ) {
  973. geometry.vertices[j].applyMatrix4( skin.bindShapeMatrix );
  974. }
  975. }
  976. else if (geometry.attributes.position) {
  977. var a = geometry.attributes.position.array;
  978. var v = new THREE.Vector3;
  979. for ( j = 0; j < a.length / 3; j++ ) {
  980. v.set(a[j * 3], a[j * 3 + 1], a[j * 3 + 2]);
  981. v.applyMatrix4( skin.bindShapeMatrix );
  982. a[j * 3] = v.x;
  983. a[j * 3 + 1] = v.y;
  984. a[j * 3 + 2] = v.z;
  985. }
  986. }
  987. if (threeMesh && dobones) {
  988. material.skinning = true;
  989. threeMesh.boneInverses = [];
  990. var jointsIds = skin.jointsIds;
  991. var joints = [];
  992. var i, len = jointsIds.length;
  993. for (i = 0; i < len; i++) {
  994. var jointId = jointsIds[i];
  995. var nodeForJoint = this.joints[jointId];
  996. var joint = this.resources.getEntry(nodeForJoint).object;
  997. if (joint) {
  998. joint.skin = threeMesh;
  999. joints.push(joint);
  1000. threeMesh.skeleton.bones.push(joint);
  1001. var m = skin.inverseBindMatrices;
  1002. var mat = new THREE.Matrix4(
  1003. m[i * 16 + 0], m[i * 16 + 4], m[i * 16 + 8], m[i * 16 + 12],
  1004. m[i * 16 + 1], m[i * 16 + 5], m[i * 16 + 9], m[i * 16 + 13],
  1005. m[i * 16 + 2], m[i * 16 + 6], m[i * 16 + 10], m[i * 16 + 14],
  1006. m[i * 16 + 3], m[i * 16 + 7], m[i * 16 + 11], m[i * 16 + 15]
  1007. );
  1008. threeMesh.skeleton.boneInverses.push(mat);
  1009. threeMesh.pose();
  1010. } else {
  1011. console.log("WARNING: jointId:"+jointId+" cannot be found in skeleton:"+skeleton);
  1012. }
  1013. }
  1014. }
  1015. if (threeMesh) {
  1016. threeMesh.castShadow = true;
  1017. node.add(threeMesh);
  1018. }
  1019. }, this);
  1020. }
  1021. }
  1022. }, this);
  1023. }
  1024. }
  1025. },
  1026. buildSkins: {
  1027. value: function(node) {
  1028. if (node.instanceSkin)
  1029. this.buildSkin(node);
  1030. var children = node.children;
  1031. if (children) {
  1032. children.forEach( function(child) {
  1033. this.buildSkins(child);
  1034. }, this);
  1035. }
  1036. }
  1037. },
  1038. createMeshAnimations : {
  1039. value : function(root) {
  1040. this.buildSkins(root);
  1041. }
  1042. },
  1043. handleScene: {
  1044. value: function(entryID, description, userInfo) {
  1045. if (!description.nodes) {
  1046. console.log("ERROR: invalid file required nodes property is missing from scene");
  1047. return false;
  1048. }
  1049. description.nodes.forEach( function(nodeUID) {
  1050. this.buildNodeHirerachy(nodeUID, userInfo.rootObj);
  1051. }, this);
  1052. if (this.delegate) {
  1053. this.delegate.loadCompleted(userInfo.callback, userInfo.rootObj);
  1054. }
  1055. return true;
  1056. }
  1057. },
  1058. handleImage: {
  1059. value: function(entryID, description, userInfo) {
  1060. this.resources.setEntry(entryID, null, description);
  1061. return true;
  1062. }
  1063. },
  1064. addNodeAnimationChannel : {
  1065. value : function(name, channel, interp) {
  1066. if (!this.nodeAnimationChannels)
  1067. this.nodeAnimationChannels = {};
  1068. if (!this.nodeAnimationChannels[name]) {
  1069. this.nodeAnimationChannels[name] = [];
  1070. }
  1071. this.nodeAnimationChannels[name].push(interp);
  1072. },
  1073. },
  1074. createAnimations : {
  1075. value : function() {
  1076. for (var name in this.nodeAnimationChannels) {
  1077. var nodeAnimationChannels = this.nodeAnimationChannels[name];
  1078. var i, len = nodeAnimationChannels.length;
  1079. //console.log(" animation channels for node " + name);
  1080. //for (i = 0; i < len; i++) {
  1081. // console.log(nodeAnimationChannels[i]);
  1082. //}
  1083. var anim = new THREE.glTFAnimation(nodeAnimationChannels);
  1084. anim.name = "animation_" + name;
  1085. this.animations.push(anim);
  1086. }
  1087. }
  1088. },
  1089. buildAnimation: {
  1090. value : function(animation) {
  1091. var interps = [];
  1092. var i, len = animation.channels.length;
  1093. for (i = 0; i < len; i++) {
  1094. var channel = animation.channels[i];
  1095. var sampler = animation.samplers[channel.sampler];
  1096. if (sampler) {
  1097. var input = animation.parameters[sampler.input];
  1098. if (input && input.data) {
  1099. var output = animation.parameters[sampler.output];
  1100. if (output && output.data) {
  1101. var target = channel.target;
  1102. var node = this.resources.getEntry(target.id);
  1103. if (node) {
  1104. var path = target.path;
  1105. if (path == "rotation")
  1106. {
  1107. convertAxisAngleToQuaternion(output.data, output.count);
  1108. }
  1109. var interp = {
  1110. keys : input.data,
  1111. values : output.data,
  1112. count : input.count,
  1113. target : node.object,
  1114. path : path,
  1115. type : sampler.interpolation
  1116. };
  1117. this.addNodeAnimationChannel(target.id, channel, interp);
  1118. interps.push(interp);
  1119. }
  1120. }
  1121. }
  1122. }
  1123. }
  1124. }
  1125. },
  1126. handleAnimation: {
  1127. value: function(entryID, description, userInfo) {
  1128. var self = this;
  1129. theLoader.animationsRequested++;
  1130. var animation = new Animation();
  1131. animation.name = entryID;
  1132. animation.onload = function() {
  1133. // self.buildAnimation(animation);
  1134. theLoader.animationsLoaded++;
  1135. theLoader.animations.push(animation);
  1136. theLoader.checkComplete();
  1137. };
  1138. animation.channels = description.channels;
  1139. animation.samplers = description.samplers;
  1140. this.resources.setEntry(entryID, animation, description);
  1141. var parameters = description.parameters;
  1142. if (!parameters) {
  1143. //FIXME: not implemented in delegate
  1144. console.log("MISSING_PARAMETERS for animation:"+ entryID);
  1145. return false;
  1146. }
  1147. // Load parameter buffers
  1148. var params = Object.keys(parameters);
  1149. params.forEach( function(param) {
  1150. animation.totalParameters++;
  1151. var parameter = parameters[param];
  1152. var accessor = this.resources.getEntry(parameter);
  1153. if (!accessor)
  1154. debugger;
  1155. accessor = accessor.object;
  1156. var bufferView = this.resources.getEntry(accessor.bufferView);
  1157. var paramObject = {
  1158. bufferView : bufferView,
  1159. byteOffset : accessor.byteOffset,
  1160. count : accessor.count,
  1161. type : accessor.type,
  1162. id : accessor.bufferView,
  1163. name : param
  1164. };
  1165. var paramContext = new AnimationParameterContext(paramObject, animation);
  1166. var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, animationParameterDelegate, paramContext);
  1167. /*if(alreadyProcessedAttribute) {
  1168. vertexAttributeDelegate.resourceAvailable(alreadyProcessedAttribute, attribContext);
  1169. }*/
  1170. }, this);
  1171. return true;
  1172. }
  1173. },
  1174. handleAccessor: {
  1175. value: function(entryID, description, userInfo) {
  1176. // Save attribute entry
  1177. this.resources.setEntry(entryID, description, description);
  1178. return true;
  1179. }
  1180. },
  1181. handleSkin: {
  1182. value: function(entryID, description, userInfo) {
  1183. // Save skin entry
  1184. var skin = {
  1185. };
  1186. var m = description.bindShapeMatrix;
  1187. skin.bindShapeMatrix = new THREE.Matrix4(
  1188. m[0], m[4], m[8], m[12],
  1189. m[1], m[5], m[9], m[13],
  1190. m[2], m[6], m[10], m[14],
  1191. m[3], m[7], m[11], m[15]
  1192. );
  1193. skin.jointsIds = description.joints;
  1194. var inverseBindMatricesDescription = description.inverseBindMatrices;
  1195. skin.inverseBindMatricesDescription = inverseBindMatricesDescription;
  1196. skin.inverseBindMatricesDescription.id = entryID + "_inverseBindMatrices";
  1197. var bufferEntry = this.resources.getEntry(inverseBindMatricesDescription.bufferView);
  1198. var paramObject = {
  1199. bufferView : bufferEntry,
  1200. byteOffset : inverseBindMatricesDescription.byteOffset,
  1201. count : inverseBindMatricesDescription.count,
  1202. type : inverseBindMatricesDescription.type,
  1203. id : inverseBindMatricesDescription.bufferView,
  1204. name : skin.inverseBindMatricesDescription.id
  1205. };
  1206. var context = new InverseBindMatricesContext(paramObject, skin);
  1207. var alreadyProcessedAttribute = THREE.GLTFLoaderUtils.getBuffer(paramObject, inverseBindMatricesDelegate, context);
  1208. var bufferView = this.resources.getEntry(skin.inverseBindMatricesDescription.bufferView);
  1209. skin.inverseBindMatricesDescription.bufferView =
  1210. bufferView.object;
  1211. this.resources.setEntry(entryID, skin, description);
  1212. return true;
  1213. }
  1214. },
  1215. handleSampler: {
  1216. value: function(entryID, description, userInfo) {
  1217. // Save attribute entry
  1218. this.resources.setEntry(entryID, description, description);
  1219. return true;
  1220. }
  1221. },
  1222. handleTexture: {
  1223. value: function(entryID, description, userInfo) {
  1224. // Save attribute entry
  1225. this.resources.setEntry(entryID, null, description);
  1226. return true;
  1227. }
  1228. },
  1229. handleError: {
  1230. value: function(msg) {
  1231. throw new Error(msg);
  1232. return true;
  1233. }
  1234. },
  1235. _delegate: {
  1236. value: new LoadDelegate,
  1237. writable: true
  1238. },
  1239. delegate: {
  1240. enumerable: true,
  1241. get: function() {
  1242. return this._delegate;
  1243. },
  1244. set: function(value) {
  1245. this._delegate = value;
  1246. }
  1247. }
  1248. });
  1249. // Loader
  1250. var Context = function(rootObj, callback) {
  1251. this.rootObj = rootObj;
  1252. this.callback = callback;
  1253. };
  1254. var rootObj = new THREE.Object3D();
  1255. var self = this;
  1256. var loader = Object.create(ThreeGLTFLoader);
  1257. loader.initWithPath(url);
  1258. loader.load(new Context(rootObj,
  1259. function(obj) {
  1260. }),
  1261. null);
  1262. this.loader = loader;
  1263. this.callback = callback;
  1264. this.rootObj = rootObj;
  1265. return rootObj;
  1266. }
  1267. THREE.glTFLoader.prototype.callLoadedCallback = function() {
  1268. var result = {
  1269. scene : this.rootObj,
  1270. cameras : this.loader.cameras,
  1271. animations : this.loader.animations,
  1272. };
  1273. this.callback(result);
  1274. }
  1275. THREE.glTFLoader.prototype.checkComplete = function() {
  1276. if (this.meshesLoaded == this.meshesRequested
  1277. && this.shadersLoaded == this.shadersRequested
  1278. && this.animationsLoaded == this.animationsRequested)
  1279. {
  1280. for (var i = 0; i < this.pendingMeshes.length; i++) {
  1281. var pending = this.pendingMeshes[i];
  1282. pending.mesh.attachToNode(pending.node);
  1283. }
  1284. for (var i = 0; i < this.animationsLoaded; i++) {
  1285. var animation = this.animations[i];
  1286. this.loader.buildAnimation(animation);
  1287. }
  1288. this.loader.createAnimations();
  1289. this.loader.createMeshAnimations(this.rootObj);
  1290. this.callLoadedCallback();
  1291. }
  1292. }