laya.gltf.js 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  1. (function (exports, Laya) {
  2. 'use strict';
  3. class glTFBase64Tool {
  4. constructor() {
  5. }
  6. static init() {
  7. if (glTFBase64Tool.lookup)
  8. return;
  9. glTFBase64Tool.lookup = new Uint8Array(256);
  10. for (var i = 0; i < glTFBase64Tool.chars.length; i++) {
  11. glTFBase64Tool.lookup[glTFBase64Tool.chars.charCodeAt(i)] = i;
  12. }
  13. }
  14. static isBase64String(str) {
  15. return glTFBase64Tool.reg.test(str);
  16. }
  17. static encode(arraybuffer) {
  18. var bytes = new Uint8Array(arraybuffer), i, len = bytes["length"], base64 = "";
  19. for (i = 0; i < len; i += 3) {
  20. base64 += glTFBase64Tool.chars[bytes[i] >> 2];
  21. base64 += glTFBase64Tool.chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
  22. base64 += glTFBase64Tool.chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
  23. base64 += glTFBase64Tool.chars[bytes[i + 2] & 63];
  24. }
  25. if ((len % 3) === 2) {
  26. base64 = base64.substring(0, base64.length - 1) + "=";
  27. }
  28. else if (len % 3 === 1) {
  29. base64 = base64.substring(0, base64.length - 2) + "==";
  30. }
  31. return base64;
  32. }
  33. static decode(base64) {
  34. glTFBase64Tool.init();
  35. var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
  36. if (base64[base64.length - 1] === "=") {
  37. bufferLength--;
  38. if (base64[base64.length - 2] === "=") {
  39. bufferLength--;
  40. }
  41. }
  42. var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
  43. for (i = 0; i < len; i += 4) {
  44. encoded1 = glTFBase64Tool.lookup[base64.charCodeAt(i)];
  45. encoded2 = glTFBase64Tool.lookup[base64.charCodeAt(i + 1)];
  46. encoded3 = glTFBase64Tool.lookup[base64.charCodeAt(i + 2)];
  47. encoded4 = glTFBase64Tool.lookup[base64.charCodeAt(i + 3)];
  48. bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
  49. bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
  50. bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
  51. }
  52. return arraybuffer;
  53. }
  54. ;
  55. }
  56. glTFBase64Tool.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  57. glTFBase64Tool.reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
  58. glTFBase64Tool.reghead = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,/i;
  59. glTFBase64Tool.lookup = null;
  60. class PrimitiveSubMesh {
  61. constructor() {
  62. }
  63. }
  64. class ClipNode {
  65. constructor() {
  66. }
  67. }
  68. class glTFUtils {
  69. static _parse(glTFData, propertyParams = null, constructParams = null) {
  70. glTFUtils._initData(glTFData);
  71. if (!glTFUtils._checkglTFVersion(this._glTF.asset)) {
  72. console.warn("glTF version wrong!");
  73. return new Laya.Sprite3D();
  74. }
  75. glTFUtils._initBufferData(glTFData.buffers);
  76. glTFUtils._initTextureData(glTFData.images);
  77. glTFUtils._loadMaterials(glTFData.materials);
  78. glTFUtils._loadNodes(glTFData.nodes);
  79. glTFUtils.buildHierarchy(glTFData.nodes);
  80. glTFUtils._loadScenes(glTFData.scenes);
  81. glTFUtils._loadAnimations(glTFData.animations);
  82. let defaultSceneIndex = (glTFData.scene != undefined) ? glTFData.scene : 0;
  83. let defaultScene = glTFUtils._glTFScenes[defaultSceneIndex];
  84. glTFUtils._clearData();
  85. return defaultScene;
  86. }
  87. static _initData(glTFData) {
  88. glTFUtils._glTF = glTFData;
  89. (glTFData.buffers) && (glTFUtils._glTFBuffers.length = glTFData.buffers.length);
  90. (glTFData.textures) && (glTFUtils._glTFTextures.length = glTFData.textures.length);
  91. (glTFData.materials) && (glTFUtils._glTFMaterials.length = glTFData.materials.length);
  92. (glTFData.nodes) && (glTFUtils._glTFNodes.length = glTFData.nodes.length);
  93. (glTFData.scenes) && (glTFUtils._glTFScenes.length = glTFData.scenes.length);
  94. }
  95. static _clearData() {
  96. glTFUtils._glTF = null;
  97. glTFUtils._glTFBuffers.length = 0;
  98. glTFUtils._glTFTextures.length = 0;
  99. glTFUtils._glTFMaterials.length = 0;
  100. glTFUtils._glTFNodes.length = 0;
  101. glTFUtils._glTFScenes.length = 0;
  102. glTFUtils.NAMEID = 0;
  103. }
  104. static _checkglTFVersion(asset) {
  105. if (asset.version !== "2.0") {
  106. return false;
  107. }
  108. return true;
  109. }
  110. static RegisterExtra(context, extraName, handler) {
  111. let extra = glTFUtils.Extras[context] || (glTFUtils.Extras[context] = {});
  112. extra[extraName] = handler;
  113. }
  114. static UnRegisterExtra(context, extraName, recoverHandler = true) {
  115. let extra = glTFUtils.Extras[context] || (glTFUtils.Extras[context] = {});
  116. if (recoverHandler) {
  117. let extraHandler = extra[extraName];
  118. extraHandler && extraHandler.recover();
  119. }
  120. delete extra[extraName];
  121. }
  122. static ExecuteExtras(context, glTFExtra, createHandler, params) {
  123. let contextExtra = glTFUtils.Extras[context];
  124. let extraRes = null;
  125. if (contextExtra) {
  126. for (const key in glTFExtra) {
  127. let extraHandler = contextExtra[key];
  128. extraRes = extraHandler ? extraHandler.runWith([...params, createHandler]) : extraRes;
  129. }
  130. }
  131. extraRes = extraRes || createHandler.runWith(params);
  132. createHandler.recover();
  133. return extraRes;
  134. }
  135. static getNodeRandomName(context) {
  136. return `${context}_${glTFUtils.NAMEID++}`;
  137. }
  138. static _initBufferData(buffers) {
  139. if (!buffers)
  140. return;
  141. buffers.forEach((buffer, index) => {
  142. glTFUtils._glTFBuffers[index] = Laya.Loader.getRes(buffer.uri);
  143. });
  144. }
  145. static getAccessorComponentsNum(type) {
  146. switch (type) {
  147. case "SCALAR": return 1;
  148. case "VEC2": return 2;
  149. case "VEC3": return 3;
  150. case "VEC4": return 4;
  151. case "MAT2": return 4;
  152. case "MAT3": return 9;
  153. case "MAT4": return 16;
  154. default: return 0;
  155. }
  156. }
  157. static getAttributeNum(attriStr) {
  158. switch (attriStr) {
  159. case "POSITION": return 3;
  160. case "NORMAL": return 3;
  161. case "COLOR": return 4;
  162. case "UV": return 2;
  163. case "UV1": return 2;
  164. case "BLENDWEIGHT": return 4;
  165. case "BLENDINDICES": return 4;
  166. case "TANGENT": return 4;
  167. default: return 0;
  168. }
  169. }
  170. static _getTypedArrayConstructor(componentType) {
  171. switch (componentType) {
  172. case 5120: return Int8Array;
  173. case 5121: return Uint8Array;
  174. case 5122: return Int16Array;
  175. case 5123: return Uint16Array;
  176. case 5125: return Uint32Array;
  177. case 5126: return Float32Array;
  178. }
  179. }
  180. static getBufferwithAccessorIndex(accessorIndex) {
  181. let accessor = glTFUtils._glTF.accessors[accessorIndex];
  182. if (!accessor)
  183. return null;
  184. let bufferView = glTFUtils._glTF.bufferViews[accessor.bufferView];
  185. let buffer = glTFUtils._glTFBuffers[bufferView.buffer];
  186. let count = accessor.count;
  187. let contentStride = glTFUtils.getAccessorComponentsNum(accessor.type);
  188. let byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
  189. let byteLength = count * contentStride;
  190. const constructor = glTFUtils._getTypedArrayConstructor(accessor.componentType);
  191. return new constructor(buffer, byteOffset, byteLength);
  192. }
  193. static _initTextureData(images) {
  194. if (!images)
  195. return;
  196. images.forEach((image, index) => {
  197. if (image.bufferView) {
  198. console.warn("glTF Loader: Todo: image bufferView data.");
  199. }
  200. else {
  201. glTFUtils._glTFTextures[index] = Laya.Loader.getRes(image.uri);
  202. }
  203. });
  204. }
  205. static getTextureMipmap(glTFSampler) {
  206. if (glTFSampler)
  207. return glTFSampler.minFilter === 9729 ||
  208. glTFSampler.minFilter === 9728;
  209. else
  210. return true;
  211. }
  212. static getTextureFormat(glTFImage) {
  213. if (glTFImage.mimeType === "image/png") {
  214. return 1;
  215. }
  216. else {
  217. return 0;
  218. }
  219. }
  220. static getTextureFilterMode(glTFSampler) {
  221. if (!glTFSampler) {
  222. return 1;
  223. }
  224. if (glTFSampler.magFilter === 9728) {
  225. return 0;
  226. }
  227. else if (glTFUtils.getTextureMipmap(glTFSampler)) {
  228. if (glTFSampler.minFilter === 9987)
  229. return 2;
  230. return 1;
  231. }
  232. return 1;
  233. }
  234. static getTextureWrapMode(mode) {
  235. if (mode === 33071) {
  236. return 1;
  237. }
  238. return 0;
  239. }
  240. static getTextureConstructParams(glTFImage, glTFSampler) {
  241. let constructParams = [];
  242. constructParams[0] = 0;
  243. constructParams[1] = 0;
  244. constructParams[2] = glTFUtils.getTextureFormat(glTFImage);
  245. constructParams[3] = glTFUtils.getTextureMipmap(glTFSampler);
  246. return constructParams;
  247. }
  248. static getTexturePropertyParams(glTFSampler) {
  249. let propertyParams = {};
  250. if (!glTFSampler) {
  251. return null;
  252. }
  253. propertyParams.filterMode = glTFUtils.getTextureFilterMode(glTFSampler);
  254. propertyParams.wrapModeU = glTFUtils.getTextureWrapMode(glTFSampler.wrapS);
  255. propertyParams.wrapModeV = glTFUtils.getTextureWrapMode(glTFSampler.wrapT);
  256. propertyParams.anisoLevel = 16;
  257. return propertyParams;
  258. }
  259. static getTexturewithInfo(glTFTextureInfo) {
  260. if (glTFTextureInfo.texCoord) {
  261. console.warn("glTF Loader: non 0 uv channel unsupported.");
  262. }
  263. return glTFUtils._glTFTextures[glTFTextureInfo.index];
  264. }
  265. static _loadMaterials(glTFMaterials) {
  266. if (!glTFMaterials)
  267. return;
  268. glTFMaterials.forEach((glTFMaterial, index) => {
  269. glTFUtils._glTFMaterials[index] = glTFUtils._loadMaterial(glTFMaterial);
  270. });
  271. }
  272. static _loadMaterial(glTFMaterial) {
  273. if (glTFMaterial.extras) {
  274. let createHandler = Laya.Handler.create(this, glTFUtils._createdefaultMaterial, null, false);
  275. return glTFUtils.ExecuteExtras("MATERIAL", glTFMaterial.extras, createHandler, [glTFMaterial]);
  276. }
  277. return glTFUtils._createdefaultMaterial(glTFMaterial);
  278. }
  279. static _createdefaultMaterial(glTFMaterial) {
  280. let layaPBRMaterial = new Laya.PBRStandardMaterial();
  281. layaPBRMaterial.name = glTFMaterial.name ? glTFMaterial.name : "";
  282. if (glTFMaterial.pbrMetallicRoughness) {
  283. glTFUtils.applyPBRMetallicRoughness(glTFMaterial.pbrMetallicRoughness, layaPBRMaterial);
  284. }
  285. if (glTFMaterial.normalTexture) {
  286. layaPBRMaterial.normalTexture = glTFUtils.getTexturewithInfo(glTFMaterial.normalTexture);
  287. if (glTFMaterial.normalTexture.scale != undefined) {
  288. layaPBRMaterial.normalTextureScale = glTFMaterial.normalTexture.scale;
  289. }
  290. }
  291. if (glTFMaterial.occlusionTexture) {
  292. layaPBRMaterial.occlusionTexture = glTFUtils.getTexturewithInfo(glTFMaterial.occlusionTexture);
  293. if (glTFMaterial.occlusionTexture.strength != undefined) {
  294. layaPBRMaterial.occlusionTextureStrength = glTFMaterial.occlusionTexture.strength;
  295. }
  296. }
  297. if (glTFMaterial.emissiveTexture) {
  298. layaPBRMaterial.emissionTexture = glTFUtils.getTexturewithInfo(glTFMaterial.emissiveTexture);
  299. if (layaPBRMaterial.emissionTexture) {
  300. layaPBRMaterial.enableEmission = true;
  301. }
  302. }
  303. if (glTFMaterial.emissiveFactor) {
  304. layaPBRMaterial.emissionColor.fromArray(glTFMaterial.emissiveFactor);
  305. layaPBRMaterial.emissionColor.w = 1.0;
  306. layaPBRMaterial.enableEmission = true;
  307. }
  308. let renderMode = glTFMaterial.alphaMode || "OPAQUE";
  309. switch (renderMode) {
  310. case "OPAQUE": {
  311. layaPBRMaterial.renderMode = Laya.PBRRenderMode.Opaque;
  312. break;
  313. }
  314. case "BLEND": {
  315. layaPBRMaterial.renderMode = Laya.PBRRenderMode.Transparent;
  316. break;
  317. }
  318. case "MASK": {
  319. layaPBRMaterial.renderMode = Laya.PBRRenderMode.Cutout;
  320. break;
  321. }
  322. default:
  323. }
  324. if (glTFMaterial.alphaCutoff != undefined) {
  325. layaPBRMaterial.alphaTestValue = glTFMaterial.alphaCutoff;
  326. }
  327. if (glTFMaterial.doubleSided) {
  328. layaPBRMaterial.cull = Laya.RenderState.CULL_NONE;
  329. }
  330. return layaPBRMaterial;
  331. }
  332. static applyPBRMetallicRoughness(pbrMetallicRoughness, layaPBRMaterial) {
  333. if (pbrMetallicRoughness.baseColorFactor) {
  334. layaPBRMaterial.albedoColor.fromArray(pbrMetallicRoughness.baseColorFactor);
  335. }
  336. if (pbrMetallicRoughness.baseColorTexture) {
  337. layaPBRMaterial.albedoTexture = glTFUtils.getTexturewithInfo(pbrMetallicRoughness.baseColorTexture);
  338. }
  339. if (pbrMetallicRoughness.metallicFactor != undefined) {
  340. layaPBRMaterial.metallic = pbrMetallicRoughness.metallicFactor;
  341. }
  342. if (pbrMetallicRoughness.roughnessFactor != undefined) {
  343. layaPBRMaterial.smoothness = 1.0 - pbrMetallicRoughness.roughnessFactor;
  344. }
  345. if (pbrMetallicRoughness.metallicRoughnessTexture) {
  346. layaPBRMaterial.metallicGlossTexture = glTFUtils.getTexturewithInfo(pbrMetallicRoughness.metallicRoughnessTexture);
  347. }
  348. }
  349. static pickMeshMaterials(glTFMesh) {
  350. let materials = [];
  351. glTFMesh.primitives.forEach(primitive => {
  352. if (primitive.material != undefined) {
  353. let material = glTFUtils._glTFMaterials[primitive.material];
  354. materials.push(material);
  355. }
  356. else {
  357. let material = new Laya.PBRStandardMaterial();
  358. materials.push(material);
  359. glTFUtils._glTFMaterials.push(material);
  360. primitive.material = glTFUtils._glTFMaterials.indexOf(material);
  361. }
  362. });
  363. return materials;
  364. }
  365. static _loadScenes(glTFScenes) {
  366. if (!glTFScenes)
  367. return;
  368. glTFScenes.forEach((glTFScene, index) => {
  369. glTFUtils._glTFScenes[index] = glTFUtils._loadScene(glTFScene);
  370. });
  371. }
  372. static _loadScene(glTFScene) {
  373. return glTFUtils._createSceneNode(glTFScene);
  374. }
  375. static _createSceneNode(glTFScene) {
  376. let glTFSceneNode = new Laya.Sprite3D(glTFScene.name || "glTF_Scene_node");
  377. glTFScene.nodes.forEach(nodeIndex => {
  378. let sprite = glTFUtils._glTFNodes[nodeIndex];
  379. glTFSceneNode.addChild(sprite);
  380. });
  381. return glTFSceneNode;
  382. }
  383. static applyTransform(glTFNode, sprite) {
  384. if (glTFNode.matrix) {
  385. let localMatrix = sprite.transform.localMatrix;
  386. localMatrix.elements.set(glTFNode.matrix);
  387. sprite.transform.localMatrix = localMatrix;
  388. }
  389. else {
  390. let localPosition = sprite.transform.localPosition;
  391. let localRotation = sprite.transform.localRotation;
  392. let localScale = sprite.transform.localScale;
  393. glTFNode.translation && localPosition.fromArray(glTFNode.translation);
  394. glTFNode.rotation && localRotation.fromArray(glTFNode.rotation);
  395. glTFNode.scale && localScale.fromArray(glTFNode.scale);
  396. sprite.transform.localPosition = localPosition;
  397. sprite.transform.localRotation = localRotation;
  398. sprite.transform.localScale = localScale;
  399. }
  400. }
  401. static buildHierarchy(glTFNodes) {
  402. glTFNodes.forEach((glTFNode, index) => {
  403. let sprite = glTFUtils._glTFNodes[index];
  404. if (glTFNode.children) {
  405. glTFNode.children.forEach((childIndex) => {
  406. let child = glTFUtils._glTFNodes[childIndex];
  407. sprite.addChild(child);
  408. });
  409. }
  410. });
  411. glTFNodes.forEach((glTFNode, index) => {
  412. let sprite = glTFUtils._glTFNodes[index];
  413. if (sprite instanceof Laya.SkinnedMeshSprite3D) {
  414. glTFUtils.fixSkinnedSprite(glTFNode, sprite);
  415. }
  416. });
  417. }
  418. static _loadNodes(glTFNodes) {
  419. if (!glTFNodes) {
  420. return;
  421. }
  422. glTFNodes.forEach((glTFNode, index) => {
  423. glTFNode.name = glTFNode.name || glTFUtils.getNodeRandomName("node");
  424. });
  425. glTFNodes.forEach((glTFNode, index) => {
  426. glTFUtils._glTFNodes[index] = glTFUtils._loadNode(glTFNode);
  427. });
  428. }
  429. static _loadNode(glTFNode) {
  430. return glTFUtils._createSprite3D(glTFNode);
  431. }
  432. static _createSprite3D(glTFNode) {
  433. glTFNode.name = glTFNode.name;
  434. if (glTFNode.skin != undefined) {
  435. let sprite = glTFUtils._createSkinnedMeshSprite3D(glTFNode);
  436. glTFUtils.applyTransform(glTFNode, sprite);
  437. return sprite;
  438. }
  439. else if (glTFNode.mesh != undefined) {
  440. let sprite = glTFUtils._createMeshSprite3D(glTFNode);
  441. glTFUtils.applyTransform(glTFNode, sprite);
  442. return sprite;
  443. }
  444. else {
  445. let sprite = new Laya.Sprite3D(glTFNode.name);
  446. glTFUtils.applyTransform(glTFNode, sprite);
  447. return sprite;
  448. }
  449. }
  450. static _createMeshSprite3D(glTFNode) {
  451. let glTFMesh = glTFUtils._glTF.meshes[glTFNode.mesh];
  452. let mesh = glTFUtils._loadMesh(glTFMesh);
  453. let materials = glTFUtils.pickMeshMaterials(glTFMesh);
  454. let sprite = new Laya.MeshSprite3D(mesh, glTFNode.name);
  455. sprite.meshRenderer.sharedMaterials = materials;
  456. return sprite;
  457. }
  458. static _createSkinnedMeshSprite3D(glTFNode) {
  459. let glTFMesh = glTFUtils._glTF.meshes[glTFNode.mesh];
  460. let glTFSkin = glTFUtils._glTF.skins[glTFNode.skin];
  461. let mesh = glTFUtils._loadMesh(glTFMesh, glTFSkin);
  462. let materials = glTFUtils.pickMeshMaterials(glTFMesh);
  463. let sprite = new Laya.SkinnedMeshSprite3D(mesh, glTFNode.name);
  464. sprite.skinnedMeshRenderer.sharedMaterials = materials;
  465. return sprite;
  466. }
  467. static getArrributeBuffer(attributeAccessorIndex, layaDeclarStr, attributeMap, vertexDeclarArr) {
  468. let attributeBuffer = glTFUtils.getBufferwithAccessorIndex(attributeAccessorIndex);
  469. if (!attributeBuffer)
  470. return null;
  471. vertexDeclarArr.push(layaDeclarStr);
  472. let res = attributeBuffer;
  473. attributeMap.set(layaDeclarStr, res);
  474. return res;
  475. }
  476. static getIndexBuffer(attributeAccessorIndex, vertexCount) {
  477. let indexBuffer = glTFUtils.getBufferwithAccessorIndex(attributeAccessorIndex);
  478. if (indexBuffer) {
  479. return new Uint32Array(indexBuffer).reverse();
  480. }
  481. else {
  482. let indices = new Uint32Array(vertexCount);
  483. for (let i = 0; i < vertexCount; i++) {
  484. indices[i] = i;
  485. }
  486. return indices;
  487. }
  488. }
  489. static parseMeshwithSubMeshData(subDatas, layaMesh) {
  490. let vertexCount = 0;
  491. let indexCount = 0;
  492. let vertexDecler = undefined;
  493. subDatas.forEach(subData => {
  494. vertexCount += subData.vertexCount;
  495. indexCount += subData.indices.length;
  496. vertexDecler = vertexDecler || subData.vertexDecler;
  497. });
  498. let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration(vertexDecler, false);
  499. let vertexByteStride = vertexDeclaration.vertexStride;
  500. let vertexFloatStride = vertexByteStride / 4;
  501. let vertexArray = new Float32Array(vertexFloatStride * vertexCount);
  502. let indexArray;
  503. let ibFormat = Laya.IndexFormat.UInt32;
  504. if (vertexCount < 65536) {
  505. indexArray = new Uint16Array(indexCount);
  506. ibFormat = Laya.IndexFormat.UInt16;
  507. }
  508. glTFUtils.fillMeshBuffers(subDatas, vertexArray, indexArray, vertexFloatStride);
  509. glTFUtils.generatMesh(vertexArray, indexArray, vertexDeclaration, ibFormat, subDatas, layaMesh);
  510. }
  511. static fillMeshBuffers(subDatas, vertexArray, indexArray, vertexFloatStride) {
  512. let ibPosOffset = 0;
  513. let ibVertexOffset = 0;
  514. let vbPosOffset = 0;
  515. subDatas.forEach((subData) => {
  516. let iAOffset = ibPosOffset;
  517. let vertexCount = subData.vertexCount;
  518. let subIb = subData.indices;
  519. for (let index = 0; index < subIb.length; index++) {
  520. indexArray[iAOffset + index] = subIb[index] + ibVertexOffset;
  521. }
  522. ibPosOffset += subIb.length;
  523. ibVertexOffset += vertexCount;
  524. const fillAttributeBuffer = (value, attriOffset, attriFloatCount = 0) => {
  525. let startOffset = vbPosOffset + attriOffset;
  526. for (let index = 0; index < vertexCount; index++) {
  527. for (let ac = 0; ac < attriFloatCount; ac++) {
  528. vertexArray[startOffset + index * vertexFloatStride + ac] = value[index * attriFloatCount + ac];
  529. }
  530. }
  531. };
  532. let attriOffset = 0;
  533. let attributeMap = subData.attributeMap;
  534. let position = attributeMap.get("POSITION");
  535. (position) && (fillAttributeBuffer(position, attriOffset, 3), attriOffset += 3);
  536. let normal = attributeMap.get("NORMAL");
  537. (normal) && (fillAttributeBuffer(normal, attriOffset, 3), attriOffset += 3);
  538. let color = attributeMap.get("COLOR");
  539. (color) && (fillAttributeBuffer(color, attriOffset, 4), attriOffset += 4);
  540. let uv = attributeMap.get("UV");
  541. (uv) && (fillAttributeBuffer(uv, attriOffset, 2), attriOffset += 2);
  542. let uv1 = attributeMap.get("UV1");
  543. (uv1) && (fillAttributeBuffer(uv1, attriOffset, 2), attriOffset += 2);
  544. let blendWeight = attributeMap.get("BLENDWEIGHT");
  545. (blendWeight) && (fillAttributeBuffer(blendWeight, attriOffset, 4), attriOffset += 4);
  546. let blendIndices = attributeMap.get("BLENDINDICES");
  547. if (blendIndices) {
  548. let blendIndicesUint8 = new Uint8Array(blendIndices);
  549. let blendIndicesFloat32 = new Float32Array(blendIndicesUint8.buffer);
  550. fillAttributeBuffer(blendIndicesFloat32, attriOffset, 1), attriOffset += 1;
  551. }
  552. let tangent = attributeMap.get("TANGENT");
  553. (tangent) && (fillAttributeBuffer(tangent, attriOffset, 4), attriOffset += 4);
  554. vbPosOffset += vertexCount * vertexFloatStride;
  555. });
  556. }
  557. static splitSubMeshByBonesCount(attributeMap, indexArray, boneIndicesList, subIndexStartArray, subIndexCountArray) {
  558. let maxSubBoneCount = glTFUtils.maxSubBoneCount;
  559. let start = 0;
  560. let subIndexSet = new Set();
  561. let boneIndexArray = attributeMap.get("BLENDINDICES");
  562. let vertexCount = boneIndexArray.length / 4;
  563. let resArray = new Float32Array(boneIndexArray.length);
  564. let flagArray = new Array(vertexCount).fill(false);
  565. for (let i = 0, n = indexArray.length; i < n; i += 3) {
  566. let triangleSet = new Set();
  567. for (let j = i; j < i + 3; j++) {
  568. let ibIndex = indexArray[j];
  569. let boneIndexOffset = ibIndex * 4;
  570. for (let k = 0; k < 4; k++) {
  571. triangleSet.add(boneIndexArray[boneIndexOffset + k]);
  572. }
  573. }
  574. let tempSet = new Set([...subIndexSet, ...triangleSet]);
  575. if (tempSet.size > maxSubBoneCount) {
  576. let count = i - start;
  577. subIndexStartArray.push(start);
  578. subIndexCountArray.push(count);
  579. let curBoneList = Array.from(subIndexSet);
  580. boneIndicesList.push(new Uint16Array(curBoneList));
  581. start = i;
  582. subIndexSet = new Set(triangleSet);
  583. }
  584. else {
  585. subIndexSet = tempSet;
  586. }
  587. if (i == n - 3) {
  588. let count = i - start + 3;
  589. subIndexStartArray.push(start);
  590. subIndexCountArray.push(count);
  591. start = i;
  592. let curBoneList = Array.from(subIndexSet);
  593. boneIndicesList.push(new Uint16Array(curBoneList));
  594. }
  595. }
  596. let drawCount = boneIndicesList.length;
  597. let newAttributeMap = new Map();
  598. attributeMap.forEach((value, key) => {
  599. let array = new Array();
  600. newAttributeMap.set(key, array);
  601. });
  602. let curMaxIndex = vertexCount - 1;
  603. for (let d = 0; d < drawCount; d++) {
  604. let k = subIndexStartArray[d];
  605. let l = subIndexCountArray[d];
  606. let bl = boneIndicesList[d];
  607. let batchFlag = new Array(vertexCount).fill(false);
  608. let batchMap = new Map();
  609. for (let area = 0; area < l; area++) {
  610. let ci = indexArray[area + k];
  611. let biStart = 4 * ci;
  612. for (let cbi = biStart; cbi < biStart + 4; cbi++) {
  613. let oldBoneIndex = boneIndexArray[cbi];
  614. let newBoneIndex = bl.indexOf(oldBoneIndex);
  615. newBoneIndex = newBoneIndex == -1 ? 0 : newBoneIndex;
  616. if (flagArray[ci] && !batchFlag[ci]) {
  617. newAttributeMap.get("BLENDINDICES").push(newBoneIndex);
  618. }
  619. else if (flagArray[ci] && batchFlag[ci]) ;
  620. else {
  621. resArray[cbi] = newBoneIndex;
  622. }
  623. }
  624. if (!flagArray[ci] && !batchFlag[ci]) {
  625. batchFlag[ci] = true;
  626. batchMap.set(ci, ci);
  627. }
  628. else if (!flagArray[ci] && batchFlag[ci]) {
  629. indexArray[area + k] = batchMap.get(ci);
  630. }
  631. else if (flagArray[ci] && !batchFlag[ci]) {
  632. batchFlag[ci] = true;
  633. curMaxIndex++;
  634. batchMap.set(ci, curMaxIndex);
  635. indexArray[area + k] = curMaxIndex;
  636. newAttributeMap.forEach((value, key) => {
  637. let attOffset = glTFUtils.getAttributeNum(key);
  638. let oldArray = attributeMap.get(key);
  639. if (key !== "BLENDINDICES") {
  640. for (let index = 0; index < attOffset; index++) {
  641. value.push(oldArray[index + ci * attOffset]);
  642. }
  643. }
  644. });
  645. }
  646. else if (flagArray[ci] && batchFlag[ci]) {
  647. indexArray[area + k] = batchMap.get(ci);
  648. }
  649. }
  650. batchFlag.forEach((value, index) => {
  651. flagArray[index] = value || flagArray[index];
  652. });
  653. }
  654. newAttributeMap.forEach((value, key) => {
  655. let oldFloatArray = attributeMap.get(key);
  656. if (key == "BLENDINDICES") {
  657. oldFloatArray = resArray;
  658. }
  659. let newLength = oldFloatArray.length + value.length;
  660. let newFloatArray = new Float32Array(newLength);
  661. newFloatArray.set(oldFloatArray, 0);
  662. newFloatArray.set(value, oldFloatArray.length);
  663. attributeMap.set(key, newFloatArray);
  664. });
  665. boneIndexArray = null;
  666. }
  667. static generatMesh(vertexArray, indexArray, vertexDeclaration, ibFormat, subDatas, layaMesh) {
  668. let gl = Laya.LayaGL.instance;
  669. let vertexBuffer = new Laya.VertexBuffer3D(vertexArray.byteLength, gl.STATIC_DRAW, true);
  670. vertexBuffer.vertexDeclaration = vertexDeclaration;
  671. vertexBuffer.setData(vertexArray.buffer);
  672. let indexBuffer = new Laya.IndexBuffer3D(ibFormat, indexArray.length, gl.STATIC_DRAW, true);
  673. indexBuffer.setData(indexArray);
  674. layaMesh._indexFormat = ibFormat;
  675. layaMesh._indexBuffer = indexBuffer;
  676. layaMesh._vertexBuffer = vertexBuffer;
  677. layaMesh._setBuffer(vertexBuffer, indexBuffer);
  678. layaMesh._vertexCount = vertexBuffer._byteLength / vertexDeclaration.vertexStride;
  679. let subMeshOffset = 0;
  680. let subMeshCount = subDatas.length;
  681. let subMeshes = new Array(subMeshCount);
  682. for (let index = 0; index < subMeshCount; index++) {
  683. let subData = subDatas[index];
  684. let subMesh = new Laya.SubMesh(layaMesh);
  685. subMeshes[index] = subMesh;
  686. subMesh._vertexBuffer = vertexBuffer;
  687. subMesh._indexBuffer = indexBuffer;
  688. let subIndexStart = subMeshOffset;
  689. subMeshOffset += subData.indices.length;
  690. let subIndexCount = subData.indices.length;
  691. subMesh._setIndexRange(subIndexStart, subIndexCount, ibFormat);
  692. subMesh._boneIndicesList = subData.boneIndicesList;
  693. subMesh._subIndexBufferStart = subData.subIndexStartArray;
  694. subMesh._subIndexBufferCount = subData.subIndexCountArray;
  695. for (let subIndex = 0; subIndex < subMesh._subIndexBufferStart.length; subIndex++) {
  696. subMesh._subIndexBufferStart[subIndex] += subIndexStart;
  697. }
  698. }
  699. layaMesh._setSubMeshes(subMeshes);
  700. layaMesh.calculateBounds();
  701. let memorySize = vertexBuffer._byteLength + indexBuffer._byteLength;
  702. layaMesh._setCPUMemory(memorySize);
  703. layaMesh._setGPUMemory(memorySize);
  704. }
  705. static applyglTFSkinData(mesh, subDatas, glTFSkin) {
  706. if (!glTFSkin)
  707. return;
  708. let joints = glTFSkin.joints;
  709. let inverseBindMatricesArray = new Float32Array(glTFUtils.getBufferwithAccessorIndex(glTFSkin.inverseBindMatrices));
  710. let boneCount = joints.length;
  711. let boneNames = mesh._boneNames = [];
  712. joints.forEach(nodeIndex => {
  713. let node = glTFUtils._glTF.nodes[nodeIndex];
  714. boneNames.push(node.name);
  715. });
  716. mesh._inverseBindPoses = [];
  717. mesh._inverseBindPosesBuffer = inverseBindMatricesArray.buffer;
  718. mesh._setInstanceBuffer(Laya.Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL);
  719. for (let index = 0; index < boneCount; index++) {
  720. let bindPosesArrayOffset = 16 * index;
  721. let matElement = inverseBindMatricesArray.slice(bindPosesArrayOffset, bindPosesArrayOffset + 16);
  722. mesh._inverseBindPoses[index] = new Laya.Matrix4x4(matElement[0], matElement[1], matElement[2], matElement[3], matElement[4], matElement[5], matElement[6], matElement[7], matElement[8], matElement[9], matElement[10], matElement[11], matElement[12], matElement[13], matElement[14], matElement[15], matElement);
  723. }
  724. let subCount = subDatas.length;
  725. let skinnedCache = mesh._skinnedMatrixCaches;
  726. skinnedCache.length = mesh._inverseBindPoses.length;
  727. for (let subIndex = 0; subIndex < subCount; subIndex++) {
  728. let submesh = mesh.getSubMesh(subIndex);
  729. let drawCount = submesh._subIndexBufferStart.length;
  730. for (let drawIndex = 0; drawIndex < drawCount; drawIndex++) {
  731. let boneIndices = submesh._boneIndicesList[drawIndex];
  732. for (let bni = 0; bni < boneIndices.length; bni++) {
  733. let bn = boneIndices[bni];
  734. skinnedCache[bn] || (skinnedCache[bn] = new Laya.skinnedMatrixCache(subIndex, drawIndex, bni));
  735. }
  736. }
  737. }
  738. for (let index = 0; index < skinnedCache.length; index++) {
  739. if (!skinnedCache[index]) {
  740. skinnedCache[index] = new Laya.skinnedMatrixCache(0, 0, 0);
  741. }
  742. }
  743. }
  744. static _loadMesh(glTFMesh, glTFSkin) {
  745. if (glTFMesh.extras) {
  746. let createHandler = Laya.Handler.create(this, glTFUtils._createMesh, null, false);
  747. return glTFUtils.ExecuteExtras("MESH", glTFMesh.extras, createHandler, [glTFMesh, glTFSkin]);
  748. }
  749. let mesh = glTFUtils._createMesh(glTFMesh, glTFSkin);
  750. return mesh;
  751. }
  752. static _createMesh(glTFMesh, glTFSkin) {
  753. let layaMesh = new Laya.Mesh();
  754. let glTFMeshPrimitives = glTFMesh.primitives;
  755. let morphWeights = glTFMesh.weights;
  756. let boneCount = (glTFSkin) ? glTFSkin.joints.length : 0;
  757. let subDatas = [];
  758. glTFMeshPrimitives.forEach((glTFMeshPrimitive) => {
  759. let mode = glTFMeshPrimitive.mode;
  760. if (mode == undefined)
  761. mode = 4;
  762. if (4 != mode) {
  763. console.warn("glTF Loader: only support gl.TRIANGLES.");
  764. debugger;
  765. }
  766. let vertexDeclarArr = [];
  767. let attributeMap = new Map();
  768. let attributes = glTFMeshPrimitive.attributes;
  769. let position = glTFUtils.getArrributeBuffer(attributes.POSITION, "POSITION", attributeMap, vertexDeclarArr);
  770. let normal = glTFUtils.getArrributeBuffer(attributes.NORMAL, "NORMAL", attributeMap, vertexDeclarArr);
  771. let color = glTFUtils.getArrributeBuffer(attributes.COLOR_0, "COLOR", attributeMap, vertexDeclarArr);
  772. let uv = glTFUtils.getArrributeBuffer(attributes.TEXCOORD_0, "UV", attributeMap, vertexDeclarArr);
  773. let uv1 = glTFUtils.getArrributeBuffer(attributes.TEXCOORD_1, "UV1", attributeMap, vertexDeclarArr);
  774. let blendWeight = glTFUtils.getArrributeBuffer(attributes.WEIGHTS_0, "BLENDWEIGHT", attributeMap, vertexDeclarArr);
  775. let blendIndices = glTFUtils.getArrributeBuffer(attributes.JOINTS_0, "BLENDINDICES", attributeMap, vertexDeclarArr);
  776. let tangent = glTFUtils.getArrributeBuffer(attributes.TANGENT, "TANGENT", attributeMap, vertexDeclarArr);
  777. let targets = glTFMeshPrimitive.targets;
  778. (targets) && targets.forEach((target, index) => {
  779. let weight = morphWeights[index];
  780. let morphPosition = glTFUtils.getBufferwithAccessorIndex(target.POSITION);
  781. let morphNormal = glTFUtils.getBufferwithAccessorIndex(target.NORMAL);
  782. let morphTangent = glTFUtils.getBufferwithAccessorIndex(target.TANGENT);
  783. (morphPosition) && morphPosition.forEach((value, index) => {
  784. position[index] += value * weight;
  785. });
  786. (morphNormal) && morphNormal.forEach((value, index) => {
  787. normal[index] += value * weight;
  788. });
  789. (morphTangent) && morphTangent.forEach((value, index) => {
  790. tangent[index] += value * weight;
  791. });
  792. });
  793. let vertexCount = position.length / 3;
  794. let indexArray = glTFUtils.getIndexBuffer(glTFMeshPrimitive.indices, vertexCount);
  795. let boneIndicesList = new Array();
  796. let subIndexStartArray = [];
  797. let subIndexCountArray = [];
  798. if (glTFSkin) {
  799. if (boneCount > glTFUtils.maxSubBoneCount) {
  800. glTFUtils.splitSubMeshByBonesCount(attributeMap, indexArray, boneIndicesList, subIndexStartArray, subIndexCountArray);
  801. vertexCount = attributeMap.get("POSITION").length / 3;
  802. }
  803. else {
  804. subIndexStartArray[0] = 0;
  805. subIndexCountArray[0] = indexArray.length;
  806. boneIndicesList[0] = new Uint16Array(boneCount);
  807. for (let bi = 0; bi < boneCount; bi++) {
  808. boneIndicesList[0][bi] = bi;
  809. }
  810. }
  811. }
  812. else {
  813. subIndexStartArray[0] = 0;
  814. subIndexCountArray[0] = indexArray.length;
  815. }
  816. let vertexDeclaration = vertexDeclarArr.toString();
  817. let subData = new PrimitiveSubMesh();
  818. subDatas.push(subData);
  819. subData.attributeMap = attributeMap;
  820. subData.indices = indexArray;
  821. subData.vertexCount = vertexCount;
  822. subData.vertexDecler = vertexDeclaration;
  823. subData.boneIndicesList = boneIndicesList;
  824. subData.subIndexStartArray = subIndexStartArray;
  825. subData.subIndexCountArray = subIndexCountArray;
  826. });
  827. glTFUtils.parseMeshwithSubMeshData(subDatas, layaMesh);
  828. glTFUtils.applyglTFSkinData(layaMesh, subDatas, glTFSkin);
  829. return layaMesh;
  830. }
  831. static calSkinnedSpriteLocalBounds(skinned) {
  832. let render = skinned.skinnedMeshRenderer;
  833. let mesh = skinned.meshFilter.sharedMesh;
  834. let rootBone = render.rootBone;
  835. let oriRootMatrix = rootBone.transform.worldMatrix;
  836. let invertRootMatrix = new Laya.Matrix4x4();
  837. oriRootMatrix.invert(invertRootMatrix);
  838. let indices = mesh.getIndices();
  839. let positions = [];
  840. let boneIndices = [];
  841. let boneWeights = [];
  842. mesh.getPositions(positions);
  843. mesh.getBoneIndices(boneIndices);
  844. mesh.getBoneWeights(boneWeights);
  845. let oriBoneIndeices = [];
  846. mesh._subMeshes.forEach((subMesh, index) => {
  847. let bonelists = subMesh._boneIndicesList;
  848. bonelists.forEach((bonelist, listIndex) => {
  849. let start = subMesh._subIndexBufferStart[listIndex];
  850. let count = subMesh._subIndexBufferCount[listIndex];
  851. let endIndex = count + start;
  852. for (let iindex = start; iindex < endIndex; iindex++) {
  853. let ii = indices[iindex];
  854. let boneIndex = boneIndices[ii];
  855. let x = bonelist[boneIndex.x];
  856. let y = bonelist[boneIndex.y];
  857. let z = bonelist[boneIndex.z];
  858. let w = bonelist[boneIndex.w];
  859. oriBoneIndeices[ii] = new Laya.Vector4(x, y, z, w);
  860. }
  861. });
  862. });
  863. let inverseBindPoses = mesh._inverseBindPoses;
  864. let bones = render.bones;
  865. let ubones = [];
  866. let tempMat = new Laya.Matrix4x4();
  867. bones.forEach((bone, index) => {
  868. ubones[index] = new Laya.Matrix4x4();
  869. Laya.Matrix4x4.multiply(invertRootMatrix, bone.transform.worldMatrix, tempMat);
  870. Laya.Matrix4x4.multiply(tempMat, inverseBindPoses[index], ubones[index]);
  871. });
  872. let skinTransform = new Laya.Matrix4x4;
  873. let resPos = new Laya.Vector3();
  874. let min = new Laya.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
  875. let max = new Laya.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
  876. positions.forEach((pos, index) => {
  877. let boneIndex = oriBoneIndeices[index];
  878. let boneWeight = boneWeights[index];
  879. for (let ei = 0; ei < 16; ei++) {
  880. skinTransform.elements[ei] = ubones[boneIndex.x].elements[ei] * boneWeight.x;
  881. skinTransform.elements[ei] += ubones[boneIndex.y].elements[ei] * boneWeight.y;
  882. skinTransform.elements[ei] += ubones[boneIndex.z].elements[ei] * boneWeight.z;
  883. skinTransform.elements[ei] += ubones[boneIndex.w].elements[ei] * boneWeight.w;
  884. }
  885. Laya.Vector3.transformV3ToV3(pos, skinTransform, resPos);
  886. Laya.Vector3.min(min, resPos, min);
  887. Laya.Vector3.max(max, resPos, max);
  888. });
  889. positions = null;
  890. boneIndices = boneWeights = oriBoneIndeices = null;
  891. indices = null;
  892. ubones = null;
  893. render.localBounds.setMin(min);
  894. render.localBounds.setMax(max);
  895. }
  896. static fixSkinnedSprite(glTFNode, skinned) {
  897. let skin = glTFUtils._glTF.skins[glTFNode.skin];
  898. let skinnedMeshRenderer = skinned.skinnedMeshRenderer;
  899. skin.joints.forEach(nodeIndex => {
  900. let bone = glTFUtils._glTFNodes[nodeIndex];
  901. skinnedMeshRenderer.bones.push(bone);
  902. });
  903. if (skin.skeleton == undefined) {
  904. skin.skeleton = skin.joints[0];
  905. }
  906. skinnedMeshRenderer.rootBone = glTFUtils._glTFNodes[skin.skeleton];
  907. glTFUtils.calSkinnedSpriteLocalBounds(skinned);
  908. }
  909. static getAnimationRoot(channels) {
  910. const isContainNode = (nodeArr, findNodeIndex) => {
  911. if (!nodeArr)
  912. return false;
  913. if (nodeArr.indexOf(findNodeIndex) == -1) {
  914. for (let index = 0; index < nodeArr.length; index++) {
  915. let glTFNode = glTFUtils._glTF.nodes[nodeArr[index]];
  916. if (isContainNode(glTFNode.children, findNodeIndex)) {
  917. return true;
  918. }
  919. }
  920. }
  921. return true;
  922. };
  923. let target = channels[0].target;
  924. let spriteIndex = target.node;
  925. for (let index = 0; index < glTFUtils._glTF.scenes.length; index++) {
  926. let glTFScene = glTFUtils._glTF.scenes[index];
  927. if (isContainNode(glTFScene.nodes, spriteIndex)) {
  928. return glTFUtils._glTFScenes[index];
  929. }
  930. }
  931. return null;
  932. }
  933. static getAnimationPath(root, curSprite) {
  934. let paths = [];
  935. if (root == curSprite)
  936. return paths;
  937. let sprite = curSprite;
  938. while (sprite.parent != root) {
  939. sprite = sprite.parent;
  940. paths.push(sprite.name);
  941. }
  942. paths = paths.reverse();
  943. paths.push(curSprite.name);
  944. return paths;
  945. }
  946. static _loadAnimations(animations) {
  947. if (!animations)
  948. return;
  949. animations.forEach((animation, index) => {
  950. glTFUtils._loadAnimation(animation);
  951. });
  952. }
  953. static _loadAnimation(animation) {
  954. return glTFUtils._createAnimator(animation);
  955. }
  956. static _createAnimator(animation) {
  957. let animator = new Laya.Animator();
  958. let channels = animation.channels;
  959. let samplers = animation.samplers;
  960. let animatorRoot = glTFUtils.getAnimationRoot(channels);
  961. if (!animatorRoot) {
  962. return animator;
  963. }
  964. animatorRoot.addComponentIntance(animator);
  965. let duration = 0;
  966. let clipNodes = new Array(channels.length);
  967. channels.forEach((channel, index) => {
  968. let target = channel.target;
  969. let sampler = samplers[channel.sampler];
  970. let clipNode = clipNodes[index] = new ClipNode();
  971. let sprite = glTFUtils._glTFNodes[target.node];
  972. let timeBuffer = glTFUtils.getBufferwithAccessorIndex(sampler.input);
  973. let outBuffer = glTFUtils.getBufferwithAccessorIndex(sampler.output);
  974. clipNode.timeArray = new Float32Array(timeBuffer);
  975. clipNode.valueArray = new Float32Array(outBuffer);
  976. clipNode.paths = glTFUtils.getAnimationPath(animatorRoot, sprite);
  977. clipNode.propertyOwner = "transform";
  978. clipNode.propertyLength = 1;
  979. clipNode.propertise = [];
  980. let targetPath = target.path;
  981. switch (targetPath) {
  982. case "translation":
  983. clipNode.propertise.push("localPosition");
  984. clipNode.type = 1;
  985. break;
  986. case "rotation":
  987. clipNode.propertise.push("localRotation");
  988. clipNode.type = 2;
  989. break;
  990. case "scale":
  991. clipNode.propertise.push("localScale");
  992. clipNode.type = 3;
  993. break;
  994. default:
  995. break;
  996. }
  997. clipNode.duration = clipNode.timeArray[clipNode.timeArray.length - 1];
  998. duration = Math.max(duration, clipNode.duration);
  999. });
  1000. let layerName = animation.name ? animation.name : "Aniamtor";
  1001. let animatorLayer = new Laya.AnimatorControllerLayer(layerName);
  1002. let clip = new Laya.AnimationClip();
  1003. clip.name = "clip name";
  1004. clip._duration = duration;
  1005. clip.islooping = true;
  1006. clip._frameRate = 30;
  1007. let nodeCount = clipNodes.length;
  1008. let nodes = clip._nodes;
  1009. nodes.count = nodeCount;
  1010. let nodesMap = clip._nodesMap = {};
  1011. let nodesDic = clip._nodesDic = {};
  1012. for (let i = 0; i < nodeCount; i++) {
  1013. let node = new Laya.KeyframeNode();
  1014. let gLTFClipNode = clipNodes[i];
  1015. nodes.setNodeByIndex(i, node);
  1016. node._indexInList = i;
  1017. let type = node.type = gLTFClipNode.type;
  1018. let pathLength = gLTFClipNode.paths.length;
  1019. node._setOwnerPathCount(pathLength);
  1020. let tempPath = gLTFClipNode.paths;
  1021. for (let j = 0; j < pathLength; j++) {
  1022. node._setOwnerPathByIndex(j, tempPath[j]);
  1023. }
  1024. let nodePath = node._joinOwnerPath("/");
  1025. let mapArray = nodesMap[nodePath];
  1026. (mapArray) || (nodesMap[nodePath] = mapArray = []);
  1027. mapArray.push(node);
  1028. node.propertyOwner = gLTFClipNode.propertyOwner;
  1029. let propertyLength = gLTFClipNode.propertyLength;
  1030. node._setPropertyCount(propertyLength);
  1031. for (let j = 0; j < propertyLength; j++) {
  1032. node._setPropertyByIndex(j, gLTFClipNode.propertise[j]);
  1033. }
  1034. let fullPath = nodePath + "." + node.propertyOwner + "." + node._joinProperty(".");
  1035. nodesDic[fullPath] = fullPath;
  1036. node.fullPath = fullPath;
  1037. let keyframeCount = gLTFClipNode.timeArray.length;
  1038. for (let j = 0; j < keyframeCount; j++) {
  1039. switch (type) {
  1040. case 0:
  1041. break;
  1042. case 1:
  1043. case 3:
  1044. case 4:
  1045. let floatArrayKeyframe = new Laya.Vector3Keyframe();
  1046. node._setKeyframeByIndex(j, floatArrayKeyframe);
  1047. let startTimev3 = floatArrayKeyframe.time = gLTFClipNode.timeArray[j];
  1048. let inTangent = floatArrayKeyframe.inTangent;
  1049. let outTangent = floatArrayKeyframe.outTangent;
  1050. let value = floatArrayKeyframe.value;
  1051. inTangent.setValue(0, 0, 0);
  1052. outTangent.setValue(0, 0, 0);
  1053. value.setValue(gLTFClipNode.valueArray[3 * j], gLTFClipNode.valueArray[3 * j + 1], gLTFClipNode.valueArray[3 * j + 2]);
  1054. break;
  1055. case 2:
  1056. let quaternionKeyframe = new Laya.QuaternionKeyframe();
  1057. node._setKeyframeByIndex(j, quaternionKeyframe);
  1058. let startTimeQu = quaternionKeyframe.time = gLTFClipNode.timeArray[j];
  1059. let inTangentQua = quaternionKeyframe.inTangent;
  1060. let outTangentQua = quaternionKeyframe.outTangent;
  1061. let valueQua = quaternionKeyframe.value;
  1062. inTangentQua.setValue(0, 0, 0, 0);
  1063. outTangentQua.setValue(0, 0, 0, 0);
  1064. valueQua.x = gLTFClipNode.valueArray[4 * j];
  1065. valueQua.y = gLTFClipNode.valueArray[4 * j + 1];
  1066. valueQua.z = gLTFClipNode.valueArray[4 * j + 2];
  1067. valueQua.w = gLTFClipNode.valueArray[4 * j + 3];
  1068. break;
  1069. }
  1070. }
  1071. }
  1072. let animatorState = new Laya.AnimatorState();
  1073. animatorState.name = "state name";
  1074. animatorState.clip = clip;
  1075. animatorLayer.addState(animatorState);
  1076. animatorLayer.defaultState = animatorState;
  1077. animatorLayer.playOnWake = true;
  1078. animator.addControllerLayer(animatorLayer);
  1079. animatorLayer.defaultWeight = 1.0;
  1080. return animator;
  1081. }
  1082. }
  1083. glTFUtils.NAMEID = 0;
  1084. glTFUtils.maxSubBoneCount = 24;
  1085. glTFUtils.Extensions = {};
  1086. glTFUtils.Extras = {};
  1087. glTFUtils._glTFBuffers = [];
  1088. glTFUtils._glTFTextures = [];
  1089. glTFUtils._glTFMaterials = [];
  1090. glTFUtils._glTFNodes = [];
  1091. glTFUtils._glTFScenes = [];
  1092. class glTFLoader {
  1093. static init() {
  1094. let createMap = Laya.LoaderManager.createMap;
  1095. createMap["gltf"] = [glTFLoader.GLTF, glTFUtils._parse];
  1096. let parseMap = Laya.Loader.parserMap;
  1097. parseMap[glTFLoader.GLTF] = glTFLoader._loadglTF;
  1098. parseMap[glTFLoader.GLTFBASE64TEX] = glTFLoader._loadBase64Texture;
  1099. glTFLoader._innerBufferLoaderManager.on(Laya.Event.ERROR, null, glTFLoader._eventLoadManagerError);
  1100. glTFLoader._innerTextureLoaderManager.on(Laya.Event.ERROR, null, glTFLoader._eventLoadManagerError);
  1101. }
  1102. static _loadglTF(loader) {
  1103. loader._originType = loader.type;
  1104. loader.on(Laya.Event.LOADED, null, glTFLoader._onglTFLoaded, [loader]);
  1105. loader.load(loader.url, Laya.Loader.JSON, false, null, true);
  1106. }
  1107. static _loadBase64Texture(loader) {
  1108. let url = loader.url;
  1109. let type = "nativeimage";
  1110. loader.on(Laya.Event.LOADED, null, function (image) {
  1111. loader._cache = loader._createCache;
  1112. let tex = Laya.Texture2D._parse(image, loader._propertyParams, loader._constructParams);
  1113. glTFLoader._endLoad(loader, tex);
  1114. });
  1115. loader.load(url, type, false, null, true);
  1116. }
  1117. static formatRelativePath(base, value) {
  1118. let path;
  1119. path = base + value;
  1120. let char1 = value.charAt(0);
  1121. if (char1 === ".") {
  1122. let parts = path.split("/");
  1123. for (let i = 0, len = parts.length; i < len; i++) {
  1124. if (parts[i] == '..') {
  1125. let index = i - 1;
  1126. if (index > 0 && parts[index] !== '..') {
  1127. parts.splice(index, 2);
  1128. i -= 2;
  1129. }
  1130. }
  1131. }
  1132. path = parts.join('/');
  1133. }
  1134. return path;
  1135. }
  1136. static _addglTFInnerUrls(urls, urlMap, urlVersion, glTFBasePath, path, type, constructParams = null, propertyParams = null) {
  1137. let formatUrl = glTFLoader.formatRelativePath(glTFBasePath, path);
  1138. (urlVersion) && (formatUrl = formatUrl + urlVersion);
  1139. urls.push({ url: formatUrl, type: type, constructParams: constructParams, propertyParams: propertyParams });
  1140. (urlMap) && (urlMap.push(formatUrl));
  1141. return formatUrl;
  1142. }
  1143. static _getglTFInnerUrls(glTFData, bufferUrls, textureUrls, subUrls, urlVersion, glTFBasePath) {
  1144. if (glTFData.buffers) {
  1145. glTFData.buffers.forEach(buffer => {
  1146. if (Laya.glTFBase64Tool.isBase64String(buffer.uri)) {
  1147. let bin = Laya.glTFBase64Tool.decode(buffer.uri.replace(Laya.glTFBase64Tool.reghead, ""));
  1148. Laya.Loader.cacheRes(buffer.uri, bin);
  1149. }
  1150. else {
  1151. buffer.uri = glTFLoader._addglTFInnerUrls(bufferUrls, null, urlVersion, glTFBasePath, buffer.uri, Laya.Loader.BUFFER);
  1152. }
  1153. });
  1154. }
  1155. if (glTFData.textures) {
  1156. glTFData.textures.forEach(glTFTexture => {
  1157. let glTFImage = glTFData.images[glTFTexture.source];
  1158. let glTFSampler = glTFData.samplers ? glTFData.samplers[glTFTexture.sampler] : undefined;
  1159. let constructParams = glTFUtils.getTextureConstructParams(glTFImage, glTFSampler);
  1160. let propertyParams = glTFUtils.getTexturePropertyParams(glTFSampler);
  1161. if (glTFImage.bufferView) ;
  1162. else if (Laya.glTFBase64Tool.isBase64String(glTFImage.uri)) {
  1163. glTFImage.uri = glTFLoader._addglTFInnerUrls(textureUrls, subUrls, urlVersion, "", glTFImage.uri, glTFLoader.GLTFBASE64TEX, constructParams, propertyParams);
  1164. }
  1165. else {
  1166. glTFImage.uri = glTFLoader._addglTFInnerUrls(textureUrls, subUrls, urlVersion, glTFBasePath, glTFImage.uri, Laya.Loader.TEXTURE2D, constructParams, propertyParams);
  1167. }
  1168. });
  1169. }
  1170. }
  1171. static _onglTFLoaded(loader, glTFData) {
  1172. let url = loader.url;
  1173. let urlVersion = Laya.Utils3D.getURLVerion(url);
  1174. let glTFBasePath = Laya.URL.getPath(url);
  1175. let bufferUrls = [];
  1176. let textureUrls = [];
  1177. let subUrls = [];
  1178. glTFLoader._getglTFInnerUrls(glTFData, bufferUrls, textureUrls, subUrls, urlVersion, glTFBasePath);
  1179. let urlCount = bufferUrls.length + textureUrls.length;
  1180. let totalProcessCount = urlCount + 1;
  1181. let weight = 1 / totalProcessCount;
  1182. glTFLoader._onProcessChange(loader, 0, weight, 1.0);
  1183. let processCeil = urlCount / totalProcessCount;
  1184. if (bufferUrls.length > 0) {
  1185. let processHandler = Laya.Handler.create(null, glTFLoader._onProcessChange, [loader, weight, processCeil], false);
  1186. glTFLoader._innerBufferLoaderManager._create(bufferUrls, false, Laya.Handler.create(null, glTFLoader._onglTFBufferResourceLoaded, [loader, processHandler, glTFData, subUrls, textureUrls, weight + processCeil * bufferUrls.length, processCeil]), processHandler, null, null, null, 1, true);
  1187. }
  1188. else {
  1189. glTFLoader._onglTFBufferResourceLoaded(loader, null, glTFData, subUrls, textureUrls, weight, processCeil);
  1190. }
  1191. }
  1192. static _onglTFBufferResourceLoaded(loader, processHandler, glTFData, subUrls, textureUrls, processOffset, processCeil) {
  1193. (processHandler) && (processHandler.recover());
  1194. if (textureUrls.length > 0) {
  1195. let process = Laya.Handler.create(null, glTFLoader._onProcessChange, [loader, processOffset, processCeil], false);
  1196. glTFLoader._innerTextureLoaderManager._create(textureUrls, false, Laya.Handler.create(null, glTFLoader._onglTFTextureResourceLoaded, [loader, process, glTFData, subUrls]), processHandler, null, null, null, 1, true);
  1197. }
  1198. else {
  1199. glTFLoader._onglTFTextureResourceLoaded(loader, processHandler, glTFData, subUrls);
  1200. }
  1201. }
  1202. static _onglTFTextureResourceLoaded(loader, processHandler, glTFData, subUrls) {
  1203. (processHandler) && (processHandler.recover());
  1204. loader._cache = loader._createCache;
  1205. let item = glTFUtils._parse(glTFData, loader._propertyParams, loader._constructParams);
  1206. glTFLoader._endLoad(loader, item, subUrls);
  1207. }
  1208. static _eventLoadManagerError(msg) {
  1209. Laya.Laya.loader.event(Laya.Event.ERROR, msg);
  1210. }
  1211. static _onProcessChange(loader, offset, weight, process) {
  1212. process = offset + process * weight;
  1213. (process < 1.0) && (loader.event(Laya.Event.PROGRESS, process * 2 / 3 + 1 / 3));
  1214. }
  1215. static _endLoad(loader, content = null, subResource = null) {
  1216. if (subResource) {
  1217. for (let i = 0; i < subResource.length; i++) {
  1218. let resource = Laya.Loader.getRes(subResource[i]);
  1219. (resource) && (resource._removeReference());
  1220. }
  1221. }
  1222. loader.endLoad(content);
  1223. }
  1224. }
  1225. glTFLoader.GLTF = "GLTF";
  1226. glTFLoader.GLTFBASE64TEX = "GLTFBASE64TEX";
  1227. glTFLoader._innerBufferLoaderManager = new Laya.LoaderManager();
  1228. glTFLoader._innerTextureLoaderManager = new Laya.LoaderManager();
  1229. exports.glTFBase64Tool = glTFBase64Tool;
  1230. exports.glTFLoader = glTFLoader;
  1231. exports.glTFUtils = glTFUtils;
  1232. }(window.Laya = window.Laya || {}, Laya));