|
@@ -0,0 +1,751 @@
|
|
|
+const log$D = new Logger$1("AvatarManager");
|
|
|
+var EAvatarRelationRank = (i=>(i[i.Self = 0] = "Self",
|
|
|
+i[i.Npc = 1] = "Npc",
|
|
|
+i[i.Friend = 2] = "Friend",
|
|
|
+i[i.Stranger = 3] = "Stranger",
|
|
|
+i[i.Robot = 4] = "Robot",
|
|
|
+i[i.Unknown = 5] = "Unknown",
|
|
|
+i))(EAvatarRelationRank || {});
|
|
|
+class XAvatarManager {
|
|
|
+ constructor(e) {
|
|
|
+ E(this, "characterMap", new Map);
|
|
|
+ E(this, "curAnimList", []);
|
|
|
+ E(this, "extraComps", new Map);
|
|
|
+ E(this, "_mainUser");
|
|
|
+ E(this, "_scene");
|
|
|
+ E(this, "_sceneManager");
|
|
|
+ E(this, "_lodSettings");
|
|
|
+ E(this, "maxBillBoardDist", 0);
|
|
|
+ E(this, "maxAvatarNum", 0);
|
|
|
+ E(this, "currentLODUsers", []);
|
|
|
+ E(this, "bboxMeshPool");
|
|
|
+ E(this, "_distLevels", []);
|
|
|
+ E(this, "_maxLODUsers", []);
|
|
|
+ E(this, "_cullingDistance", 0);
|
|
|
+ E(this, "_maxDistRange");
|
|
|
+ E(this, "_delayTime", 100);
|
|
|
+ E(this, "_queueLength", -1);
|
|
|
+ E(this, "_queue", []);
|
|
|
+ E(this, "_processList", []);
|
|
|
+ E(this, "_process");
|
|
|
+ E(this, "_updateLoopObserver");
|
|
|
+ E(this, "_avatarInDistance", []);
|
|
|
+ E(this, "_renderedAvatar", []);
|
|
|
+ E(this, "_enableNickname", !0);
|
|
|
+ E(this, "_tickObserver");
|
|
|
+ E(this, "_tickInterval");
|
|
|
+ E(this, "_defaultAnims");
|
|
|
+ E(this, "_tickDispose", 0);
|
|
|
+ E(this, "_disposeTime", 100);
|
|
|
+ E(this, "avatarLoader", avatarLoader);
|
|
|
+ this._scene = e.mainScene,
|
|
|
+ this._sceneManager = e,
|
|
|
+ this.initAvatarMap(),
|
|
|
+ this._initSettings(),
|
|
|
+ this._maxDistRange = this._distLevels[this._distLevels.length - 1],
|
|
|
+ this.bboxMeshPool = new Pool(this.createBboxAsset,this.resetBboxAsset,0,this.maxAvatarNum,this._sceneManager.Scene,0,0,0),
|
|
|
+ this._tickInterval = 250;
|
|
|
+ let t = 0;
|
|
|
+ this._tickObserver = this._scene.onAfterRenderObservable.add(()=>{
|
|
|
+ t += 1,
|
|
|
+ t == this._tickInterval && (this.tick(),
|
|
|
+ t = 0)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ tick() {
|
|
|
+ this.bboxMeshPool.clean(0)
|
|
|
+ }
|
|
|
+ createBboxAsset(e, t, r, n) {
|
|
|
+ return MeshBuilder.CreateBox("avatarBbox", {
|
|
|
+ width: t,
|
|
|
+ height: r,
|
|
|
+ depth: n
|
|
|
+ }, e)
|
|
|
+ }
|
|
|
+ resetBboxAsset(e) {
|
|
|
+ const t = e.data;
|
|
|
+ return t.setEnabled(!1),
|
|
|
+ t.isPickable = !1,
|
|
|
+ e
|
|
|
+ }
|
|
|
+ _initSettings() {
|
|
|
+ this._defaultAnims = avatarSetting.defaultIdle,
|
|
|
+ this._lodSettings = avatarSetting.lod,
|
|
|
+ this._distLevels = avatarSetting.lod.map(e=>e.dist),
|
|
|
+ this._maxLODUsers = avatarSetting.lod.map(e=>e.quota),
|
|
|
+ this.currentLODUsers = new Array(this._distLevels.length).fill(0),
|
|
|
+ this.maxAvatarNum = avatarSetting.maxAvatarNum,
|
|
|
+ this.maxBillBoardDist = avatarSetting.maxBillBoardDist,
|
|
|
+ this._cullingDistance = avatarSetting.cullingDistance
|
|
|
+ }
|
|
|
+ maxRenderNum() {
|
|
|
+ let e = 0;
|
|
|
+ return this._maxLODUsers.forEach(t=>{
|
|
|
+ e += t
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e
|
|
|
+ }
|
|
|
+ curRenderNum() {
|
|
|
+ let e = 0;
|
|
|
+ return this.currentLODUsers.forEach(t=>{
|
|
|
+ e += t
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e
|
|
|
+ }
|
|
|
+ setLoDLevels(e) {
|
|
|
+ this._distLevels = e
|
|
|
+ }
|
|
|
+ set cullingDistance(e) {
|
|
|
+ this._cullingDistance = e
|
|
|
+ }
|
|
|
+ get cullingDistance() {
|
|
|
+ return this._cullingDistance
|
|
|
+ }
|
|
|
+ getLoDLevels() {
|
|
|
+ return this._distLevels
|
|
|
+ }
|
|
|
+ setLodUserLimits(e, t) {
|
|
|
+ this._maxLODUsers.length > e && (this._maxLODUsers[e] = t)
|
|
|
+ }
|
|
|
+ setLodDist(e, t) {
|
|
|
+ this._distLevels[e] = t
|
|
|
+ }
|
|
|
+ setMaxDistRange(e) {
|
|
|
+ this._maxDistRange = e,
|
|
|
+ this._distLevels[this._distLevels.length - 1] = e
|
|
|
+ }
|
|
|
+ get scene() {
|
|
|
+ return this._scene
|
|
|
+ }
|
|
|
+ setMainAvatar(e) {
|
|
|
+ var t;
|
|
|
+ this._mainUser = (t = this.characterMap.get(0)) == null ? void 0 : t.get(e)
|
|
|
+ }
|
|
|
+ getMainAvatar() {
|
|
|
+ return this._mainUser
|
|
|
+ }
|
|
|
+ enableAllNickname(e) {
|
|
|
+ return this.characterMap.forEach((t,r)=>{
|
|
|
+ r != 0 && t.forEach((n,o)=>{
|
|
|
+ this._updateBillboardStatus(n, e ? BillboardStatus.SHOW : BillboardStatus.HIDE)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ this._enableNickname = e
|
|
|
+ }
|
|
|
+ getAvatarById(e) {
|
|
|
+ let t;
|
|
|
+ return this.characterMap.forEach((r,n)=>{
|
|
|
+ r.get(e) && (t = r.get(e))
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ t
|
|
|
+ }
|
|
|
+ getAvatarNums() {
|
|
|
+ let e = 0;
|
|
|
+ return this.characterMap.forEach((t,r)=>{
|
|
|
+ e += t.size
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e
|
|
|
+ }
|
|
|
+ registerAvatar(e) {
|
|
|
+ this.characterMap.get(e.priority).set(e.id, e)
|
|
|
+ }
|
|
|
+ unregisterAvatar(e) {
|
|
|
+ this.characterMap.get(e.priority).delete(e.id)
|
|
|
+ }
|
|
|
+ initAvatarMap() {
|
|
|
+ this.characterMap.set(0, new Map),
|
|
|
+ this.characterMap.set(1, new Map),
|
|
|
+ this.characterMap.set(2, new Map),
|
|
|
+ this.characterMap.set(3, new Map),
|
|
|
+ this.characterMap.set(4, new Map),
|
|
|
+ this.characterMap.set(5, new Map)
|
|
|
+ }
|
|
|
+ loadAvatar({id: e, avatarType: t, priority: r, avatarManager: n, assets: o, status: a}) {
|
|
|
+ return new Promise((s,l)=>{
|
|
|
+ if (this.getAvatarById(e))
|
|
|
+ return l(new DuplicateAvatarIDError(`[Engine] cannot init avatar with the same id = ${e}`));
|
|
|
+ if (this.getAvatarNums() > this.maxAvatarNum)
|
|
|
+ return l(new ExceedMaxAvatarNumError(`[Engine] \u8D85\u51FA\u6700\u5927\u89D2\u8272\u9650\u5236 ${this.maxAvatarNum}`));
|
|
|
+ const u = new XAvatar({
|
|
|
+ id: e,
|
|
|
+ avatarType: t,
|
|
|
+ priority: r,
|
|
|
+ avatarManager: n,
|
|
|
+ assets: o,
|
|
|
+ status: a
|
|
|
+ });
|
|
|
+ if (this.registerAvatar(u),
|
|
|
+ r == 0)
|
|
|
+ this.setMainAvatar(u.id),
|
|
|
+ this.addAvatarToScene(u, 0).then(c=>(log$D.debug(`[Engine] avatar ${u.id} has been added to scene`),
|
|
|
+ c ? (this._updateBillboardStatus(c, BillboardStatus.SHOW),
|
|
|
+ setTimeout(()=>{
|
|
|
+ this.launchProcessLoadingLoop()
|
|
|
+ }
|
|
|
+ , this._delayTime),
|
|
|
+ s(c)) : (u.removeAvatarFromScene(),
|
|
|
+ l(new AvatarAssetLoadingError)))).catch(c=>(u.removeAvatarFromScene(),
|
|
|
+ l(new AvatarAssetLoadingError(c))));
|
|
|
+ else
|
|
|
+ return s(u)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ deleteAvatar(e) {
|
|
|
+ return e.isRender ? (e.removeAvatarFromScene(),
|
|
|
+ this.currentLODUsers[e.distLevel]--) : e.bbComponent.disposeBillBoard(e),
|
|
|
+ this._processList = this._processList.filter(t=>t.id !== e.id),
|
|
|
+ this.unregisterAvatar(e),
|
|
|
+ e.rootNode && (e.rootNode.dispose(),
|
|
|
+ e.rootNode = void 0),
|
|
|
+ e.bbComponent.bbox && e.bbComponent.bbox.dispose(),
|
|
|
+ e.removeObserver(),
|
|
|
+ e
|
|
|
+ }
|
|
|
+ _checkLODLevel(e) {
|
|
|
+ if (e < this._distLevels[0])
|
|
|
+ return 0;
|
|
|
+ for (let t = 1; t < this._distLevels.length; ++t)
|
|
|
+ if (e >= this._distLevels[t - 1] && e < this._distLevels[t])
|
|
|
+ return t;
|
|
|
+ return this._distLevels.length - 1
|
|
|
+ }
|
|
|
+ get sceneManager() {
|
|
|
+ return this._sceneManager
|
|
|
+ }
|
|
|
+ launchProcessLoadingLoop() {
|
|
|
+ this._updateAvatarStatus()
|
|
|
+ }
|
|
|
+ stopProcessLoadingLoop() {
|
|
|
+ var e;
|
|
|
+ this._updateLoopObserver && ((e = this._scene) == null || e.onBeforeRenderObservable.remove(this._updateLoopObserver))
|
|
|
+ }
|
|
|
+ _distToMain(e) {
|
|
|
+ var n;
|
|
|
+ const t = (n = this._mainUser) == null ? void 0 : n.position
|
|
|
+ , r = e.position;
|
|
|
+ if (r && t) {
|
|
|
+ const o = this.sceneManager.cameraComponent.MainCamera.getFrontPosition(1).subtract(this.sceneManager.cameraComponent.MainCamera.position).normalize()
|
|
|
+ , a = e.rootNode.position.subtract(this.sceneManager.cameraComponent.MainCamera.position).normalize();
|
|
|
+ let s = 1;
|
|
|
+ if (o && a) {
|
|
|
+ const l = a.multiply(o);
|
|
|
+ s = Math.acos(l.x + l.y + l.z) < this.sceneManager.cameraComponent.MainCamera.fov / 2 ? 1 : 1e11
|
|
|
+ }
|
|
|
+ return calcDistance3D(t, r) * s
|
|
|
+ } else
|
|
|
+ return log$D.warn("user position or camera position is not correct!"),
|
|
|
+ 1e11
|
|
|
+ }
|
|
|
+ _distToCamera(e) {
|
|
|
+ var n;
|
|
|
+ const t = (n = this._sceneManager) == null ? void 0 : n.cameraComponent.getCameraPose().position
|
|
|
+ , r = e.position;
|
|
|
+ return r && t ? calcDistance3D(t, r) : (log$D.warn("user position or camera position is not correct!"),
|
|
|
+ 1e11)
|
|
|
+ }
|
|
|
+ showAll(e) {
|
|
|
+ this.characterMap.forEach((t,r)=>{
|
|
|
+ e && r == 0 && t.forEach((n,o)=>{
|
|
|
+ n.show()
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ r != 0 && t.forEach((n,o)=>{
|
|
|
+ n.show()
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ hideAll(e) {
|
|
|
+ this.characterMap.forEach((t,r)=>{
|
|
|
+ e && r == 0 && t.forEach((n,o)=>{
|
|
|
+ n.hide()
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ r != 0 && t.forEach((n,o)=>{
|
|
|
+ n.hide()
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ _assemblyAvatar(e, t) {
|
|
|
+ var n, o;
|
|
|
+ const r = e.get(avatarSetting.body);
|
|
|
+ if (r && !t.attachBody(r)) {
|
|
|
+ t.isInLoadingList = !1,
|
|
|
+ e.clear();
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for (const a of e)
|
|
|
+ if (a[0] != avatarSetting.body && a[0] != avatarSetting.animations && !t.attachDecoration(a[1])) {
|
|
|
+ t.isInLoadingList = !1,
|
|
|
+ t.removeAvatarFromScene(),
|
|
|
+ e.clear();
|
|
|
+ return
|
|
|
+ }
|
|
|
+ t.isRender = !0,
|
|
|
+ (n = t.controller) == null || n.playAnimation(t.controller.onPlay, t.controller.loop),
|
|
|
+ (o = t.controller) == null || o.onPlayObservable.addOnce(()=>{
|
|
|
+ var a, s;
|
|
|
+ if (!this.getAvatarById(t.id)) {
|
|
|
+ t.isInLoadingList = !1,
|
|
|
+ t.removeAvatarFromScene(),
|
|
|
+ this.currentLODUsers[t.distLevel]--;
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.getAvatarById(t.id).rootNode.getChildMeshes().length < e.size) {
|
|
|
+ log$D.error(`this avatar does not have complete components, render failed. current list ${(a = this.getAvatarById(t.id)) == null ? void 0 : a.clothesList},avatar: ${t.id},${t.nickName}`),
|
|
|
+ t.isInLoadingList = !1,
|
|
|
+ t.removeAvatarFromScene(),
|
|
|
+ this.currentLODUsers[t.distLevel]--;
|
|
|
+ return
|
|
|
+ }
|
|
|
+ t.setIsPickable(!0),
|
|
|
+ t.isInLoadingList = !1,
|
|
|
+ t.setAvatarVisible(!0),
|
|
|
+ (s = this._sceneManager) == null || s.lightComponent.setShadow(t),
|
|
|
+ t.getBbox(),
|
|
|
+ t.nameBoard && t.nickName.length > 0 && t.setNickName(t.nickName, t.nameBoard.DEFAULT_CONFIGS),
|
|
|
+ t.bubble && t.words.length > 0 && t.say(t.words, t.bubble.DEFAULT_CONFIGS),
|
|
|
+ log$D.debug(`[Engine] avatar ${t.id} has been added to scene, current number of users : ${this.currentLODUsers}`)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ _disposeUnusedAssets() {
|
|
|
+ this._tickDispose++,
|
|
|
+ this._tickDispose > this._disposeTime && (avatarLoader.disposeContainer(),
|
|
|
+ this._tickDispose = 0)
|
|
|
+ }
|
|
|
+ _addResourcesToList(e, t) {
|
|
|
+ return e.clothesList.forEach(r=>{
|
|
|
+ r.lod = t,
|
|
|
+ this._queue.push(r)
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ this._queue.push({
|
|
|
+ type: avatarSetting.animations,
|
|
|
+ id: this._defaultAnims
|
|
|
+ }),
|
|
|
+ this._queue.push({
|
|
|
+ type: avatarSetting.body,
|
|
|
+ id: e.avatarType,
|
|
|
+ lod: t
|
|
|
+ }),
|
|
|
+ !0
|
|
|
+ }
|
|
|
+ _updateBillboardStatus(e, t) {
|
|
|
+ e.bbComponent.updateBillboardStatus(e, t)
|
|
|
+ }
|
|
|
+ _processLayer(e) {
|
|
|
+ const t = this.characterMap.get(e)
|
|
|
+ , r = [];
|
|
|
+ for (t == null || t.forEach(n=>{
|
|
|
+ n.distToCam = this._distToCamera(n);
|
|
|
+ const o = n.distToCam < this._cullingDistance;
|
|
|
+ if (n.isRender && (!n.isHide && o ? n._hide_culling() : n._show_culling()),
|
|
|
+ n.priority != 0) {
|
|
|
+ n.distance = this._distToMain(n);
|
|
|
+ let a = BillboardStatus.SHOW;
|
|
|
+ n.distance < this._maxDistRange && (o ? a = BillboardStatus.HIDE : n._show_culling(),
|
|
|
+ this._updateBillboardStatus(n, a)),
|
|
|
+ n.isHide || (n.isInLoadingList ? this.currentLODUsers[n.distLevel]++ : r.push(n))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ r.sort((n,o)=>o.distance - n.distance); r.length > 0 && this.curRenderNum() < this.maxRenderNum(); ) {
|
|
|
+ const n = r.pop();
|
|
|
+ let o = this._checkLODLevel(n.distance)
|
|
|
+ , a = !1;
|
|
|
+ for (let s = 0; s < this._maxLODUsers.length; ++s)
|
|
|
+ if (this.currentLODUsers[s] < this._maxLODUsers[s]) {
|
|
|
+ o = s,
|
|
|
+ a = !0;
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if (!a || n.distance > this._maxDistRange) {
|
|
|
+ if (n.isRender) {
|
|
|
+ n._removeAvatarFromScene();
|
|
|
+ let s = BillboardStatus.HIDE;
|
|
|
+ n.distance < this._maxDistRange && (s = BillboardStatus.SHOW),
|
|
|
+ this._updateBillboardStatus(n, s)
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ o != n.distLevel ? (n.isRender && (n.pendingLod = !0),
|
|
|
+ n.distLevel = o,
|
|
|
+ this._processList.push(n),
|
|
|
+ n.isInLoadingList = !0) : n.isRender || (this._processList.push(n),
|
|
|
+ n.isInLoadingList = !0),
|
|
|
+ this.currentLODUsers[o]++
|
|
|
+ }
|
|
|
+ return this.curRenderNum() >= this.maxRenderNum() && r.forEach(n=>{
|
|
|
+ if (n.isRender) {
|
|
|
+ n._removeAvatarFromScene();
|
|
|
+ let o = BillboardStatus.HIDE;
|
|
|
+ n.distance < this._maxDistRange && (o = BillboardStatus.SHOW),
|
|
|
+ this._updateBillboardStatus(n, o)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ this.curRenderNum() < this.maxRenderNum()
|
|
|
+ }
|
|
|
+ _updateAvatar() {
|
|
|
+ this.currentLODUsers = [0, 0, 0];
|
|
|
+ const e = [5, 4, 3, 2, 1, 0];
|
|
|
+ for (; e.length > 0; ) {
|
|
|
+ const t = e.pop();
|
|
|
+ if (!this._processLayer(t)) {
|
|
|
+ e.forEach(n=>{
|
|
|
+ var o;
|
|
|
+ (o = this.characterMap.get(n)) == null || o.forEach(a=>{
|
|
|
+ a.distance = this._distToMain(a);
|
|
|
+ let s = BillboardStatus.HIDE;
|
|
|
+ a.distToCam < this._maxDistRange && (s = BillboardStatus.SHOW,
|
|
|
+ a.isRender && a._removeAvatarFromScene()),
|
|
|
+ this._updateBillboardStatus(a, s)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ );
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _updateAvatarStatus() {
|
|
|
+ const e = new Map;
|
|
|
+ this._updateLoopObserver = this.scene.onBeforeRenderObservable.add(()=>{
|
|
|
+ var t;
|
|
|
+ if (this._disposeUnusedAssets(),
|
|
|
+ !(this.getAvatarNums() <= 0)) {
|
|
|
+ if (!this._process && this._processList.length == 0 && this._updateAvatar(),
|
|
|
+ !this._process && this._processList.length > 0) {
|
|
|
+ const r = this._processList.shift();
|
|
|
+ r != this._process && !r.isCulling ? this._addResourcesToList(r, r.distLevel) ? (this._process = r,
|
|
|
+ this._queueLength = this._queue.length) : (this._process = void 0,
|
|
|
+ this._queue = [],
|
|
|
+ r.isInLoadingList = !1) : r.isInLoadingList = !1
|
|
|
+ }
|
|
|
+ if (e.size === this._queueLength && this._process) {
|
|
|
+ this._process.pendingLod && (this._process.pendingLod = !1,
|
|
|
+ this._process._removeAvatarFromScene());
|
|
|
+ const r = Date.now();
|
|
|
+ this._assemblyAvatar(e, this._process),
|
|
|
+ (t = this._sceneManager) == null || t.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
|
|
|
+ this._updateBillboardStatus(this._process, BillboardStatus.SHOW),
|
|
|
+ e.clear(),
|
|
|
+ this._queue = [],
|
|
|
+ this._process.isInLoadingList = !1,
|
|
|
+ this._process = void 0,
|
|
|
+ this._disposeUnusedAssets()
|
|
|
+ }
|
|
|
+ this._loadResByList(e)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ _loadResByList(e) {
|
|
|
+ let t = 0;
|
|
|
+ const r = 5;
|
|
|
+ if (!this._process) {
|
|
|
+ e.clear();
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for (; t < r && this._queue.length > 0; ) {
|
|
|
+ const n = Date.now()
|
|
|
+ , o = this._queue.pop();
|
|
|
+ setTimeout(()=>{
|
|
|
+ o ? o.type === avatarSetting.body ? this.loadBody(o.type, o.id, o.lod).then(a=>{
|
|
|
+ a && e.set(avatarSetting.body, a),
|
|
|
+ t += Date.now() - n
|
|
|
+ }
|
|
|
+ ).catch(a=>{
|
|
|
+ this._process && (this._process.isHide = !0,
|
|
|
+ this.currentLODUsers[this._process.distLevel]--,
|
|
|
+ e.clear(),
|
|
|
+ this._queue = [],
|
|
|
+ this._process.isInLoadingList = !1,
|
|
|
+ this._process = void 0,
|
|
|
+ t += 100),
|
|
|
+ log$D.warn(`[Engine] body ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
|
|
|
+ }
|
|
|
+ ) : o.type === avatarSetting.animations ? this.loadAnimation(this._process.avatarType, o.id).then(a=>{
|
|
|
+ a && e.set(avatarSetting.animations, a),
|
|
|
+ t += Date.now() - n
|
|
|
+ }
|
|
|
+ ).catch(a=>{
|
|
|
+ this._process && (this._process.isHide = !0,
|
|
|
+ this.currentLODUsers[this._process.distLevel]--,
|
|
|
+ e.clear(),
|
|
|
+ this._queue = [],
|
|
|
+ this._process.isInLoadingList = !1,
|
|
|
+ this._process = void 0,
|
|
|
+ t += 100),
|
|
|
+ log$D.warn(`animation ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
|
|
|
+ }
|
|
|
+ ) : this.loadDecoration(o.type, o.id, o.lod).then(a=>{
|
|
|
+ a && e.set(a.type, a),
|
|
|
+ t += Date.now() - n
|
|
|
+ }
|
|
|
+ ).catch(a=>{
|
|
|
+ this._process && (this._process.isHide = !0,
|
|
|
+ this.currentLODUsers[this._process.distLevel]--,
|
|
|
+ e.clear(),
|
|
|
+ this._queue = [],
|
|
|
+ this._process.isInLoadingList = !1,
|
|
|
+ this._process = void 0,
|
|
|
+ t += 100),
|
|
|
+ log$D.warn(`component ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
|
|
|
+ }
|
|
|
+ ) : t += 100
|
|
|
+ }
|
|
|
+ , 0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _validateContainer(e) {
|
|
|
+ return !e.meshes || e.meshes.length <= 1 ? (log$D.warn("import container has no valid meshes"),
|
|
|
+ !1) : !e.skeletons || e.skeletons.length == 0 ? (log$D.warn("import container has no valid skeletons"),
|
|
|
+ !1) : !0
|
|
|
+ }
|
|
|
+ _getAssetContainer(e, t) {
|
|
|
+ return new Promise((r,n)=>{
|
|
|
+ const o = this._getSourceKey(e, t || 0)
|
|
|
+ , a = avatarLoader.containers.get(o);
|
|
|
+ if (a)
|
|
|
+ return r(a);
|
|
|
+ avatarLoader.load(this.sceneManager, e, t).then(s=>s ? this._validateContainer(s) ? (avatarLoader.containers.set(o, s),
|
|
|
+ r(s)) : n(new ContainerLoadingFailedError(`[Engine] :: cannot load body type ${e}.`)) : n(new ContainerLoadingFailedError(`[Engine] container load failed cannot load body type ${e}.`))).catch(s=>n(new ContainerLoadingFailedError(`[Engine] ${s} :: cannot load body type ${e}.`)))
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ _clipContainerRes(e) {
|
|
|
+ e.transformNodes.forEach(t=>{
|
|
|
+ t.dispose()
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e.transformNodes = [],
|
|
|
+ e.skeletons.forEach(t=>{
|
|
|
+ t.dispose()
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e.skeletons = []
|
|
|
+ }
|
|
|
+ loadBody(e, t, r) {
|
|
|
+ return new Promise((n,o)=>avatarLoader.load(this.sceneManager, t, r).then(a=>{
|
|
|
+ if (a) {
|
|
|
+ const s = a.instantiateModelsToScene();
|
|
|
+ a.xReferenceCount++;
|
|
|
+ const l = {
|
|
|
+ isRender: !1,
|
|
|
+ uId: Math.random(),
|
|
|
+ root: s.rootNodes[0],
|
|
|
+ skeletonType: e,
|
|
|
+ name: t,
|
|
|
+ animations: s.animationGroups,
|
|
|
+ skeleton: s.skeletons[0],
|
|
|
+ lod: r
|
|
|
+ };
|
|
|
+ return s.rootNodes[0]._parentContainer = a,
|
|
|
+ s.rootNodes[0].setEnabled(!1),
|
|
|
+ n(l)
|
|
|
+ } else
|
|
|
+ return o(new ContainerLoadingFailedError("[Engine] container failed instanciates failed"))
|
|
|
+ }
|
|
|
+ ).catch(()=>o(new ContainerLoadingFailedError(`[Engine] body type ${e} instanciates failed`))))
|
|
|
+ }
|
|
|
+ updateAnimationLists(e, t) {
|
|
|
+ return new Promise((r,n)=>(avatarLoader.avaliableAnimation.set(t, e),
|
|
|
+ r()))
|
|
|
+ }
|
|
|
+ loadAnimation(e, t) {
|
|
|
+ return new Promise((r,n)=>avatarLoader.loadAnimRes(this.sceneManager, t, e).then(o=>{
|
|
|
+ if (o) {
|
|
|
+ let a;
|
|
|
+ const s = this.avatarLoader.animations;
|
|
|
+ return o.animationGroups.forEach(l=>{
|
|
|
+ l.stop(),
|
|
|
+ l.name === t && (a = l,
|
|
|
+ a.pContainer = o),
|
|
|
+ s.set(getAnimationKey(l.name, e), l)
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ this._clipContainerRes(o),
|
|
|
+ o.xReferenceCount++,
|
|
|
+ r(a)
|
|
|
+ } else
|
|
|
+ return n(new ContainerLoadingFailedError("[Engine] container failed instanciates failed"))
|
|
|
+ }
|
|
|
+ ))
|
|
|
+ }
|
|
|
+ loadDecoration(e, t, r) {
|
|
|
+ return new Promise((n,o)=>avatarLoader.load(this.sceneManager, t, r).then(a=>{
|
|
|
+ if (a) {
|
|
|
+ this._clipContainerRes(a);
|
|
|
+ const s = a.meshes[1].clone(a.meshes[1].name, null);
|
|
|
+ if (!s) {
|
|
|
+ log$D.warn("[Engine] decoration does not exist!"),
|
|
|
+ n(null);
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const l = {
|
|
|
+ isRender: !1,
|
|
|
+ uId: Math.random(),
|
|
|
+ root: s,
|
|
|
+ type: e,
|
|
|
+ name: t,
|
|
|
+ isSelected: !1,
|
|
|
+ lod: r
|
|
|
+ };
|
|
|
+ if (a.xReferenceCount++,
|
|
|
+ s._parentContainer = a,
|
|
|
+ a.meshes.length > 1)
|
|
|
+ for (let u = 2; u < a.meshes.length; u++)
|
|
|
+ s.addChild(a.meshes[u].clone(a.meshes[u].name, null));
|
|
|
+ s.setEnabled(!1),
|
|
|
+ l.isSelected = !0,
|
|
|
+ n(l)
|
|
|
+ } else
|
|
|
+ return o(new ContainerLoadingFailedError("[Engine] container failed, instanciates failed."))
|
|
|
+ }
|
|
|
+ ).catch(()=>o(new ContainerLoadingFailedError(`[Engine] body type ${e} instanciates failed.`))))
|
|
|
+ }
|
|
|
+ _getSourceKey(e, t) {
|
|
|
+ return t && avatarSetting.lod[t] ? e + avatarSetting.lod[t].fileName.split(".")[0] : e
|
|
|
+ }
|
|
|
+ addAvatarToScene(e, t) {
|
|
|
+ const r = Date.now();
|
|
|
+ return new Promise((n,o)=>{
|
|
|
+ this.loadBody(e.avatarType, e.avatarType, t).then(a=>{
|
|
|
+ var s;
|
|
|
+ if (!a)
|
|
|
+ return e.isInLoadingList = !1,
|
|
|
+ o(new ContainerLoadingFailedError(`[Engine] avatar ${e.id} instanciates failed`));
|
|
|
+ if (e.attachBody(a),
|
|
|
+ a.animations.length > 0)
|
|
|
+ return a.animations.forEach(l=>{
|
|
|
+ l.stop()
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e.setAnimations(a.animations),
|
|
|
+ (s = e.controller) == null || s.playAnimation(e.controller.onPlay, !0),
|
|
|
+ e.isRender = !0,
|
|
|
+ e.isInLoadingList = !1,
|
|
|
+ e.setAvatarVisible(!0),
|
|
|
+ n(e);
|
|
|
+ this.loadAnimation(e.avatarType, this._defaultAnims).then(l=>{
|
|
|
+ if (!l)
|
|
|
+ return e.removeAvatarFromScene(),
|
|
|
+ e.isInLoadingList = !1,
|
|
|
+ o(new AvatarAnimationError);
|
|
|
+ const u = [];
|
|
|
+ e.clothesList.length > 0 && e.clothesList.forEach(c=>{
|
|
|
+ u.push(this.loadDecoration(c.type, c.id, t))
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ Promise.all(u).then(c=>{
|
|
|
+ var d, _, g, m;
|
|
|
+ c.forEach(v=>{
|
|
|
+ if (v && !v.isRender)
|
|
|
+ e.attachDecoration(v);
|
|
|
+ else
|
|
|
+ return e.isInLoadingList = !1,
|
|
|
+ e.removeAvatarFromScene(),
|
|
|
+ o(new AvatarAssetLoadingError)
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e.isRender = !0,
|
|
|
+ (d = e.controller) == null || d.playAnimation(e.controller.onPlay, e.controller.loop),
|
|
|
+ e.setAvatarVisible(!0);
|
|
|
+ const h = avatarLoader.mshPath.get("meshes/ygb.glb")
|
|
|
+ , f = avatarLoader.matPath.get(avatarResources.ygb.mesh);
|
|
|
+ h && f ? this.loadExtra(f, h).then(v=>{
|
|
|
+ var y;
|
|
|
+ e.isRender = !0,
|
|
|
+ e.isInLoadingList = !1,
|
|
|
+ e.distLevel = t,
|
|
|
+ (y = this._sceneManager) == null || y.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
|
|
|
+ n(e)
|
|
|
+ }
|
|
|
+ ) : (e.isRender = !0,
|
|
|
+ e.isInLoadingList = !1,
|
|
|
+ e.distLevel = t,
|
|
|
+ (_ = this._sceneManager) == null || _.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
|
|
|
+ n(e)),
|
|
|
+ (g = this._sceneManager) == null || g.lightComponent.setShadow(e),
|
|
|
+ e.isInLoadingList = !1,
|
|
|
+ e.distLevel = t,
|
|
|
+ (m = this._sceneManager) == null || m.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
|
|
|
+ n(e)
|
|
|
+ }
|
|
|
+ ).catch(()=>o(new AvatarAssetLoadingError(`[Engine] avatar ${e.id} instanciates failed.`)))
|
|
|
+ }
|
|
|
+ ).catch(()=>o(new AvatarAssetLoadingError(`[Engine] avatar ${e.id} instanciates failed.`)))
|
|
|
+ }
|
|
|
+ ).catch(()=>o(new AvatarAssetLoadingError(`[Engine] avatar ${e.id} instanciates failed.`)))
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ loadExtra(e, t) {
|
|
|
+ const r = avatarResources.ygb.name;
|
|
|
+ return new Promise((n,o)=>{
|
|
|
+ var a;
|
|
|
+ (a = this.sceneManager) == null || a.urlTransformer(e).then(s=>{
|
|
|
+ SceneLoader.LoadAssetContainerAsync("", s, this.scene, null, avatarSetting.fileType).then(l=>{
|
|
|
+ var c;
|
|
|
+ this.extraComps.set(r, l.meshes[0]);
|
|
|
+ const u = new NodeMaterial(`material_${r}`,this._scene,{
|
|
|
+ emitComments: !1
|
|
|
+ });
|
|
|
+ (c = this.sceneManager) == null || c.urlTransformer(t).then(h=>{
|
|
|
+ u.loadAsync(h).then(()=>{
|
|
|
+ l.meshes[2].material.dispose(!0, !0),
|
|
|
+ u.build(!1),
|
|
|
+ l.meshes[2].material = u,
|
|
|
+ n(l.meshes[2])
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ getAvatarList() {
|
|
|
+ const e = [];
|
|
|
+ return this.characterMap.forEach((t,r)=>{
|
|
|
+ t.forEach((n,o)=>{
|
|
|
+ e.push(n)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ e
|
|
|
+ }
|
|
|
+ _debug_avatar() {
|
|
|
+ var t, r;
|
|
|
+ console.error("===>currentLODUsers", this.currentLODUsers),
|
|
|
+ console.error("===>maxLODUsers", this._maxLODUsers),
|
|
|
+ console.error("===>Loddist", this.getLoDLevels()),
|
|
|
+ console.error("===> main character loc", (r = (t = this._mainUser) == null ? void 0 : t.rootNode) == null ? void 0 : r.position);
|
|
|
+ let e = 0;
|
|
|
+ this.getAvatarList().forEach(n=>{
|
|
|
+ n.isRender && (console.error(`avatar id : ${n.id},lod ${n.distLevel},is Hide ${n.isHide}, distance ${n.distance}, is pending ${n.isInLoadingList}`),
|
|
|
+ e++)
|
|
|
+ }
|
|
|
+ ),
|
|
|
+ console.error("========= avatar num", e),
|
|
|
+ console.error("loop:", this._updateLoopObserver ? "on" : "false", "=> process", this._process, "===> comp", this._processList),
|
|
|
+ console.error("===>maxLODUsers", this._maxLODUsers)
|
|
|
+ }
|
|
|
+}
|