123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- import Logger from "./Logger.js"
- const logger = new Logger('XAvatarLoader')
- export default class XAvatarLoader {
- constructor() {
- this.containers = new Map,
- this.meshes = new Map,
- this.animations = new Map,
- this.aniPath = new Map,
- this.binPath = new Map,
- this.texPath = new Map,
- this.matPath = new Map,
- this.mshPath = new Map,
- this.rootPath = new Map,
- this.meshTexList = new Map,
- this._enableIdb = !0,
- this._mappings = new Map,
- this._sharedTex = new Map,
- this.avaliableAnimation = new Map,
- this.enableShareTexture = !0,
- this.enableShareAnimation = !0,
- this.fillEmptyLod = !0,
- this.pendantMap = new Map;
- const e = new BABYLON.GLTFFileLoader;
- BABYLON.SceneLoader.RegisterPlugin(e),
- e.preprocessUrlAsync = function(i) {
- const o = avatarLoader._mappings.get(i);
- return o ? Promise.resolve(o) : Promise.resolve(i)
- }
- }
- _parsePendant(e, i) {
- if (!e || !i) {
- logger.error("[Engine] invalid id or url when loading pendant");
- return
- }
- const o = ".zip"
- , s = i.replace(o, "/");
- this.pendantMap.set(e, s)
- }
- pullAndLoadXObject(e, i) {
- const o = avatarLoader.pendantMap.get(i);
- return Tools.LoadFileAsync(o + `${i}.json`, !1).then(s=>{
- if (!(s instanceof ArrayBuffer))
- return LoadXObject(o, s).then(c=>c)
- }
- )
- }
- getParsedUrl(e, i, o, s="") {
- return new Promise((c,d)=>{
- if (!o || o.indexOf(".zip") === -1)
- return c(o);
- const _ = this.rootPath.get(o);
- if (_)
- return c(_);
- {
- const b = ".zip"
- , k = o.replace(b, "") + COMPONENT_LIST_PREFIX;
- e.urlTransformer(k, !0).then(j=>{
- if (!j)
- return d("Loading Failed");
- new Response(j).json().then($=>{
- var tt, rt, it, nt, ot, at, st;
- const _e = o.replace(b, "")
- , et = _e + ((tt = $ == null ? void 0 : $.components) == null ? void 0 : tt.url.replace("./", ""));
- if (this.rootPath.set(o, et),
- $.components ? ($.components.url && this.mshPath.set(i, _e + "/" + ((rt = $ == null ? void 0 : $.components) == null ? void 0 : rt.url.replace("./", ""))),
- $.components.url_lod2 && this.mshPath.set(i + "_" + avatarSetting.lod[1].level, _e + "/" + ((it = $ == null ? void 0 : $.components) == null ? void 0 : it.url_lod2.replace("./", ""))),
- $.components.url_lod4 && this.mshPath.set(i + "_" + avatarSetting.lod[2].level, _e + "/" + ((nt = $ == null ? void 0 : $.components) == null ? void 0 : nt.url_lod4.replace("./", "")))) : ($.meshes.url && this.mshPath.set(i, _e + "/" + ((ot = $ == null ? void 0 : $.meshes) == null ? void 0 : ot.url.replace("./", ""))),
- $.meshes.url_lod2 && this.mshPath.set(i + "_" + avatarSetting.lod[1].level, _e + "/" + ((at = $ == null ? void 0 : $.meshes) == null ? void 0 : at.url_lod2.replace("./", ""))),
- $.meshes.url_lod4 && this.mshPath.set(i + "_" + avatarSetting.lod[2].level, _e + "/" + ((st = $ == null ? void 0 : $.meshes) == null ? void 0 : st.url_lod4.replace("./", "")))),
- $.materials && $.materials.forEach(ut=>{
- const ct = _e + "/" + ut.url;
- this.matPath.set(ut.name, ct)
- }
- ),
- $.bin) {
- const ut = _e + "/" + $.bin.url;
- this.binPath.set(i, ut);
- const ct = _e + "/" + $.bin.url_lod2;
- this.binPath.set(i + "_" + avatarSetting.lod[1].level, ct);
- const lt = _e + "/" + $.bin.url_lod4;
- this.binPath.set(i + "_" + avatarSetting.lod[2].level, lt)
- }
- return $.textures && $.textures.forEach(ut=>{
- const ct = _e + "/" + ut.url;
- this.texPath.set(ut.url, ct);
- const lt = this.meshTexList.get($.components.url);
- ut.type === "png" && (lt ? lt.find(ft=>ft === ut.name) || lt.push(ut.url) : this.meshTexList.set(i, [ut.name]))
- }
- ),
- c(et)
- }
- ).catch($=>{
- d(`[Engine] parse json file error,${$}`)
- }
- )
- }
- ).catch(j=>{
- d(`[Engine] ulrtransform error, cannot find resource in db,${j}`)
- }
- )
- }
- }
- )
- }
- async parse(e, i) {
- const o = [];
- i.forEach(s=>{
- this._setAnimationList(s.id, s.animations),
- o.push(this.getParsedUrl(e, s.id, s.url)),
- s.components.forEach(c=>{
- c.name === "pendant" ? c.units.forEach(d=>{
- this._parsePendant(d.id, d.url)
- }
- ) : c.units.forEach(d=>{
- o.push(this.getParsedUrl(e, d.name, d.url))
- }
- )
- }
- )
- }
- ),
- await Promise.all(o)
- }
- _setAnimationList(e, i) {
- i ? i.forEach(o=>{
- this.aniPath.set(e + "_" + o.name, o.url)
- }
- ) : logger.error("[Engine] no animation list exist, please check config for details")
- }
- disposeContainer() {
- const e = [];
- this.containers.forEach((i,o)=>{
- if (i.xReferenceCount < 1) {
- if (this.enableShareTexture && i.textures.length > 0) {
- for (let s = 0; s < i.textures.length; ++s)
- i.textures[s].xReferenceCount != null ? i.textures[s].xReferenceCount-- : i.textures[s].xReferenceCount = 0,
- i.textures[s]._parentContainer = null;
- i.textures = []
- }
- e.push(o)
- }
- }
- ),
- e.forEach(i=>{
- var o, s;
- (o = this.containers.get(i)) == null || o.removeAllFromScene(),
- (s = this.containers.get(i)) == null || s.dispose(),
- this.containers.delete(i)
- }
- ),
- this._sharedTex.forEach((i,o)=>{
- i.xReferenceCount == 0 && (i.dispose(),
- this._sharedTex.delete(o))
- }
- )
- }
- set enableIdb(e) {
- this._enableIdb = e
- }
- getGlbPath(e) {
- return this.aniPath.get(e + ".glb")
- }
- getGltfPath(e) {
- return this.mshPath.get(e + ".gltf")
- }
- getPngUrl(e) {
- return this.texPath.get(e + ".png")
- }
- getMeshUrl(e) {
- return this.mshPath.get(e)
- }
- _getSourceKey(e, i) {
- return i && avatarSetting.lod[i] ? e + avatarSetting.lod[i].fileName.split(".")[0] : e
- }
- _getAnimPath(e, i) {
- let o = this.aniPath.get(i + "_animations_" + i.split("_")[1]);
- return o || (o = this.aniPath.get(i + "_" + e)),
- o
- }
- load(e, i, o, s) {
- return this.loadGlb(e, i, o).then(c=>c || Promise.reject("[Engine] container load failed")).catch(()=>Promise.reject("[Engine] container load failed"))
- }
- _searchAnimation(e, i) {
- let o;
- return this.containers.forEach((s,c)=>{
- const d = i.split("_")[0];
- c.indexOf(d) != -1 && c.indexOf(e) != -1 && (o = s)
- }
- ),
- o
- }
- loadAnimRes(e, i, o) {
- const s = this._getAnimPath(i, o)
- , c = getAnimationKey(i, o);
- return s && this.containers.get(s) ? Promise.resolve(this.containers.get(s)) : s ? this._loadGlbFromBlob(e, c, s).then(d=>d.animationGroups.length == 0 ? (this.containers.delete(c),
- d.dispose(),
- Promise.reject("container does not contains animation data")) : d) : Promise.reject("no such url")
- }
- loadGlb(e, i, o) {
- let s = this.getMeshUrl(this._getSourceKey(i, o));
- return !s && this.fillEmptyLod && (o = 0,
- s = this.getMeshUrl(this._getSourceKey(i, o))),
- s && this.containers.get(s) ? Promise.resolve(this.containers.get(s)) : s ? this._enableIdb ? this._loadGlbFromBlob(e, this._getSourceKey(i, o), s) : this._loadGlbFromUrl(e, this._getSourceKey(i, o), s) : Promise.reject("no such url")
- }
- loadGltf(e, i, o, s) {
- const c = this._getSourceKey(i, o || 0);
- let d = this.getGltfPath(c);
- return !d && this.fillEmptyLod && (d = this.getGltfPath(i)),
- d && this.containers.get(d) ? Promise.resolve(this.containers.get(d)) : this._enableIdb ? this._loadGltfFromBlob(e, i, o, s) : d ? this._loadGltfFromUrl(e, i, d.replace(i + ".gltf", "")) : Promise.reject()
- }
- loadSubsequence() {}
- loadVAT() {}
- getResourceName(e) {
- return this.meshTexList.get(e)
- }
- _loadGltfFromUrl(e, i, o) {
- return BABYLON.SceneLoader.LoadAssetContainerAsync(o, i + ".gltf", e.Scene, null, ".gltf")
- }
- _loadGlbFromBlob(e, i, o) {
- return e.urlTransformer(o).then(s=>BABYLON.SceneLoader.LoadAssetContainerAsync("", s, e.Scene, null, ".glb").then(c=>{
- if (c) {
- if (this.containers.get(o))
- return c.dispose(),
- this.containers.get(o);
- if (c.addAllToScene(),
- this.enableShareTexture && c.textures.length > 0) {
- const d = [];
- let _ = !1;
- c.meshes.forEach(b=>{
- if (b.material) {
- const k = b.material._albedoTexture;
- if (k) {
- let j = k.name;
- j = j.replace(" (Base Color)", "").split(".")[0];
- const $ = this._sharedTex.get(j);
- $ ? (_ = !0,
- b.material._albedoTexture = $,
- d.push($),
- $._parentContainer = c,
- $.xReferenceCount++) : (this._sharedTex.set(j, k),
- c.textures[0].xReferenceCount = 1)
- }
- }
- }
- ),
- _ && (c.textures.forEach(b=>{
- e.Scene.removeTexture(b),
- b.dispose()
- }
- ),
- c.textures = d)
- }
- return c.xReferenceCount = 0,
- c.meshes.forEach(d=>{
- d.setEnabled(!1)
- }
- ),
- this.containers.set(o, c),
- Promise.resolve(c)
- } else
- return Promise.reject("glb file load failed")
- }
- ))
- }
- _loadGlbFromUrl(e, i, o) {
- return BABYLON.SceneLoader.LoadAssetContainerAsync("", o, e.Scene, null, ".glb").then(s=>s ? (s.addAllToScene(),
- s.meshes.forEach(c=>{
- c.setEnabled(!1)
- }
- ),
- this.enableShareTexture && s.textures.length > 0 ? (s.meshes.forEach(c=>{
- if (c.material) {
- const d = c.material._albedoTexture;
- if (d) {
- let _ = d.name;
- _ = _.replace(" (Base Color)", "").split(".")[0];
- const b = this._sharedTex.get(_);
- b ? (c.material._albedoTexture = b,
- b.xReferenceCount++) : (this._sharedTex.set(_, d),
- s.textures[0].xReferenceCount = 1)
- }
- }
- }
- ),
- s.xReferenceCount = 0,
- this.containers.set(o, s),
- Promise.resolve(s)) : Promise.reject("glb file load failed"),
- s.xReferenceCount = 0,
- this.containers.set(o, s),
- Promise.resolve(s)) : Promise.reject("glb file load failed"))
- }
- _loadGltfFromBlob(e, i, o, s) {
- return new Promise((c,d)=>{
- const _ = [];
- let b = this._getSourceKey(i, o)
- , k = this.getGltfPath(b);
- if (!k && this.fillEmptyLod && (o = 0,
- b = this._getSourceKey(i, o),
- k = this.getGltfPath(b)),
- !k)
- return d(`[Engine] gltf path incorrect ${b},cancel.`);
- const j = this.mshPath.get(b + ".gltf");
- if (!j)
- return d("cannot find asset mshPath");
- const $ = this.binPath.get(b + ".bin");
- if (!$)
- return d("cannot find asset binPath");
- if (!s) {
- const tt = this.meshTexList.get(i);
- if (!tt || tt.length == 0)
- return d("cannot find texture");
- s = tt[0]
- }
- const _e = this.texPath.get(s + ".png");
- if (!_e)
- return d();
- const et = this.texPath.get(s + "-astc.ktx");
- if (!et)
- return d();
- _.push(this._blobMapping(e, j)),
- _.push(this._blobMapping(e, $)),
- _.push(this._blobMapping(e, _e)),
- _.push(this._blobMapping(e, et)),
- Promise.all(_).then(()=>{
- const tt = k.replace(b + ".gltf", "");
- BABYLON.SceneLoader.LoadAssetContainerAsync(tt, b + ".gltf", e.Scene, null, ".gltf").then(rt=>{
- var nt;
- this.containers.set(k, rt),
- rt.addAllToScene(),
- rt.meshes.forEach(ot=>{
- ot.setEnabled(!1)
- }
- );
- const it = this._sharedTex.get(i);
- it ? ((nt = rt.meshes[1].material._albedoTexture) == null || nt.dispose(),
- rt.meshes[1].material._albedoTexture = it) : this._sharedTex.set(i, rt.meshes[1].material._albedoTexture),
- c(rt)
- }
- )
- }
- )
- }
- )
- }
- _blobMapping(e, i) {
- return new Promise((o,s)=>{
- e.urlTransformer(i).then(c=>c ? (this._mappings.set(i, c),
- o(i)) : s(`[Engine] url urlTransformer parse error ${i}`))
- }
- )
- }
- }
- const avatarLoader = new XAvatarLoader();
- export { avatarLoader };
|