XAvatarLoader.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. export default class XAvatarLoader {
  2. constructor() {
  3. E(this, "containers", new Map);
  4. E(this, "meshes", new Map);
  5. E(this, "animations", new Map);
  6. E(this, "aniPath", new Map);
  7. E(this, "binPath", new Map);
  8. E(this, "texPath", new Map);
  9. E(this, "matPath", new Map);
  10. E(this, "mshPath", new Map);
  11. E(this, "rootPath", new Map);
  12. E(this, "meshTexList", new Map);
  13. E(this, "_enableIdb", !0);
  14. E(this, "_mappings", new Map);
  15. E(this, "_sharedTex", new Map);
  16. E(this, "avaliableAnimation", new Map);
  17. E(this, "enableShareTexture", !0);
  18. E(this, "enableShareAnimation", !0);
  19. E(this, "fillEmptyLod", !0);
  20. const e = new BABYLON.GLTFFileLoader;
  21. BABYLON.SceneLoader.RegisterPlugin(e),
  22. e.preprocessUrlAsync = function(t) {
  23. const r = avatarLoader._mappings.get(t);
  24. return r ? Promise.resolve(r) : Promise.resolve(t)
  25. }
  26. }
  27. getParsedUrl(e, t, r, n="") {
  28. return new Promise((o,a)=>{
  29. if (!r || r.indexOf(".zip") === -1)
  30. return o(r);
  31. const s = this.rootPath.get(r);
  32. if (s)
  33. return o(s);
  34. {
  35. const l = ".zip"
  36. , u = r.replace(l, "") + COMPONENT_LIST_PREFIX;
  37. e.urlTransformer(u, !0).then(c=>{
  38. if (!c)
  39. return a("Loading Failed");
  40. new Response(c).json().then(h=>{
  41. var _, g, m, v, y, b, T;
  42. const f = r.replace(l, "")
  43. , d = f + ((_ = h == null ? void 0 : h.components) == null ? void 0 : _.url.replace("./", ""));
  44. if (this.rootPath.set(r, d),
  45. h.components ? (h.components.url && this.mshPath.set(t, f + "/" + ((g = h == null ? void 0 : h.components) == null ? void 0 : g.url.replace("./", ""))),
  46. h.components.url_lod2 && this.mshPath.set(t + "_" + avatarSetting.lod[1].level, f + "/" + ((m = h == null ? void 0 : h.components) == null ? void 0 : m.url_lod2.replace("./", ""))),
  47. h.components.url_lod4 && this.mshPath.set(t + "_" + avatarSetting.lod[2].level, f + "/" + ((v = h == null ? void 0 : h.components) == null ? void 0 : v.url_lod4.replace("./", "")))) : (h.meshes.url && this.mshPath.set(t, f + "/" + ((y = h == null ? void 0 : h.meshes) == null ? void 0 : y.url.replace("./", ""))),
  48. h.meshes.url_lod2 && this.mshPath.set(t + "_" + avatarSetting.lod[1].level, f + "/" + ((b = h == null ? void 0 : h.meshes) == null ? void 0 : b.url_lod2.replace("./", ""))),
  49. h.meshes.url_lod4 && this.mshPath.set(t + "_" + avatarSetting.lod[2].level, f + "/" + ((T = h == null ? void 0 : h.meshes) == null ? void 0 : T.url_lod4.replace("./", "")))),
  50. h.materials && h.materials.forEach(C=>{
  51. const A = f + "/" + C.url;
  52. this.matPath.set(C.name, A)
  53. }
  54. ),
  55. h.bin) {
  56. const C = f + "/" + h.bin.url;
  57. this.binPath.set(t, C);
  58. const A = f + "/" + h.bin.url_lod2;
  59. this.binPath.set(t + "_" + avatarSetting.lod[1].level, A);
  60. const S = f + "/" + h.bin.url_lod4;
  61. this.binPath.set(t + "_" + avatarSetting.lod[2].level, S)
  62. }
  63. return h.textures && h.textures.forEach(C=>{
  64. const A = f + "/" + C.url;
  65. this.texPath.set(C.url, A);
  66. const S = this.meshTexList.get(h.components.url);
  67. C.type === "png" && (S ? S.find(P=>P === C.name) || S.push(C.url) : this.meshTexList.set(t, [C.name]))
  68. }
  69. ),
  70. o(d)
  71. }
  72. ).catch(h=>{
  73. logger.error(`[Engine] parse json file error,${h}`)
  74. }
  75. )
  76. }
  77. ).catch(c=>{
  78. logger.error(`[Engine] ulrtransform error, cannot find resource in db,${c}`)
  79. }
  80. )
  81. }
  82. }
  83. )
  84. }
  85. async parse(e, t) {
  86. const r = [];
  87. t.forEach(n=>{
  88. this._setAnimationList(n.id, n.animations),
  89. r.push(this.getParsedUrl(e, n.id, n.url)),
  90. n.components.forEach(o=>{
  91. o.units.forEach(a=>{
  92. r.push(this.getParsedUrl(e, a.name, a.url))
  93. }
  94. )
  95. }
  96. )
  97. }
  98. ),
  99. await Promise.all(r)
  100. }
  101. _setAnimationList(e, t) {
  102. t ? t.forEach(r=>{
  103. this.aniPath.set(e + "_" + r.name, r.url)
  104. }
  105. ) : logger.error("[Engine] no animation list exist, please check config for details")
  106. }
  107. disposeContainer() {
  108. this.containers.forEach((e,t)=>{
  109. e.xReferenceCount < 1 && (this.enableShareTexture && e.textures.length > 0 && e.textures[0].xReferenceCount != null && (e.textures[0].xReferenceCount--,
  110. e.textures = []),
  111. e.dispose(),
  112. this.containers.delete(t))
  113. }
  114. ),
  115. this._sharedTex.forEach((e,t)=>{
  116. e.xReferenceCount == 0 && (e.dispose(),
  117. this._sharedTex.delete(t))
  118. }
  119. )
  120. }
  121. set enableIdb(e) {
  122. this._enableIdb = e
  123. }
  124. getGlbPath(e) {
  125. return this.aniPath.get(e + ".glb")
  126. }
  127. getGltfPath(e) {
  128. return this.mshPath.get(e + ".gltf")
  129. }
  130. getPngUrl(e) {
  131. return this.texPath.get(e + ".png")
  132. }
  133. getMeshUrl(e) {
  134. return this.mshPath.get(e)
  135. }
  136. _getSourceKey(e, t) {
  137. return t && avatarSetting.lod[t] ? e + avatarSetting.lod[t].fileName.split(".")[0] : e
  138. }
  139. _getAnimPath(e, t) {
  140. let r = this.aniPath.get(t + "_animations_" + t.split("_")[1]);
  141. return r || (r = this.aniPath.get(t + "_" + e)),
  142. r
  143. }
  144. load(e, t, r, n) {
  145. return new Promise((o,a)=>{
  146. this.loadGlb(e, t, r).then(s=>s ? o(s) : a("[Engine] container load failed")).catch(()=>a("[Engine] container load failed"))
  147. }
  148. )
  149. }
  150. _searchAnimation(e, t) {
  151. let r;
  152. return this.containers.forEach((n,o)=>{
  153. const a = t.split("_")[0];
  154. o.indexOf(a) != -1 && o.indexOf(e) != -1 && (r = n)
  155. }
  156. ),
  157. r
  158. }
  159. loadAnimRes(e, t, r) {
  160. return new Promise((n,o)=>{
  161. const a = this._getAnimPath(t, r)
  162. , s = getAnimationKey(t, r);
  163. if (a && this.containers.get(a))
  164. return n(this.containers.get(a));
  165. if (a)
  166. this._loadGlbFromBlob(e, s, a).then(l=>l.animationGroups.length == 0 ? (this.containers.delete(s),
  167. l.dispose(),
  168. Promise.reject("container does not contains animation data")) : n(l));
  169. else
  170. return o("no such url")
  171. }
  172. )
  173. }
  174. loadGlb(e, t, r) {
  175. let n = this.getMeshUrl(this._getSourceKey(t, r));
  176. return !n && this.fillEmptyLod && (r = 0,
  177. n = this.getMeshUrl(this._getSourceKey(t, r))),
  178. n && this.containers.get(n) ? Promise.resolve(this.containers.get(n)) : n ? this._enableIdb ? Promise.resolve(this._loadGlbFromBlob(e, this._getSourceKey(t, r), n)) : Promise.resolve(this._loadGlbFromUrl(e, this._getSourceKey(t, r), n)) : Promise.reject("no such url")
  179. }
  180. loadGltf(e, t, r, n) {
  181. const o = this._getSourceKey(t, r || 0);
  182. let a = this.getGltfPath(o);
  183. return !a && this.fillEmptyLod && (a = this.getGltfPath(t)),
  184. a && this.containers.get(a) ? Promise.resolve(this.containers.get(a)) : this._enableIdb ? this._loadGltfFromBlob(e, t, r, n) : a ? this._loadGltfFromUrl(e, t, a.replace(t + ".gltf", "")) : Promise.reject()
  185. }
  186. loadSubsequence() {}
  187. loadVAT() {}
  188. getResourceName(e) {
  189. return this.meshTexList.get(e)
  190. }
  191. _loadGltfFromUrl(e, t, r) {
  192. return BABYLON.SceneLoader.LoadAssetContainerAsync(r, t + ".gltf", e.Scene, null, ".gltf")
  193. }
  194. _loadGlbFromBlob(e, t, r) {
  195. return new Promise((n,o)=>{
  196. e.urlTransformer(r).then(a=>{
  197. BABYLON.SceneLoader.LoadAssetContainerAsync("", a, e.Scene, null, ".glb").then(s=>{
  198. if (s) {
  199. if (this.enableShareTexture && s.textures.length > 0) {
  200. const l = t.indexOf("_lod") != -1 ? t.slice(0, -5) : t
  201. , u = this._sharedTex.get(l);
  202. u ? (s.meshes[1].material._albedoTexture = u,
  203. s.textures.forEach(c=>{
  204. c.dispose()
  205. }
  206. ),
  207. s.textures = [u],
  208. u.xReferenceCount++) : (this._sharedTex.set(l, s.textures[0]),
  209. s.textures[0].xReferenceCount = 1)
  210. }
  211. return s.addAllToScene(),
  212. s.xReferenceCount = 0,
  213. s.meshes.forEach(l=>{
  214. l.setEnabled(!1)
  215. }
  216. ),
  217. this.containers.set(r, s),
  218. n(s)
  219. } else
  220. o("glb file load failed")
  221. }
  222. )
  223. }
  224. )
  225. }
  226. )
  227. }
  228. _loadGlbFromUrl(e, t, r) {
  229. return new Promise((n,o)=>{
  230. BABYLON.SceneLoader.LoadAssetContainerAsync("", r, e.Scene, null, ".glb").then(a=>{
  231. if (a) {
  232. if (a.addAllToScene(),
  233. a.meshes.forEach(s=>{
  234. s.setEnabled(!1)
  235. }
  236. ),
  237. this.enableShareTexture && a.textures.length > 0) {
  238. const s = t.indexOf("_lod") != -1 ? t.slice(0, -5) : t
  239. , l = this._sharedTex.get(s);
  240. l ? (a.meshes[1].material._albedoTexture = l,
  241. a.textures.forEach(u=>{
  242. u.dispose()
  243. }
  244. ),
  245. a.textures = [l],
  246. l.xReferenceCount++) : (this._sharedTex.set(s, a.textures[0]),
  247. a.textures[0].xReferenceCount = 1)
  248. }
  249. return a.xReferenceCount = 0,
  250. this.containers.set(r, a),
  251. n(a)
  252. } else
  253. o("glb file load failed")
  254. }
  255. )
  256. }
  257. )
  258. }
  259. _loadGltfFromBlob(e, t, r, n) {
  260. return new Promise((o,a)=>{
  261. const s = [];
  262. let l = this._getSourceKey(t, r)
  263. , u = this.getGltfPath(l);
  264. if (!u && this.fillEmptyLod && (r = 0,
  265. l = this._getSourceKey(t, r),
  266. u = this.getGltfPath(l)),
  267. !u)
  268. return a(`[Engine] gltf path incorrect ${l},cancel.`);
  269. const c = this.mshPath.get(l + ".gltf");
  270. if (!c)
  271. return a("cannot find asset mshPath");
  272. const h = this.binPath.get(l + ".bin");
  273. if (!h)
  274. return a("cannot find asset binPath");
  275. if (!n) {
  276. const _ = this.meshTexList.get(t);
  277. if (!_ || _.length == 0)
  278. return a("cannot find texture");
  279. n = _[0]
  280. }
  281. const f = this.texPath.get(n + ".png");
  282. if (!f)
  283. return a();
  284. const d = this.texPath.get(n + "-astc.ktx");
  285. if (!d)
  286. return a();
  287. s.push(this._blobMapping(e, c)),
  288. s.push(this._blobMapping(e, h)),
  289. s.push(this._blobMapping(e, f)),
  290. s.push(this._blobMapping(e, d)),
  291. Promise.all(s).then(()=>{
  292. const _ = u.replace(l + ".gltf", "");
  293. BABYLON.SceneLoader.LoadAssetContainerAsync(_, l + ".gltf", e.Scene, null, ".gltf").then(g=>{
  294. var v;
  295. this.containers.set(u, g),
  296. g.addAllToScene(),
  297. g.meshes.forEach(y=>{
  298. y.setEnabled(!1)
  299. }
  300. );
  301. const m = this._sharedTex.get(t);
  302. m ? ((v = g.meshes[1].material._albedoTexture) == null || v.dispose(),
  303. g.meshes[1].material._albedoTexture = m) : this._sharedTex.set(t, g.meshes[1].material._albedoTexture),
  304. o(g)
  305. }
  306. )
  307. }
  308. )
  309. }
  310. )
  311. }
  312. _blobMapping(e, t) {
  313. return new Promise((r,n)=>{
  314. e.urlTransformer(t).then(o=>o ? (this._mappings.set(t, o),
  315. r(t)) : n(`[Engine] url urlTransformer parse error ${t}`))
  316. }
  317. )
  318. }
  319. }
  320. const avatarLoader = new XAvatarLoader();
  321. export { avatarLoader };