babylon.glTFFileLoader.js 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. var BABYLON;
  2. (function (BABYLON) {
  3. /**
  4. * Enums
  5. */
  6. (function (EComponentType) {
  7. EComponentType[EComponentType["BYTE"] = 5120] = "BYTE";
  8. EComponentType[EComponentType["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE";
  9. EComponentType[EComponentType["SHORT"] = 5122] = "SHORT";
  10. EComponentType[EComponentType["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT";
  11. EComponentType[EComponentType["FLOAT"] = 5126] = "FLOAT";
  12. })(BABYLON.EComponentType || (BABYLON.EComponentType = {}));
  13. var EComponentType = BABYLON.EComponentType;
  14. (function (EShaderType) {
  15. EShaderType[EShaderType["FRAGMENT"] = 35632] = "FRAGMENT";
  16. EShaderType[EShaderType["VERTEX"] = 35633] = "VERTEX";
  17. })(BABYLON.EShaderType || (BABYLON.EShaderType = {}));
  18. var EShaderType = BABYLON.EShaderType;
  19. (function (EParameterType) {
  20. EParameterType[EParameterType["BYTE"] = 5120] = "BYTE";
  21. EParameterType[EParameterType["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE";
  22. EParameterType[EParameterType["SHORT"] = 5122] = "SHORT";
  23. EParameterType[EParameterType["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT";
  24. EParameterType[EParameterType["INT"] = 5124] = "INT";
  25. EParameterType[EParameterType["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT";
  26. EParameterType[EParameterType["FLOAT"] = 5126] = "FLOAT";
  27. EParameterType[EParameterType["FLOAT_VEC2"] = 35664] = "FLOAT_VEC2";
  28. EParameterType[EParameterType["FLOAT_VEC3"] = 35665] = "FLOAT_VEC3";
  29. EParameterType[EParameterType["FLOAT_VEC4"] = 35666] = "FLOAT_VEC4";
  30. EParameterType[EParameterType["INT_VEC2"] = 35667] = "INT_VEC2";
  31. EParameterType[EParameterType["INT_VEC3"] = 35668] = "INT_VEC3";
  32. EParameterType[EParameterType["INT_VEC4"] = 35669] = "INT_VEC4";
  33. EParameterType[EParameterType["BOOL"] = 35670] = "BOOL";
  34. EParameterType[EParameterType["BOOL_VEC2"] = 35671] = "BOOL_VEC2";
  35. EParameterType[EParameterType["BOOL_VEC3"] = 35672] = "BOOL_VEC3";
  36. EParameterType[EParameterType["BOOL_VEC4"] = 35673] = "BOOL_VEC4";
  37. EParameterType[EParameterType["FLOAT_MAT2"] = 35674] = "FLOAT_MAT2";
  38. EParameterType[EParameterType["FLOAT_MAT3"] = 35675] = "FLOAT_MAT3";
  39. EParameterType[EParameterType["FLOAT_MAT4"] = 35676] = "FLOAT_MAT4";
  40. EParameterType[EParameterType["SAMPLER_2D"] = 35678] = "SAMPLER_2D";
  41. })(BABYLON.EParameterType || (BABYLON.EParameterType = {}));
  42. var EParameterType = BABYLON.EParameterType;
  43. (function (ETextureWrapMode) {
  44. ETextureWrapMode[ETextureWrapMode["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE";
  45. ETextureWrapMode[ETextureWrapMode["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT";
  46. ETextureWrapMode[ETextureWrapMode["REPEAT"] = 10497] = "REPEAT";
  47. })(BABYLON.ETextureWrapMode || (BABYLON.ETextureWrapMode = {}));
  48. var ETextureWrapMode = BABYLON.ETextureWrapMode;
  49. (function (ETextureFilterType) {
  50. ETextureFilterType[ETextureFilterType["NEAREST"] = 9728] = "NEAREST";
  51. ETextureFilterType[ETextureFilterType["LINEAR"] = 9728] = "LINEAR";
  52. ETextureFilterType[ETextureFilterType["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";
  53. ETextureFilterType[ETextureFilterType["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";
  54. ETextureFilterType[ETextureFilterType["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";
  55. ETextureFilterType[ETextureFilterType["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR";
  56. })(BABYLON.ETextureFilterType || (BABYLON.ETextureFilterType = {}));
  57. var ETextureFilterType = BABYLON.ETextureFilterType;
  58. (function (ETextureFormat) {
  59. ETextureFormat[ETextureFormat["ALPHA"] = 6406] = "ALPHA";
  60. ETextureFormat[ETextureFormat["RGB"] = 6407] = "RGB";
  61. ETextureFormat[ETextureFormat["RGBA"] = 6408] = "RGBA";
  62. ETextureFormat[ETextureFormat["LUMINANCE"] = 6409] = "LUMINANCE";
  63. ETextureFormat[ETextureFormat["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA";
  64. })(BABYLON.ETextureFormat || (BABYLON.ETextureFormat = {}));
  65. var ETextureFormat = BABYLON.ETextureFormat;
  66. /**
  67. * Tokenizer. Used for shaders compatibility
  68. * Automatically map world, view, projection, worldViewProjection and attributes
  69. */
  70. var ETokenType;
  71. (function (ETokenType) {
  72. ETokenType[ETokenType["IDENTIFIER"] = 1] = "IDENTIFIER";
  73. ETokenType[ETokenType["UNKNOWN"] = 2] = "UNKNOWN";
  74. ETokenType[ETokenType["END_OF_INPUT"] = 3] = "END_OF_INPUT";
  75. })(ETokenType || (ETokenType = {}));
  76. var Tokenizer = (function () {
  77. function Tokenizer(toParse) {
  78. this._pos = 0;
  79. this.isLetterOrDigitPattern = /^[a-zA-Z0-9]+$/;
  80. this._toParse = toParse;
  81. this._maxPos = toParse.length;
  82. }
  83. Tokenizer.prototype.getNextToken = function () {
  84. if (this.isEnd())
  85. return ETokenType.END_OF_INPUT;
  86. this.currentString = this.read();
  87. this.currentToken = ETokenType.UNKNOWN;
  88. if (this.currentString === "_" || this.isLetterOrDigitPattern.test(this.currentString)) {
  89. this.currentToken = ETokenType.IDENTIFIER;
  90. this.currentIdentifier = this.currentString;
  91. while (!this.isEnd() && (this.isLetterOrDigitPattern.test(this.currentString = this.peek()) || this.currentString === "_")) {
  92. this.currentIdentifier += this.currentString;
  93. this.forward();
  94. }
  95. }
  96. return this.currentToken;
  97. };
  98. Tokenizer.prototype.peek = function () {
  99. return this._toParse[this._pos];
  100. };
  101. Tokenizer.prototype.read = function () {
  102. return this._toParse[this._pos++];
  103. };
  104. Tokenizer.prototype.forward = function () {
  105. this._pos++;
  106. };
  107. Tokenizer.prototype.isEnd = function () {
  108. return this._pos >= this._maxPos;
  109. };
  110. return Tokenizer;
  111. })();
  112. /**
  113. * Values
  114. */
  115. var glTFTransforms = ["MODEL", "VIEW", "PROJECTION", "MODELVIEW", "MODELVIEWPROJECTION", "JOINTMATRIX"];
  116. var babylonTransforms = ["world", "view", "projection", "worldView", "worldViewProjection", "mBones"];
  117. var glTFAnimationPaths = ["translation", "rotation", "scale"];
  118. var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling"];
  119. /**
  120. * Parse
  121. */
  122. var parseBuffers = function (parsedBuffers, gltfRuntime) {
  123. for (var buf in parsedBuffers) {
  124. var parsedBuffer = parsedBuffers[buf];
  125. gltfRuntime.buffers[buf] = parsedBuffer;
  126. gltfRuntime.buffersCount++;
  127. }
  128. };
  129. var parseShaders = function (parsedShaders, gltfRuntime) {
  130. for (var sha in parsedShaders) {
  131. var parsedShader = parsedShaders[sha];
  132. gltfRuntime.shaders[sha] = parsedShader;
  133. gltfRuntime.shaderscount++;
  134. }
  135. };
  136. var parseObject = function (parsedObjects, runtimeProperty, gltfRuntime) {
  137. for (var object in parsedObjects) {
  138. var parsedObject = parsedObjects[object];
  139. gltfRuntime[runtimeProperty][object] = parsedObject;
  140. }
  141. };
  142. /**
  143. * Utils
  144. */
  145. var getByteStrideFromType = function (accessor) {
  146. // Needs this function since "byteStride" isn't requiered in glTF format
  147. var type = accessor.type;
  148. switch (type) {
  149. case "VEC2": return 2;
  150. case "VEC3": return 3;
  151. case "VEC4": return 4;
  152. case "MAT2": return 4;
  153. case "MAT3": return 9;
  154. case "MAT4": return 16;
  155. default: return 1;
  156. }
  157. };
  158. var setMatrix = function (scene, source, parameter, uniformName, shaderMaterial) {
  159. var mat = null;
  160. if (parameter.semantic === "MODEL") {
  161. mat = source.getWorldMatrix();
  162. }
  163. else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") {
  164. mat = BABYLON.Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert());
  165. }
  166. else if (parameter.semantic === "MODELVIEW") {
  167. mat = source.getWorldMatrix().multiply(scene.getViewMatrix());
  168. }
  169. else if (parameter.semantic === "MODELVIEWPROJECTION") {
  170. mat = source.getWorldMatrix().multiply(scene.getTransformMatrix());
  171. }
  172. else if (parameter.semantic === "MODELINVERSE") {
  173. mat = source.getWorldMatrix().invert();
  174. }
  175. else if (parameter.semantic === "VIEWINVERSE") {
  176. mat = scene.getViewMatrix().invert();
  177. }
  178. else if (parameter.semantic === "PROJECTIONINVERSE") {
  179. mat = scene.getProjectionMatrix().invert();
  180. }
  181. else if (parameter.semantic === "MODELVIEWINVERSE") {
  182. mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert();
  183. }
  184. else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") {
  185. mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert();
  186. }
  187. else if (parameter.semantic === "MODELINVERSETRANSPOSE") {
  188. mat = BABYLON.Matrix.Transpose(source.getWorldMatrix().invert());
  189. }
  190. switch (parameter.type) {
  191. case EParameterType.FLOAT_MAT2:
  192. shaderMaterial.setMatrix2x2(uniformName, BABYLON.Matrix.GetAsMatrix2x2(mat));
  193. break;
  194. case EParameterType.FLOAT_MAT3:
  195. shaderMaterial.setMatrix3x3(uniformName, BABYLON.Matrix.GetAsMatrix3x3(mat));
  196. break;
  197. case EParameterType.FLOAT_MAT4:
  198. shaderMaterial.setMatrix(uniformName, mat);
  199. break;
  200. default: break;
  201. }
  202. };
  203. var setUniform = function (shaderMaterial, uniform, value, type) {
  204. switch (type) {
  205. case EParameterType.FLOAT:
  206. shaderMaterial.setFloat(uniform, value);
  207. return true;
  208. case EParameterType.FLOAT_VEC2:
  209. shaderMaterial.setVector2(uniform, BABYLON.Vector2.FromArray(value));
  210. return true;
  211. case EParameterType.FLOAT_VEC3:
  212. shaderMaterial.setVector3(uniform, BABYLON.Vector3.FromArray(value));
  213. return true;
  214. case EParameterType.FLOAT_VEC4:
  215. shaderMaterial.setVector4(uniform, BABYLON.Vector4.FromArray(value));
  216. return true;
  217. default: return false;
  218. }
  219. };
  220. var getWrapMode = function (mode) {
  221. switch (mode) {
  222. case ETextureWrapMode.CLAMP_TO_EDGE: return BABYLON.Texture.CLAMP_ADDRESSMODE;
  223. case ETextureWrapMode.MIRRORED_REPEAT: return BABYLON.Texture.MIRROR_ADDRESSMODE;
  224. case ETextureWrapMode.REPEAT: return BABYLON.Texture.WRAP_ADDRESSMODE;
  225. default: return BABYLON.Texture.WRAP_ADDRESSMODE;
  226. }
  227. };
  228. var getTextureFilterMode = function (mode) {
  229. switch (mode) {
  230. case ETextureFilterType.LINEAR:
  231. case ETextureFilterType.LINEAR_MIPMAP_NEAREST:
  232. case ETextureFilterType.LINEAR_MIPMAP_LINEAR: return BABYLON.Texture.TRILINEAR_SAMPLINGMODE;
  233. case ETextureFilterType.NEAREST:
  234. case ETextureFilterType.NEAREST_MIPMAP_NEAREST: return BABYLON.Texture.NEAREST_SAMPLINGMODE;
  235. default: return BABYLON.Texture.BILINEAR_SAMPLINGMODE;
  236. }
  237. };
  238. var getBufferFromAccessor = function (gltfRuntime, accessor) {
  239. var bufferView = gltfRuntime.bufferViews[accessor.bufferView];
  240. var arrayBuffer = gltfRuntime.arrayBuffers[bufferView.buffer];
  241. var byteOffset = accessor.byteOffset + bufferView.byteOffset;
  242. var count = accessor.count * getByteStrideFromType(accessor);
  243. switch (accessor.componentType) {
  244. case EComponentType.BYTE: return new Int8Array(arrayBuffer, byteOffset, count);
  245. case EComponentType.UNSIGNED_BYTE: return new Uint8Array(arrayBuffer, byteOffset, count);
  246. case EComponentType.SHORT: return new Int16Array(arrayBuffer, byteOffset, count);
  247. case EComponentType.UNSIGNED_SHORT: return new Uint16Array(arrayBuffer, byteOffset, count);
  248. default: return new Float32Array(arrayBuffer, byteOffset, count);
  249. }
  250. };
  251. var normalizeUVs = function (buffer) {
  252. for (var i = 0; i < buffer.length / 2; i++) {
  253. buffer[i * 2 + 1] = 1.0 - buffer[i * 2 + 1];
  254. }
  255. };
  256. var replaceInString = function (str, searchValue, replaceValue) {
  257. while (str.indexOf(searchValue) !== -1) {
  258. str = str.replace(searchValue, replaceValue);
  259. }
  260. return str;
  261. };
  262. var getAttribute = function (attributeParameter) {
  263. if (attributeParameter.semantic === "NORMAL") {
  264. return "normal";
  265. }
  266. else if (attributeParameter.semantic === "POSITION") {
  267. return "position";
  268. }
  269. else if (attributeParameter.semantic === "JOINT") {
  270. return "matricesIndices";
  271. }
  272. else if (attributeParameter.semantic === "WEIGHT") {
  273. return "matricesWeights";
  274. }
  275. else if (attributeParameter.semantic.indexOf("TEXCOORD_") !== -1) {
  276. var channel = Number(attributeParameter.semantic.split("_")[1]);
  277. return "uv" + (channel === 0 ? "" : channel + 1);
  278. }
  279. };
  280. var isBase64 = function (uri) {
  281. return uri.length < 5 ? false : uri.substr(0, 5) === "data:";
  282. };
  283. var textureHasAlpha = function (texture) {
  284. var image = new Image();
  285. image.onload = function (ev) {
  286. var canvas = document.createElement('canvas');
  287. var context = canvas.getContext('2d');
  288. context.drawImage(image, 0, 0);
  289. var data = context.getImageData(0, 0, image.width, image.height).data;
  290. var foundAlpha = false;
  291. for (var i = 0; i < data.length; i += 4) {
  292. if (data[i + 3] === 0) {
  293. texture.hasAlpha = true;
  294. break;
  295. }
  296. }
  297. };
  298. image.src = texture.url;
  299. };
  300. /**
  301. * Load animations
  302. */
  303. var getAnimationPath = function (path) {
  304. var index = glTFAnimationPaths.indexOf(path);
  305. if (index !== -1) {
  306. return babylonAnimationPaths[index];
  307. }
  308. return path;
  309. };
  310. var loadAnimations = function (gltfRuntime) {
  311. for (var anim in gltfRuntime.animations) {
  312. var animation = gltfRuntime.animations[anim];
  313. for (var i = 0; i < animation.channels.length; i++) {
  314. // Get parameters and load buffers
  315. var channel = animation.channels[i];
  316. var sampler = animation.samplers[channel.sampler];
  317. if (!sampler) {
  318. continue;
  319. }
  320. var inputData = animation.parameters[sampler.input];
  321. var outputData = animation.parameters[sampler.output];
  322. var bufferInput = getBufferFromAccessor(gltfRuntime, gltfRuntime.accessors[inputData]);
  323. var bufferOutput = getBufferFromAccessor(gltfRuntime, gltfRuntime.accessors[outputData]);
  324. var targetID = channel.target.id;
  325. var targetNode = gltfRuntime.scene.getNodeByID(targetID);
  326. if (targetNode === null) {
  327. BABYLON.Tools.Warn("Creating animation named " + anim + ". But cannot find node named " + targetID + " to attach to");
  328. continue;
  329. }
  330. var isBone = targetNode instanceof BABYLON.Bone;
  331. // Get target path (position, rotation or scaling)
  332. var targetPath = channel.target.path;
  333. var targetPathIndex = glTFAnimationPaths.indexOf(targetPath);
  334. if (targetPathIndex !== -1) {
  335. targetPath = babylonAnimationPaths[targetPathIndex];
  336. }
  337. // Determine animation type
  338. var animationType = BABYLON.Animation.ANIMATIONTYPE_MATRIX;
  339. if (!isBone) {
  340. if (targetPath === "rotationQuaternion") {
  341. animationType = BABYLON.Animation.ANIMATIONTYPE_QUATERNION;
  342. targetNode.rotationQuaternion = new BABYLON.Quaternion();
  343. }
  344. else {
  345. animationType = BABYLON.Animation.ANIMATIONTYPE_VECTOR3;
  346. }
  347. }
  348. // Create animation and key frames
  349. var babylonAnimation = new BABYLON.Animation(anim, isBone ? "_matrix" : targetPath, 1, animationType, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
  350. var keys = [];
  351. for (var i = 0; i < bufferInput.length; i++) {
  352. var value = null;
  353. if (targetPath === "rotationQuaternion") {
  354. value = BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.FromArray([bufferOutput[i * 4], bufferOutput[i * 4 + 1], bufferOutput[i * 4 + 2]]).normalize(), bufferOutput[i * 4 + 3]);
  355. }
  356. else {
  357. value = BABYLON.Vector3.FromArray([bufferOutput[i * 3], bufferOutput[i * 3 + 1], bufferOutput[i * 3 + 2]]);
  358. }
  359. if (isBone) {
  360. var translation = BABYLON.Vector3.Zero();
  361. var rotationQuaternion = new BABYLON.Quaternion();
  362. var scaling = BABYLON.Vector3.Zero();
  363. var bone = targetNode;
  364. var mat = bone.getLocalMatrix();
  365. mat.decompose(scaling, rotationQuaternion, translation);
  366. if (targetPath === "position") {
  367. translation = value;
  368. }
  369. else if (targetPath === "rotationQuaternion") {
  370. rotationQuaternion = value;
  371. }
  372. else {
  373. scaling = value;
  374. }
  375. if (targetNode instanceof BABYLON.Mesh) {
  376. targetNode.a;
  377. }
  378. value = BABYLON.Matrix.Compose(scaling, rotationQuaternion, translation);
  379. }
  380. keys.push({
  381. frame: bufferInput[i],
  382. value: value
  383. });
  384. }
  385. // Finish
  386. babylonAnimation.setKeys(keys);
  387. targetNode.animations.push(babylonAnimation);
  388. if (!(targetNode instanceof BABYLON.Bone)) {
  389. gltfRuntime.scene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true);
  390. }
  391. }
  392. }
  393. };
  394. /**
  395. * Import skeletons and bones
  396. */
  397. var configureBoneTransformation = function (node) {
  398. var mat = null;
  399. if (node.translation && node.rotation && node.scale) {
  400. mat = BABYLON.Matrix.Compose(BABYLON.Vector3.FromArray(node.scale), BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.FromArray([node.rotation[0], node.rotation[1], node.rotation[2]]).normalize(), node.rotation[3]), BABYLON.Vector3.FromArray(node.translation));
  401. }
  402. else {
  403. mat = BABYLON.Matrix.FromArray(node.matrix);
  404. }
  405. return mat;
  406. };
  407. var getParentBone = function (gltfRuntime, jointName, newSkeleton) {
  408. for (var nde in gltfRuntime.nodes) {
  409. var node = gltfRuntime.nodes[nde];
  410. if (!node || !node.jointName) {
  411. continue;
  412. }
  413. for (var i = 0; i < node.children.length; i++) {
  414. var child = gltfRuntime.nodes[node.children[i]];
  415. if (!child || !node.jointName) {
  416. continue;
  417. }
  418. if (child.jointName === jointName) {
  419. var parent = gltfRuntime.scene.getNodeByID(nde);
  420. if (parent instanceof BABYLON.Bone) {
  421. return parent;
  422. }
  423. return null;
  424. }
  425. }
  426. }
  427. return null;
  428. for (var i = 0; i < newSkeleton.bones.length; i++) {
  429. if (newSkeleton.bones[i].id === jointName) {
  430. return newSkeleton.bones[i];
  431. }
  432. }
  433. return null;
  434. };
  435. var importSkeleton = function (gltfRuntime, skins) {
  436. var newSkeleton = new BABYLON.Skeleton(skins.name, "", gltfRuntime.scene);
  437. // Matrices
  438. var accessor = gltfRuntime.accessors[skins.inverseBindMatrices];
  439. var buffer = getBufferFromAccessor(gltfRuntime, accessor);
  440. // Joints
  441. for (var i = 0; i < skins.jointNames.length; i++) {
  442. var node = gltfRuntime.nodes[skins.jointNames[i]];
  443. if (!node) {
  444. BABYLON.Tools.Warn("Joint named " + skins.jointNames[i] + " does not exist");
  445. continue;
  446. }
  447. // Transform
  448. var mat = configureBoneTransformation(node);
  449. // Parent bone
  450. var boneID = skins.jointNames[i];
  451. var parentBone = getParentBone(gltfRuntime, boneID, newSkeleton);
  452. // Create bone
  453. var bone = new BABYLON.Bone(node.name, newSkeleton, parentBone, mat);
  454. bone.id = boneID;
  455. }
  456. newSkeleton.prepare();
  457. return newSkeleton;
  458. };
  459. /**
  460. * Load geometries and nodes
  461. */
  462. var importMesh = function (gltfRuntime, node, meshes, id, skin) {
  463. var newMesh = new BABYLON.Mesh(node.name, gltfRuntime.scene);
  464. newMesh.id = id;
  465. newMesh.layerMask = 0x0FFFFFFF;
  466. newMesh.subMeshes = [];
  467. var multiMat = new BABYLON.MultiMaterial("multimat" + id, gltfRuntime.scene);
  468. multiMat.backFaceCulling = false;
  469. newMesh.material = multiMat;
  470. var vertexData = new BABYLON.VertexData();
  471. var geometry = new BABYLON.Geometry(id, gltfRuntime.scene, vertexData, true);
  472. var verticesStarts = [];
  473. var verticesCounts = [];
  474. var indexStarts = [];
  475. var indexCounts = [];
  476. for (var meshIndex = 0; meshIndex < meshes.length; meshIndex++) {
  477. var meshID = meshes[meshIndex];
  478. var mesh = gltfRuntime.meshes[meshID];
  479. if (!mesh) {
  480. continue;
  481. }
  482. // Positions, normals and UVs
  483. for (var i = 0; i < mesh.primitives.length; i++) {
  484. // Temporary vertex data
  485. var tempVertexData = new BABYLON.VertexData();
  486. var primitive = mesh.primitives[i];
  487. if (primitive.primitive !== 4) {
  488. continue;
  489. }
  490. var attributes = primitive.attributes;
  491. var accessor = null;
  492. var buffer = null;
  493. // Set positions, normal and uvs
  494. for (var semantic in attributes) {
  495. // Link accessor and buffer view
  496. accessor = gltfRuntime.accessors[attributes[semantic]];
  497. buffer = getBufferFromAccessor(gltfRuntime, accessor);
  498. if (semantic === "NORMAL") {
  499. tempVertexData.set(buffer, BABYLON.VertexBuffer.NormalKind);
  500. }
  501. else if (semantic === "POSITION") {
  502. verticesCounts.push(buffer.length);
  503. tempVertexData.set(buffer, BABYLON.VertexBuffer.PositionKind);
  504. }
  505. else if (semantic.indexOf("TEXCOORD_") !== -1) {
  506. var channel = Number(semantic.split("_")[1]);
  507. var uvKind = BABYLON.VertexBuffer.UVKind + (channel === 0 ? "" : (channel + 1));
  508. normalizeUVs(buffer);
  509. tempVertexData.set(buffer, uvKind);
  510. }
  511. else if (semantic === "JOINT") {
  512. tempVertexData.set(buffer, BABYLON.VertexBuffer.MatricesIndicesKind);
  513. }
  514. else if (semantic === "WEIGHT") {
  515. tempVertexData.set(buffer, BABYLON.VertexBuffer.MatricesWeightsKind);
  516. }
  517. }
  518. // Indices
  519. accessor = gltfRuntime.accessors[primitive.indices];
  520. buffer = getBufferFromAccessor(gltfRuntime, accessor);
  521. tempVertexData.indices = buffer;
  522. indexCounts.push(buffer.length);
  523. vertexData.merge(tempVertexData);
  524. tempVertexData = undefined;
  525. // Sub material
  526. var material = gltfRuntime.scene.getMaterialByID(primitive.material);
  527. multiMat.subMaterials.push(material === null ? gltfRuntime.scene.defaultMaterial : material);
  528. // Update vertices start and index start
  529. verticesStarts.push(verticesStarts.length === 0 ? 0 : verticesStarts[verticesStarts.length - 1] + verticesCounts[verticesCounts.length - 2]);
  530. indexStarts.push(indexStarts.length === 0 ? 0 : indexStarts[indexStarts.length - 1] + indexCounts[indexCounts.length - 2]);
  531. }
  532. }
  533. // Apply geometry
  534. geometry.setAllVerticesData(vertexData);
  535. geometry.applyToMesh(newMesh);
  536. newMesh.flipFaces(true);
  537. // Apply submeshes
  538. newMesh.subMeshes = [];
  539. var index = 0;
  540. for (var meshIndex = 0; meshIndex < meshes.length; meshIndex++) {
  541. var meshID = meshes[meshIndex];
  542. var mesh = gltfRuntime.meshes[meshID];
  543. if (!mesh) {
  544. continue;
  545. }
  546. for (var i = 0; i < mesh.primitives.length; i++) {
  547. if (mesh.primitives[i].primitive !== 4) {
  548. continue;
  549. }
  550. var subMesh = BABYLON.SubMesh.CreateFromIndices(index, indexStarts[index], indexCounts[index], newMesh, newMesh);
  551. index++;
  552. }
  553. }
  554. // Finish
  555. return newMesh;
  556. };
  557. var configureNode = function (newNode, position, rotation, scaling) {
  558. if (newNode.position) {
  559. newNode.position = position;
  560. }
  561. if (newNode.rotationQuaternion || newNode.rotation) {
  562. newNode.rotationQuaternion = rotation;
  563. }
  564. if (newNode.scaling) {
  565. newNode.scaling = scaling;
  566. }
  567. };
  568. var configureNodeFromMatrix = function (newNode, node) {
  569. if (node.matrix) {
  570. var position = new BABYLON.Vector3(0, 0, 0);
  571. var rotation = new BABYLON.Quaternion();
  572. var scaling = new BABYLON.Vector3(0, 0, 0);
  573. var mat = BABYLON.Matrix.FromArray(node.matrix);
  574. mat.decompose(scaling, rotation, position);
  575. configureNode(newNode, position, rotation, scaling);
  576. if (newNode instanceof BABYLON.TargetCamera) {
  577. newNode.setTarget(BABYLON.Vector3.Zero());
  578. }
  579. }
  580. else {
  581. configureNode(newNode, BABYLON.Vector3.FromArray(node.translation), BABYLON.Quaternion.RotationAxis(BABYLON.Vector3.FromArray(node.rotation).normalize(), node.rotation[3]), BABYLON.Vector3.FromArray(node.scale));
  582. }
  583. };
  584. var importNode = function (gltfRuntime, node, id) {
  585. var lastNode = null;
  586. // Meshes
  587. if (node.instanceSkin) {
  588. var instanceSkin = node.instanceSkin;
  589. if (instanceSkin.meshes) {
  590. var skin = gltfRuntime.skins[instanceSkin.skin];
  591. var newMesh = importMesh(gltfRuntime, node, instanceSkin.meshes, id, skin);
  592. newMesh.skeleton = gltfRuntime.scene.getLastSkeletonByID(instanceSkin.skin);
  593. if (newMesh.skeleton === null) {
  594. newMesh.skeleton = importSkeleton(gltfRuntime, gltfRuntime.skins[instanceSkin.skin]);
  595. }
  596. if (newMesh.skeleton !== null) {
  597. newMesh.useBones = true;
  598. newMesh.applySkeleton(newMesh.skeleton);
  599. }
  600. lastNode = newMesh;
  601. }
  602. }
  603. else if (node.meshes) {
  604. /**
  605. * Improve meshes property
  606. */
  607. var newMesh = importMesh(gltfRuntime, node, node.mesh ? [node.mesh] : node.meshes, id);
  608. lastNode = newMesh;
  609. }
  610. else if (node.light) {
  611. var light = gltfRuntime.lights[node.light];
  612. if (light) {
  613. if (light.type === "ambient") {
  614. var ambienLight = light[light.type];
  615. var hemiLight = new BABYLON.HemisphericLight(node.light, BABYLON.Vector3.Zero(), gltfRuntime.scene);
  616. hemiLight.name = node.name;
  617. if (ambienLight.color) {
  618. hemiLight.diffuse = BABYLON.Color3.FromArray(ambienLight.color);
  619. }
  620. lastNode = hemiLight;
  621. }
  622. else if (light.type === "directional") {
  623. var directionalLight = light[light.type];
  624. var dirLight = new BABYLON.DirectionalLight(node.light, BABYLON.Vector3.Zero(), gltfRuntime.scene);
  625. dirLight.name = node.name;
  626. if (directionalLight.color) {
  627. dirLight.diffuse = BABYLON.Color3.FromArray(directionalLight.color);
  628. }
  629. lastNode = dirLight;
  630. }
  631. else if (light.type === "point") {
  632. var pointLight = light[light.type];
  633. var ptLight = new BABYLON.PointLight(node.light, BABYLON.Vector3.Zero(), gltfRuntime.scene);
  634. ptLight.name = node.name;
  635. if (pointLight.color) {
  636. ptLight.diffuse = BABYLON.Color3.FromArray(pointLight.color);
  637. }
  638. lastNode = ptLight;
  639. }
  640. else if (light.type === "spot") {
  641. var spotLight = light[light.type];
  642. var spLight = new BABYLON.SpotLight(node.light, BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero(), 0, 0, gltfRuntime.scene);
  643. spLight.name = node.name;
  644. if (spotLight.color) {
  645. spLight.diffuse = BABYLON.Color3.FromArray(spotLight.color);
  646. }
  647. if (spotLight.fallOfAngle) {
  648. spLight.angle = spotLight.fallOfAngle;
  649. }
  650. if (spotLight.fallOffExponent) {
  651. spLight.exponent = spotLight.fallOffExponent;
  652. }
  653. lastNode = spLight;
  654. }
  655. }
  656. }
  657. else if (node.camera) {
  658. var camera = gltfRuntime.cameras[node.camera];
  659. if (camera) {
  660. if (camera.type === "orthographic") {
  661. var orthographicCamera = camera[camera.type];
  662. var orthoCamera = new BABYLON.FreeCamera(node.camera, BABYLON.Vector3.Zero(), gltfRuntime.scene);
  663. orthoCamera.name = node.name;
  664. orthoCamera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
  665. orthoCamera.attachControl(gltfRuntime.scene.getEngine().getRenderingCanvas());
  666. lastNode = orthoCamera;
  667. }
  668. else if (camera.type === "perspective") {
  669. var perspectiveCamera = camera[camera.type];
  670. var persCamera = new BABYLON.FreeCamera(node.camera, BABYLON.Vector3.Zero(), gltfRuntime.scene);
  671. persCamera.name = node.name;
  672. persCamera.attachControl(gltfRuntime.scene.getEngine().getRenderingCanvas());
  673. if (!perspectiveCamera.aspectRatio) {
  674. perspectiveCamera.aspectRatio = gltfRuntime.scene.getEngine().getRenderWidth() / gltfRuntime.scene.getEngine().getRenderHeight();
  675. }
  676. if (perspectiveCamera.znear && perspectiveCamera.zfar) {
  677. persCamera.maxZ = perspectiveCamera.zfar;
  678. persCamera.minZ = perspectiveCamera.znear;
  679. }
  680. lastNode = persCamera;
  681. }
  682. }
  683. }
  684. // Empty node
  685. if (lastNode === null && !node.jointName) {
  686. var dummy = new BABYLON.Mesh(node.name, gltfRuntime.scene);
  687. lastNode = dummy;
  688. }
  689. if (lastNode !== null) {
  690. if (node.matrix) {
  691. configureNodeFromMatrix(lastNode, node);
  692. }
  693. else {
  694. configureNode(lastNode, BABYLON.Vector3.FromArray(node.translation), BABYLON.Quaternion.FromArray(node.rotation), BABYLON.Vector3.FromArray(node.scale));
  695. }
  696. lastNode.updateCache(true);
  697. }
  698. return lastNode;
  699. };
  700. /**
  701. * Load buffers
  702. */
  703. var onBuffersLoaded = function (gltfRuntime) {
  704. // Nodes
  705. var parsedNodes = gltfRuntime.nodes;
  706. var currentScene = gltfRuntime.currentScene;
  707. for (var nde in parsedNodes) {
  708. var node = parsedNodes[nde];
  709. var newNode = importNode(gltfRuntime, node, nde);
  710. if (newNode !== null) {
  711. newNode.id = nde;
  712. }
  713. }
  714. // Resolve parenting once all nodes were created
  715. for (var nde in parsedNodes) {
  716. var node = parsedNodes[nde];
  717. var parent = gltfRuntime.scene.getNodeByID(nde);
  718. if (node.children && parent !== null) {
  719. for (var i = 0; i < node.children.length; i++) {
  720. var child = gltfRuntime.nodes[node.children[i]];
  721. var childNode = gltfRuntime.scene.getNodeByID(node.children[i]);
  722. if (childNode !== null) {
  723. childNode.parent = parent;
  724. }
  725. else {
  726. BABYLON.Tools.Warn("Node named " + node.name + " as a children named " + node.children[i] + " but does not exists");
  727. }
  728. }
  729. }
  730. }
  731. // Set animations
  732. loadAnimations(gltfRuntime);
  733. };
  734. var onLoadBuffer = function (gltfRuntime, buf) {
  735. return function (data) {
  736. gltfRuntime.loadedBuffers++;
  737. if (!(data instanceof ArrayBuffer)) {
  738. BABYLON.Tools.Error("Buffer named " + buf + " is not an array buffer");
  739. }
  740. else if (data.byteLength != gltfRuntime.buffers[buf].byteLength) {
  741. BABYLON.Tools.Error("Buffer named " + buf + " is length " + data.byteLength + ". Expected: " + gltfRuntime.buffers[buf].byteLength); // Improve error message
  742. }
  743. gltfRuntime.arrayBuffers[buf] = data;
  744. if (gltfRuntime.loadedBuffers === gltfRuntime.buffersCount) {
  745. onBuffersLoaded(gltfRuntime);
  746. }
  747. };
  748. };
  749. var onLoadBufferError = function (gltfRuntime, buf) {
  750. return function () {
  751. BABYLON.Tools.Error("Error when loading buffer named " + buf + " located at " + gltfRuntime.buffers[buf].uri);
  752. };
  753. };
  754. var decodeArrayBuffer = function (base64) {
  755. var decodedString = atob(base64);
  756. var bufferLength = decodedString.length;
  757. var arraybuffer = new Uint8Array(new ArrayBuffer(bufferLength));
  758. for (var i = 0; i < bufferLength; i++) {
  759. arraybuffer[i] = decodedString.charCodeAt(i);
  760. }
  761. return arraybuffer.buffer;
  762. };
  763. var loadBuffers = function (gltfRuntime) {
  764. for (var buf in gltfRuntime.buffers) {
  765. var buffer = gltfRuntime.buffers[buf];
  766. if (buffer) {
  767. if (isBase64(buffer.uri)) {
  768. var arrayBuffer = decodeArrayBuffer(buffer.uri.split(",")[1]);
  769. onLoadBuffer(gltfRuntime, buf)(arrayBuffer);
  770. }
  771. else {
  772. BABYLON.Tools.LoadFile(gltfRuntime.rootUrl + buffer.uri, onLoadBuffer(gltfRuntime, buf), null, null, true, onLoadBufferError(gltfRuntime, buf));
  773. }
  774. }
  775. else {
  776. BABYLON.Tools.Error("No buffer named : " + buf);
  777. }
  778. }
  779. };
  780. /**
  781. * Load shaders
  782. */
  783. var onBindShaderMaterial = function (mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, pass, material) {
  784. for (var unif in unTreatedUniforms) {
  785. var uniform = unTreatedUniforms[unif];
  786. var type = uniform.type;
  787. if (type === EParameterType.FLOAT_MAT2 || type === EParameterType.FLOAT_MAT3 || type === EParameterType.FLOAT_MAT4) {
  788. if (uniform.semantic && !uniform.source && !uniform.node) {
  789. setMatrix(gltfRuntime.scene, mesh, uniform, unif, shaderMaterial.getEffect());
  790. }
  791. else if (uniform.semantic && (uniform.source || uniform.node)) {
  792. var source = gltfRuntime.scene.getNodeByName(uniform.source || uniform.node);
  793. if (source === null) {
  794. source = gltfRuntime.scene.getNodeByID(uniform.source || uniform.node);
  795. }
  796. if (source === null) {
  797. continue;
  798. }
  799. setMatrix(gltfRuntime.scene, source, uniform, unif, shaderMaterial.getEffect());
  800. }
  801. }
  802. else {
  803. var value = material.instanceTechnique.values[pass.instanceProgram.uniforms[unif]];
  804. if (!value) {
  805. continue;
  806. }
  807. if (type === EParameterType.SAMPLER_2D) {
  808. var texture = gltfRuntime.textures[value].babylonTexture;
  809. if (texture === null) {
  810. continue;
  811. }
  812. shaderMaterial.getEffect().setTexture(unif, texture);
  813. }
  814. else {
  815. setUniform(shaderMaterial.getEffect(), unif, value, type);
  816. }
  817. }
  818. }
  819. };
  820. var prepareShaderMaterialUniforms = function (gltfRuntime, shaderMaterial, pass, material, unTreatedUniforms) {
  821. var materialValues = material.instanceTechnique.values;
  822. var instanceProgramUniforms = pass.instanceProgram.uniforms;
  823. /**
  824. * Prepare values here (not matrices)
  825. */
  826. for (var unif in unTreatedUniforms) {
  827. var uniform = unTreatedUniforms[unif];
  828. var type = uniform.type;
  829. var value = materialValues[instanceProgramUniforms[unif]] || uniform.value;
  830. if (!value) {
  831. continue;
  832. }
  833. // Texture (sampler2D)
  834. if (type === EParameterType.SAMPLER_2D) {
  835. var texture = gltfRuntime.textures[value];
  836. var sampler = gltfRuntime.samplers[texture.sampler];
  837. if (!texture || !texture.source) {
  838. continue;
  839. }
  840. var source = gltfRuntime.images[texture.source];
  841. var newTexture = null;
  842. if (isBase64(source.uri)) {
  843. newTexture = new BABYLON.Texture(source.uri, gltfRuntime.scene, true, undefined, undefined, undefined, undefined, source.uri, true);
  844. }
  845. else {
  846. newTexture = new BABYLON.Texture(gltfRuntime.rootUrl + source.uri, gltfRuntime.scene, true);
  847. }
  848. newTexture.name = value;
  849. textureHasAlpha(newTexture);
  850. texture.babylonTexture = newTexture;
  851. if (texture.internalFormat && (texture.internalFormat === ETextureFormat.ALPHA || texture.internalFormat === ETextureFormat.RGBA)) {
  852. newTexture.hasAlpha = true;
  853. }
  854. if (uniform.value) {
  855. // Static uniform
  856. shaderMaterial.setTexture(unif, newTexture);
  857. delete unTreatedUniforms[unif];
  858. }
  859. }
  860. else {
  861. if (uniform.value && setUniform(shaderMaterial, unif, value, type)) {
  862. // Static uniform
  863. delete unTreatedUniforms[unif];
  864. }
  865. }
  866. }
  867. };
  868. var onShaderCompileError = function (program, shaderMaterial) {
  869. return function (effect, error) {
  870. BABYLON.Tools.Error("Cannot compile program named " + program.name + ". Error: " + error + ". Default material will be applied");
  871. shaderMaterial.dispose(true);
  872. };
  873. };
  874. var onShaderCompileSuccess = function (gltfRuntime, shaderMaterial, pass, material, unTreatedUniforms) {
  875. return function (_) {
  876. prepareShaderMaterialUniforms(gltfRuntime, shaderMaterial, pass, material, unTreatedUniforms);
  877. shaderMaterial.onBind = function (mat, mesh) {
  878. onBindShaderMaterial(mesh, gltfRuntime, unTreatedUniforms, shaderMaterial, pass, material);
  879. };
  880. };
  881. };
  882. var parseShaderUniforms = function (tokenizer, instanceProgram, technique, unTreatedUniforms) {
  883. for (var unif in instanceProgram.uniforms) {
  884. var uniform = instanceProgram.uniforms[unif];
  885. var uniformParameter = technique.parameters[uniform];
  886. if (tokenizer.currentIdentifier === unif) {
  887. if (uniformParameter.semantic && !uniformParameter.source && !uniformParameter.node) {
  888. var transformIndex = glTFTransforms.indexOf(uniformParameter.semantic);
  889. if (transformIndex !== -1) {
  890. delete unTreatedUniforms[unif];
  891. return babylonTransforms[transformIndex];
  892. }
  893. }
  894. }
  895. }
  896. return tokenizer.currentIdentifier;
  897. };
  898. var onShadersLoaded = function (gltfRuntime) {
  899. // Create materials
  900. for (var mat in gltfRuntime.materials) {
  901. var material = gltfRuntime.materials[mat];
  902. var instanceTechnique = material.instanceTechnique;
  903. var technique = gltfRuntime.techniques[instanceTechnique.technique];
  904. var pass = technique.passes[technique.pass];
  905. var instanceProgram = pass.instanceProgram;
  906. var program = gltfRuntime.programs[instanceProgram.program];
  907. var states = pass.states;
  908. var vertexShader = BABYLON.Effect.ShadersStore[program.vertexShader + "VertexShader"];
  909. var pixelShader = BABYLON.Effect.ShadersStore[program.fragmentShader + "PixelShader"];
  910. var newVertexShader = "";
  911. var newPixelShader = "";
  912. var vertexTokenizer = new Tokenizer(vertexShader);
  913. var pixelTokenizer = new Tokenizer(pixelShader);
  914. var unTreatedUniforms = {};
  915. var uniforms = [];
  916. var attributes = [];
  917. var samplers = [];
  918. // Fill uniform, sampler2D and attributes
  919. for (var unif in instanceProgram.uniforms) {
  920. var uniform = instanceProgram.uniforms[unif];
  921. var uniformParameter = technique.parameters[uniform];
  922. unTreatedUniforms[unif] = uniformParameter;
  923. if (uniformParameter.semantic && !uniformParameter.node && !uniformParameter.source) {
  924. var transformIndex = glTFTransforms.indexOf(uniformParameter.semantic);
  925. if (transformIndex !== -1) {
  926. uniforms.push(babylonTransforms[transformIndex]);
  927. }
  928. else {
  929. uniforms.push(unif);
  930. }
  931. }
  932. else if (uniformParameter.type === EParameterType.SAMPLER_2D) {
  933. samplers.push(unif);
  934. }
  935. else {
  936. uniforms.push(unif);
  937. }
  938. }
  939. for (var attr in instanceProgram.attributes) {
  940. var attribute = instanceProgram.attributes[attr];
  941. var attributeParameter = technique.parameters[attribute];
  942. if (attributeParameter.semantic) {
  943. attributes.push(getAttribute(attributeParameter));
  944. }
  945. }
  946. // Configure vertex shader
  947. while (!vertexTokenizer.isEnd() && vertexTokenizer.getNextToken()) {
  948. var tokenType = vertexTokenizer.currentToken;
  949. if (tokenType !== ETokenType.IDENTIFIER) {
  950. newVertexShader += vertexTokenizer.currentString;
  951. continue;
  952. }
  953. var foundAttribute = false;
  954. for (var attr in instanceProgram.attributes) {
  955. var attribute = instanceProgram.attributes[attr];
  956. var attributeParameter = technique.parameters[attribute];
  957. if (vertexTokenizer.currentIdentifier === attr && attributeParameter.semantic) {
  958. newVertexShader += getAttribute(attributeParameter);
  959. foundAttribute = true;
  960. break;
  961. }
  962. }
  963. if (foundAttribute) {
  964. continue;
  965. }
  966. newVertexShader += parseShaderUniforms(vertexTokenizer, instanceProgram, technique, unTreatedUniforms);
  967. }
  968. // Configure pixel shader
  969. while (!pixelTokenizer.isEnd() && pixelTokenizer.getNextToken()) {
  970. var tokenType = pixelTokenizer.currentToken;
  971. if (tokenType !== ETokenType.IDENTIFIER) {
  972. newPixelShader += pixelTokenizer.currentString;
  973. continue;
  974. }
  975. newPixelShader += parseShaderUniforms(pixelTokenizer, instanceProgram, technique, unTreatedUniforms);
  976. }
  977. // Create shader material
  978. var shaderPath = {
  979. vertex: program.vertexShader,
  980. fragment: program.fragmentShader
  981. };
  982. var options = {
  983. attributes: attributes,
  984. uniforms: uniforms,
  985. samplers: samplers,
  986. needAlphaBlending: states.functions && states.functions.blendEquationSeparate
  987. };
  988. BABYLON.Effect.ShadersStore[program.vertexShader + "VertexShader"] = newVertexShader;
  989. BABYLON.Effect.ShadersStore[program.fragmentShader + "PixelShader"] = newPixelShader;
  990. var shaderMaterial = new BABYLON.ShaderMaterial(material.name, gltfRuntime.scene, shaderPath, options);
  991. shaderMaterial.id = mat;
  992. shaderMaterial.onError = onShaderCompileError(program, shaderMaterial);
  993. shaderMaterial.onCompiled = onShaderCompileSuccess(gltfRuntime, shaderMaterial, pass, material, unTreatedUniforms);
  994. }
  995. // Finish
  996. loadBuffers(gltfRuntime);
  997. };
  998. var onLoadShader = function (gltfRuntime, sha) {
  999. return function (data) {
  1000. gltfRuntime.loadedShaders++;
  1001. BABYLON.Effect.ShadersStore[sha + (gltfRuntime.shaders[sha].type === EShaderType.VERTEX ? "VertexShader" : "PixelShader")] = data;
  1002. if (gltfRuntime.loadedShaders === gltfRuntime.shaderscount) {
  1003. onShadersLoaded(gltfRuntime);
  1004. }
  1005. };
  1006. };
  1007. var onLoadShaderError = function (gltfRuntime, sha) {
  1008. return function () {
  1009. BABYLON.Tools.Error("Error when loading shader program named " + sha + " located at " + gltfRuntime.shaders[sha].uri);
  1010. };
  1011. };
  1012. var load = function (gltfRuntime) {
  1013. // Begin with shaders
  1014. for (var sha in gltfRuntime.shaders) {
  1015. var shader = gltfRuntime.shaders[sha];
  1016. if (shader) {
  1017. if (isBase64(shader.uri)) {
  1018. var shaderString = atob(shader.uri.split(",")[1]);
  1019. onLoadShader(gltfRuntime, sha)(shaderString);
  1020. }
  1021. else {
  1022. BABYLON.Tools.LoadFile(gltfRuntime.rootUrl + shader.uri, onLoadShader(gltfRuntime, sha), null, null, false, onLoadShaderError(gltfRuntime, sha));
  1023. }
  1024. }
  1025. else {
  1026. BABYLON.Tools.Error("No shader file named " + shader.uri);
  1027. }
  1028. }
  1029. };
  1030. /**
  1031. * glTF File Loader Plugin
  1032. */
  1033. var GLTFFileLoader = (function () {
  1034. function GLTFFileLoader() {
  1035. /**
  1036. * Public members
  1037. */
  1038. this.extensions = ".gltf";
  1039. }
  1040. /**
  1041. * Private members
  1042. */
  1043. // None
  1044. /**
  1045. * Import meshes
  1046. */
  1047. GLTFFileLoader.prototype.importMesh = function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons) {
  1048. return true;
  1049. };
  1050. /**
  1051. * Load scene
  1052. */
  1053. GLTFFileLoader.prototype.load = function (scene, data, rootUrl) {
  1054. var parsedData = JSON.parse(data);
  1055. var gltfRuntime = {
  1056. accessors: {},
  1057. buffers: {},
  1058. bufferViews: {},
  1059. meshes: {},
  1060. lights: {},
  1061. cameras: {},
  1062. nodes: {},
  1063. images: {},
  1064. textures: {},
  1065. shaders: {},
  1066. programs: {},
  1067. samplers: {},
  1068. techniques: {},
  1069. materials: {},
  1070. animations: {},
  1071. skins: {},
  1072. currentScene: {},
  1073. buffersCount: 0,
  1074. shaderscount: 0,
  1075. scene: scene,
  1076. dummyNodes: [],
  1077. loadedBuffers: 0,
  1078. loadedShaders: 0,
  1079. rootUrl: rootUrl,
  1080. arrayBuffers: []
  1081. };
  1082. // Parse
  1083. if (parsedData.buffers) {
  1084. parseBuffers(parsedData.buffers, gltfRuntime);
  1085. }
  1086. if (parsedData.bufferViews) {
  1087. parseObject(parsedData.bufferViews, "bufferViews", gltfRuntime);
  1088. }
  1089. if (parsedData.accessors) {
  1090. parseObject(parsedData.accessors, "accessors", gltfRuntime);
  1091. }
  1092. if (parsedData.meshes) {
  1093. parseObject(parsedData.meshes, "meshes", gltfRuntime);
  1094. }
  1095. if (parsedData.lights) {
  1096. parseObject(parsedData.lights, "lights", gltfRuntime);
  1097. }
  1098. if (parsedData.cameras) {
  1099. parseObject(parsedData.cameras, "cameras", gltfRuntime);
  1100. }
  1101. if (parsedData.nodes) {
  1102. parseObject(parsedData.nodes, "nodes", gltfRuntime);
  1103. }
  1104. if (parsedData.images) {
  1105. parseObject(parsedData.images, "images", gltfRuntime);
  1106. }
  1107. if (parsedData.textures) {
  1108. parseObject(parsedData.textures, "textures", gltfRuntime);
  1109. }
  1110. if (parsedData.shaders) {
  1111. parseShaders(parsedData.shaders, gltfRuntime);
  1112. }
  1113. if (parsedData.programs) {
  1114. parseObject(parsedData.programs, "programs", gltfRuntime);
  1115. }
  1116. if (parsedData.samplers) {
  1117. parseObject(parsedData.samplers, "samplers", gltfRuntime);
  1118. }
  1119. if (parsedData.techniques) {
  1120. parseObject(parsedData.techniques, "techniques", gltfRuntime);
  1121. }
  1122. if (parsedData.materials) {
  1123. parseObject(parsedData.materials, "materials", gltfRuntime);
  1124. }
  1125. if (parsedData.animations) {
  1126. parseObject(parsedData.animations, "animations", gltfRuntime);
  1127. }
  1128. if (parsedData.skins) {
  1129. parseObject(parsedData.skins, "skins", gltfRuntime);
  1130. }
  1131. if (parsedData.scene && parsedData.scenes) {
  1132. gltfRuntime.currentScene = parsedData.scenes[parsedData.scene];
  1133. }
  1134. // Load shaders and buffers
  1135. load(gltfRuntime);
  1136. // Test on bones
  1137. for (var i = 0; i < scene.meshes.length; i++) {
  1138. var mesh = scene.meshes[i];
  1139. if (mesh.skeleton) {
  1140. scene.beginAnimation(mesh.skeleton, 0, 20, true, 0.5, function () {
  1141. console.log("finished");
  1142. });
  1143. }
  1144. }
  1145. // Finish
  1146. return true;
  1147. };
  1148. return GLTFFileLoader;
  1149. })();
  1150. BABYLON.GLTFFileLoader = GLTFFileLoader;
  1151. ;
  1152. BABYLON.SceneLoader.RegisterPlugin(new GLTFFileLoader());
  1153. })(BABYLON || (BABYLON = {}));
  1154. //# sourceMappingURL=babylon.glTFFileLoader.js.map