XAvatarManager.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. import Pool from "./Pool"
  2. import BillboardStatus from "./enum/BillboardStatus.js"
  3. import {avatarLoader} from "./XAvatarLoader.js"
  4. import XAvatar from "./XAvatar.js"
  5. import Logger from "./Logger.js"
  6. const logger = new Logger('AvatarManager')
  7. export default class XAvatarManager {
  8. constructor(e) {
  9. this.characterMap = new Map
  10. this.curAnimList = []
  11. this.extraComps = new Map
  12. this._mainUser = null
  13. this._lodSettings = null
  14. this.maxBillBoardDist = 0
  15. this.maxAvatarNum = 0
  16. this.currentLODUsers = []
  17. this.bboxMeshPool = null
  18. this._distLevels = []
  19. this._maxLODUsers = []
  20. this._cullingDistance = 0
  21. this._maxDistRange = null
  22. this._delayTime = 100
  23. this._queueLength = -1
  24. this._queue = []
  25. this._processList = []
  26. this._process = null
  27. this._updateLoopObserver = null
  28. this._avatarInDistance = []
  29. this._renderedAvatar = []
  30. this._enableNickname = !0
  31. this._tickObserver = null
  32. this._tickInterval = null
  33. this._defaultAnims = null
  34. this._tickDispose = 0
  35. this._disposeTime = 100
  36. this.avatarLoader = avatarLoader
  37. this._scene = e.mainScene;
  38. this._sceneManager = e;
  39. this.initAvatarMap();
  40. this._initSettings();
  41. this._maxDistRange = this._distLevels[this._distLevels.length - 1],
  42. this.bboxMeshPool = new Pool(this.createBboxAsset,this.resetBboxAsset,0,this.maxAvatarNum,this._sceneManager.Scene,0,0,0),
  43. this._tickInterval = 250;
  44. let t = 0;
  45. this._tickObserver = this._scene.onAfterRenderObservable.add(()=>{
  46. t += 1,
  47. t == this._tickInterval && (this.tick(),
  48. t = 0)
  49. }
  50. )
  51. }
  52. tick() {
  53. this.bboxMeshPool.clean(0)
  54. }
  55. createBboxAsset(e, t, r, n) {
  56. return BABYLON.MeshBuilder.CreateBox("avatarBbox", {
  57. width: t,
  58. height: r,
  59. depth: n
  60. }, e)
  61. }
  62. resetBboxAsset(e) {
  63. const t = e.data;
  64. return t.setEnabled(!1),
  65. t.isPickable = !1,
  66. e
  67. }
  68. _initSettings() {
  69. this._defaultAnims = avatarSetting.defaultIdle,
  70. this._lodSettings = avatarSetting.lod,
  71. this._distLevels = avatarSetting.lod.map(e=>e.dist),
  72. this._maxLODUsers = avatarSetting.lod.map(e=>e.quota),
  73. this.currentLODUsers = new Array(this._distLevels.length).fill(0),
  74. this.maxAvatarNum = avatarSetting.maxAvatarNum,
  75. this.maxBillBoardDist = avatarSetting.maxBillBoardDist,
  76. this._cullingDistance = avatarSetting.cullingDistance
  77. }
  78. maxRenderNum() {
  79. let e = 0;
  80. return this._maxLODUsers.forEach(t=>{
  81. e += t
  82. }
  83. ),
  84. e
  85. }
  86. curRenderNum() {
  87. let e = 0;
  88. return this.currentLODUsers.forEach(t=>{
  89. e += t
  90. }
  91. ),
  92. e
  93. }
  94. setLoDLevels(e) {
  95. this._distLevels = e
  96. }
  97. set cullingDistance(e) {
  98. this._cullingDistance = e
  99. }
  100. get cullingDistance() {
  101. return this._cullingDistance
  102. }
  103. getLoDLevels() {
  104. return this._distLevels
  105. }
  106. setLodUserLimits(e, t) {
  107. this._maxLODUsers.length > e && (this._maxLODUsers[e] = t)
  108. }
  109. setLodDist(e, t) {
  110. this._distLevels[e] = t
  111. }
  112. setMaxDistRange(e) {
  113. this._maxDistRange = e,
  114. this._distLevels[this._distLevels.length - 1] = e
  115. }
  116. get scene() {
  117. return this._scene
  118. }
  119. setMainAvatar(e) {
  120. var t;
  121. this._mainUser = (t = this.characterMap.get(0)) == null ? void 0 : t.get(e)
  122. }
  123. getMainAvatar() {
  124. return this._mainUser
  125. }
  126. enableAllNickname(e) {
  127. return this.characterMap.forEach((t,r)=>{
  128. r != 0 && t.forEach((n,o)=>{
  129. this._updateBillboardStatus(n, e ? BillboardStatus.SHOW : BillboardStatus.HIDE)
  130. }
  131. )
  132. }
  133. ),
  134. this._enableNickname = e
  135. }
  136. getAvatarById(e) {
  137. let t;
  138. return this.characterMap.forEach((r,n)=>{
  139. r.get(e) && (t = r.get(e))
  140. }
  141. ),
  142. t
  143. }
  144. getAvatarNums() {
  145. let e = 0;
  146. return this.characterMap.forEach((t,r)=>{
  147. e += t.size
  148. }
  149. ),
  150. e
  151. }
  152. registerAvatar(e) {
  153. this.characterMap.get(e.priority).set(e.id, e)
  154. }
  155. unregisterAvatar(e) {
  156. this.characterMap.get(e.priority).delete(e.id)
  157. }
  158. initAvatarMap() {
  159. this.characterMap.set(0, new Map),
  160. this.characterMap.set(1, new Map),
  161. this.characterMap.set(2, new Map),
  162. this.characterMap.set(3, new Map),
  163. this.characterMap.set(4, new Map),
  164. this.characterMap.set(5, new Map)
  165. }
  166. loadAvatar({id, avatarType, priority, avatarManager, assets, status}) {
  167. return new Promise((resolve, reject)=>{
  168. if (this.getAvatarById(id))
  169. return reject(new DuplicateAvatarIDError(`[Engine] cannot init avatar with the same id = ${e}`));
  170. if (this.getAvatarNums() > this.maxAvatarNum)
  171. return reject(new ExceedMaxAvatarNumError(`[Engine] \u8D85\u51FA\u6700\u5927\u89D2\u8272\u9650\u5236 ${this.maxAvatarNum}`));
  172. const avatar = new XAvatar({ id, avatarType, priority, avatarManager, assets, status });
  173. this.registerAvatar(avatar);
  174. if (priority == 0)
  175. this.setMainAvatar(avatar.id),
  176. this.addAvatarToScene(avatar, 0).then(c=>(
  177. logger.debug(`[Engine] avatar ${avatar.id} has been added to scene`),
  178. c ? (
  179. this._updateBillboardStatus(c, BillboardStatus.SHOW),
  180. setTimeout(()=>{ this.launchProcessLoadingLoop() }, this._delayTime),
  181. resolve(c)
  182. ) : (
  183. avatar.removeAvatarFromScene(),
  184. reject(new AvatarAssetLoadingError)
  185. )
  186. )).catch(c=>(
  187. avatar.removeAvatarFromScene(),
  188. reject(new AvatarAssetLoadingError(c))
  189. ));
  190. else
  191. return resolve(avatar)
  192. })
  193. }
  194. deleteAvatar(e) {
  195. return e.isRender ? (e.removeAvatarFromScene(),
  196. this.currentLODUsers[e.distLevel]--) : e.bbComponent.disposeBillBoard(e),
  197. this._processList = this._processList.filter(t=>t.id !== e.id),
  198. this.unregisterAvatar(e),
  199. e.rootNode && (e.rootNode.dispose(),
  200. e.rootNode = void 0),
  201. e.bbComponent.bbox && e.bbComponent.bbox.dispose(),
  202. e.removeObserver(),
  203. e
  204. }
  205. _checkLODLevel(e) {
  206. if (e < this._distLevels[0])
  207. return 0;
  208. for (let t = 1; t < this._distLevels.length; ++t)
  209. if (e >= this._distLevels[t - 1] && e < this._distLevels[t])
  210. return t;
  211. return this._distLevels.length - 1
  212. }
  213. get sceneManager() {
  214. return this._sceneManager
  215. }
  216. launchProcessLoadingLoop() {
  217. this._updateAvatarStatus()
  218. }
  219. stopProcessLoadingLoop() {
  220. var e;
  221. this._updateLoopObserver && ((e = this._scene) == null || e.onBeforeRenderObservable.remove(this._updateLoopObserver))
  222. }
  223. _distToMain(e) {
  224. var n;
  225. const t = (n = this._mainUser) == null ? void 0 : n.position
  226. , r = e.position;
  227. if (r && t) {
  228. const o = this.sceneManager.cameraComponent.MainCamera.getFrontPosition(1).subtract(this.sceneManager.cameraComponent.MainCamera.position).normalize()
  229. , a = e.rootNode.position.subtract(this.sceneManager.cameraComponent.MainCamera.position).normalize();
  230. let s = 1;
  231. if (o && a) {
  232. const l = a.multiply(o);
  233. s = Math.acos(l.x + l.y + l.z) < this.sceneManager.cameraComponent.MainCamera.fov / 2 ? 1 : 1e11
  234. }
  235. return calcDistance3D(t, r) * s
  236. } else
  237. logger.warn("user position or camera position is not correct!");
  238. return 1e11
  239. }
  240. _distToCamera(e) {
  241. var n;
  242. const t = (n = this._sceneManager) == null ? void 0 : n.cameraComponent.getCameraPose().position
  243. , r = e.position;
  244. return r && t ? calcDistance3D(t, r) : (logger.warn("user position or camera position is not correct!"),
  245. 1e11)
  246. }
  247. showAll(e) {
  248. this.characterMap.forEach((t,r)=>{
  249. e && r == 0 && t.forEach((n,o)=>{
  250. n.show()
  251. }
  252. ),
  253. r != 0 && t.forEach((n,o)=>{
  254. n.show()
  255. }
  256. )
  257. }
  258. )
  259. }
  260. hideAll(e) {
  261. this.characterMap.forEach((t,r)=>{
  262. e && r == 0 && t.forEach((n,o)=>{
  263. n.hide()
  264. }
  265. ),
  266. r != 0 && t.forEach((n,o)=>{
  267. n.hide()
  268. }
  269. )
  270. }
  271. )
  272. }
  273. _assemblyAvatar(e, t) {
  274. var n, o;
  275. const r = e.get(avatarSetting.body);
  276. if (r && !t.attachBody(r)) {
  277. t.isInLoadingList = !1,
  278. e.clear();
  279. return
  280. }
  281. for (const a of e)
  282. if (a[0] != avatarSetting.body && a[0] != avatarSetting.animations && !t.attachDecoration(a[1])) {
  283. t.isInLoadingList = !1,
  284. t.removeAvatarFromScene(),
  285. e.clear();
  286. return
  287. }
  288. t.isRender = !0,
  289. (n = t.controller) == null || n.playAnimation(t.controller.onPlay, t.controller.loop),
  290. (o = t.controller) == null || o.onPlayObservable.addOnce(()=>{
  291. var a, s;
  292. if (!this.getAvatarById(t.id)) {
  293. t.isInLoadingList = !1,
  294. t.removeAvatarFromScene(),
  295. this.currentLODUsers[t.distLevel]--;
  296. return
  297. }
  298. if (this.getAvatarById(t.id).rootNode.getChildMeshes().length < e.size) {
  299. logger.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}`),
  300. t.isInLoadingList = !1,
  301. t.removeAvatarFromScene(),
  302. this.currentLODUsers[t.distLevel]--;
  303. return
  304. }
  305. t.setIsPickable(!0),
  306. t.isInLoadingList = !1,
  307. t.setAvatarVisible(!0),
  308. (s = this._sceneManager) == null || s.lightComponent.setShadow(t),
  309. t.getBbox(),
  310. t.nameBoard && t.nickName.length > 0 && t.setNickName(t.nickName, t.nameBoard.DEFAULT_CONFIGS),
  311. t.bubble && t.words.length > 0 && t.say(t.words, t.bubble.DEFAULT_CONFIGS),
  312. logger.debug(`[Engine] avatar ${t.id} has been added to scene, current number of users : ${this.currentLODUsers}`)
  313. }
  314. )
  315. }
  316. _disposeUnusedAssets() {
  317. this._tickDispose++,
  318. this._tickDispose > this._disposeTime && (avatarLoader.disposeContainer(),
  319. this._tickDispose = 0)
  320. }
  321. _addResourcesToList(e, t) {
  322. return e.clothesList.forEach(r=>{
  323. r.lod = t,
  324. this._queue.push(r)
  325. }
  326. ),
  327. this._queue.push({
  328. type: avatarSetting.animations,
  329. id: this._defaultAnims
  330. }),
  331. this._queue.push({
  332. type: avatarSetting.body,
  333. id: e.avatarType,
  334. lod: t
  335. }),
  336. !0
  337. }
  338. _updateBillboardStatus(e, t) {
  339. e.bbComponent.updateBillboardStatus(e, t)
  340. }
  341. _processLayer(e) {
  342. const t = this.characterMap.get(e)
  343. , r = [];
  344. for (t == null || t.forEach(n=>{
  345. n.distToCam = this._distToCamera(n);
  346. const o = n.distToCam < this._cullingDistance;
  347. if (n.isRender && (!n.isHide && o ? n._hide_culling() : n._show_culling()),
  348. n.priority != 0) {
  349. n.distance = this._distToMain(n);
  350. let a = BillboardStatus.SHOW;
  351. n.distance < this._maxDistRange && (o ? a = BillboardStatus.HIDE : n._show_culling(),
  352. this._updateBillboardStatus(n, a)),
  353. n.isHide || (n.isInLoadingList ? this.currentLODUsers[n.distLevel]++ : r.push(n))
  354. }
  355. }
  356. ),
  357. r.sort((n,o)=>o.distance - n.distance); r.length > 0 && this.curRenderNum() < this.maxRenderNum(); ) {
  358. const n = r.pop();
  359. let o = this._checkLODLevel(n.distance)
  360. , a = !1;
  361. for (let s = 0; s < this._maxLODUsers.length; ++s)
  362. if (this.currentLODUsers[s] < this._maxLODUsers[s]) {
  363. o = s,
  364. a = !0;
  365. break
  366. }
  367. if (!a || n.distance > this._maxDistRange) {
  368. if (n.isRender) {
  369. n._removeAvatarFromScene();
  370. let s = BillboardStatus.HIDE;
  371. n.distance < this._maxDistRange && (s = BillboardStatus.SHOW),
  372. this._updateBillboardStatus(n, s)
  373. }
  374. break
  375. }
  376. o != n.distLevel ? (n.isRender && (n.pendingLod = !0),
  377. n.distLevel = o,
  378. this._processList.push(n),
  379. n.isInLoadingList = !0) : n.isRender || (this._processList.push(n),
  380. n.isInLoadingList = !0),
  381. this.currentLODUsers[o]++
  382. }
  383. return this.curRenderNum() >= this.maxRenderNum() && r.forEach(n=>{
  384. if (n.isRender) {
  385. n._removeAvatarFromScene();
  386. let o = BillboardStatus.HIDE;
  387. n.distance < this._maxDistRange && (o = BillboardStatus.SHOW),
  388. this._updateBillboardStatus(n, o)
  389. }
  390. }
  391. ),
  392. this.curRenderNum() < this.maxRenderNum()
  393. }
  394. _updateAvatar() {
  395. this.currentLODUsers = [0, 0, 0];
  396. const e = [5, 4, 3, 2, 1, 0];
  397. for (; e.length > 0; ) {
  398. const t = e.pop();
  399. if (!this._processLayer(t)) {
  400. e.forEach(n=>{
  401. var o;
  402. (o = this.characterMap.get(n)) == null || o.forEach(a=>{
  403. a.distance = this._distToMain(a);
  404. let s = BillboardStatus.HIDE;
  405. a.distToCam < this._maxDistRange && (s = BillboardStatus.SHOW,
  406. a.isRender && a._removeAvatarFromScene()),
  407. this._updateBillboardStatus(a, s)
  408. }
  409. )
  410. }
  411. );
  412. break
  413. }
  414. }
  415. }
  416. _updateAvatarStatus() {
  417. const e = new Map;
  418. this._updateLoopObserver = this.scene.onBeforeRenderObservable.add(()=>{
  419. var t;
  420. if (this._disposeUnusedAssets(),
  421. !(this.getAvatarNums() <= 0)) {
  422. if (!this._process && this._processList.length == 0 && this._updateAvatar(),
  423. !this._process && this._processList.length > 0) {
  424. const r = this._processList.shift();
  425. r != this._process && !r.isCulling ? this._addResourcesToList(r, r.distLevel) ? (this._process = r,
  426. this._queueLength = this._queue.length) : (this._process = void 0,
  427. this._queue = [],
  428. r.isInLoadingList = !1) : r.isInLoadingList = !1
  429. }
  430. if (e.size === this._queueLength && this._process) {
  431. this._process.pendingLod && (this._process.pendingLod = !1,
  432. this._process._removeAvatarFromScene());
  433. const r = Date.now();
  434. this._assemblyAvatar(e, this._process),
  435. (t = this._sceneManager) == null || t.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
  436. this._updateBillboardStatus(this._process, BillboardStatus.SHOW),
  437. e.clear(),
  438. this._queue = [],
  439. this._process.isInLoadingList = !1,
  440. this._process = void 0,
  441. this._disposeUnusedAssets()
  442. }
  443. this._loadResByList(e)
  444. }
  445. }
  446. )
  447. }
  448. _loadResByList(e) {
  449. let t = 0;
  450. const r = 5;
  451. if (!this._process) {
  452. e.clear();
  453. return
  454. }
  455. for (; t < r && this._queue.length > 0; ) {
  456. const n = Date.now()
  457. , o = this._queue.pop();
  458. setTimeout(()=>{
  459. o ? o.type === avatarSetting.body ? this.loadBody(o.type, o.id, o.lod).then(a=>{
  460. a && e.set(avatarSetting.body, a),
  461. t += Date.now() - n
  462. }
  463. ).catch(a=>{
  464. this._process && (this._process.isHide = !0,
  465. this.currentLODUsers[this._process.distLevel]--,
  466. e.clear(),
  467. this._queue = [],
  468. this._process.isInLoadingList = !1,
  469. this._process = void 0,
  470. t += 100),
  471. logger.warn(`[Engine] body ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
  472. }
  473. ) : o.type === avatarSetting.animations ? this.loadAnimation(this._process.avatarType, o.id).then(a=>{
  474. a && e.set(avatarSetting.animations, a),
  475. t += Date.now() - n
  476. }
  477. ).catch(a=>{
  478. this._process && (this._process.isHide = !0,
  479. this.currentLODUsers[this._process.distLevel]--,
  480. e.clear(),
  481. this._queue = [],
  482. this._process.isInLoadingList = !1,
  483. this._process = void 0,
  484. t += 100),
  485. logger.warn(`animation ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
  486. }
  487. ) : this.loadDecoration(o.type, o.id, o.lod).then(a=>{
  488. a && e.set(a.type, a),
  489. t += Date.now() - n
  490. }
  491. ).catch(a=>{
  492. this._process && (this._process.isHide = !0,
  493. this.currentLODUsers[this._process.distLevel]--,
  494. e.clear(),
  495. this._queue = [],
  496. this._process.isInLoadingList = !1,
  497. this._process = void 0,
  498. t += 100),
  499. logger.warn(`component ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
  500. }
  501. ) : t += 100
  502. }
  503. , 0)
  504. }
  505. }
  506. _validateContainer(e) {
  507. return !e.meshes || e.meshes.length <= 1 ? (logger.warn("import container has no valid meshes"),
  508. !1) : !e.skeletons || e.skeletons.length == 0 ? (logger.warn("import container has no valid skeletons"),
  509. !1) : !0
  510. }
  511. _getAssetContainer(e, t) {
  512. return new Promise((r,n)=>{
  513. const o = this._getSourceKey(e, t || 0)
  514. , a = avatarLoader.containers.get(o);
  515. if (a)
  516. return r(a);
  517. avatarLoader.load(this.sceneManager, e, t).then(s=>s ? this._validateContainer(s) ? (avatarLoader.containers.set(o, s),
  518. 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}.`)))
  519. }
  520. )
  521. }
  522. _clipContainerRes(e) {
  523. e.transformNodes.forEach(t=>{
  524. t.dispose()
  525. }
  526. ),
  527. e.transformNodes = [],
  528. e.skeletons.forEach(t=>{
  529. t.dispose()
  530. }
  531. ),
  532. e.skeletons = []
  533. }
  534. loadBody(e, t, r) {
  535. return new Promise((n,o)=>avatarLoader.load(this.sceneManager, t, r).then(a=>{
  536. if (a) {
  537. const s = a.instantiateModelsToScene();
  538. // zeg 此时body_man缩放已经0.01
  539. console.log("body_man缩放", s.rootNodes[0]._children[0]._scaling)
  540. a.xReferenceCount++;
  541. const l = {
  542. isRender: !1,
  543. uId: Math.random(),
  544. root: s.rootNodes[0],
  545. skeletonType: e,
  546. name: t,
  547. animations: s.animationGroups,
  548. skeleton: s.skeletons[0],
  549. lod: r
  550. };
  551. return s.rootNodes[0]._parentContainer = a,
  552. s.rootNodes[0].setEnabled(!1),
  553. n(l)
  554. } else
  555. return o(new ContainerLoadingFailedError("[Engine] container failed instanciates failed"))
  556. }
  557. ).catch(()=>o(new ContainerLoadingFailedError(`[Engine] body type ${e} instanciates failed`))))
  558. }
  559. updateAnimationLists(e, t) {
  560. return new Promise((r,n)=>(avatarLoader.avaliableAnimation.set(t, e),
  561. r()))
  562. }
  563. loadAnimation(e, t) {
  564. return new Promise((r,n)=>avatarLoader.loadAnimRes(this.sceneManager, t, e).then(o=>{
  565. if (o) {
  566. let a;
  567. const s = this.avatarLoader.animations;
  568. return o.animationGroups.forEach(l=>{
  569. l.stop(),
  570. l.name === t && (a = l,
  571. a.pContainer = o),
  572. s.set(getAnimationKey(l.name, e), l)
  573. }
  574. ),
  575. this._clipContainerRes(o),
  576. o.xReferenceCount++,
  577. r(a)
  578. } else
  579. return n(new ContainerLoadingFailedError("[Engine] container failed instanciates failed"))
  580. }
  581. ))
  582. }
  583. loadDecoration(e, t, r) {
  584. return new Promise((n,o)=>avatarLoader.load(this.sceneManager, t, r).then(a=>{
  585. if (a) {
  586. this._clipContainerRes(a);
  587. const s = a.meshes[1].clone(a.meshes[1].name, null);
  588. // zeg 装饰模型scale矫正
  589. s.scaling = new BABYLON.Vector3(-0.01, 0.01, -0.01)
  590. if (!s) {
  591. logger.warn("[Engine] decoration does not exist!"),
  592. n(null);
  593. return
  594. }
  595. const l = {
  596. isRender: !1,
  597. uId: Math.random(),
  598. root: s,
  599. type: e,
  600. name: t,
  601. isSelected: !1,
  602. lod: r
  603. };
  604. if (a.xReferenceCount++,
  605. s._parentContainer = a,
  606. a.meshes.length > 1)
  607. for (let u = 2; u < a.meshes.length; u++)
  608. s.addChild(a.meshes[u].clone(a.meshes[u].name, null));
  609. s.setEnabled(!1),
  610. l.isSelected = !0,
  611. n(l)
  612. } else
  613. return o(new ContainerLoadingFailedError("[Engine] container failed, instanciates failed."))
  614. }
  615. ).catch(()=>o(new ContainerLoadingFailedError(`[Engine] body type ${e} instanciates failed.`))))
  616. }
  617. _getSourceKey(e, t) {
  618. return t && avatarSetting.lod[t] ? e + avatarSetting.lod[t].fileName.split(".")[0] : e
  619. }
  620. addAvatarToScene(xavatar, t) {
  621. const startTime = Date.now();
  622. return new Promise((resolve, reject)=>{
  623. this.loadBody(xavatar.avatarType, xavatar.avatarType, t).then(modelData => {
  624. if (!modelData) {
  625. xavatar.isInLoadingList = !1
  626. return reject(new ContainerLoadingFailedError(`[Engine] avatar ${xavatar.id} instanciates failed`));
  627. }
  628. xavatar.attachBody(modelData)
  629. if (modelData.animations.length > 0) {
  630. modelData.animations.forEach(l=>{
  631. l.stop()
  632. })
  633. xavatar.setAnimations(modelData.animations)
  634. xavatar.controller == null || xavatar.controller.playAnimation(xavatar.controller.onPlay, !0)
  635. xavatar.isRender = !0
  636. xavatar.isInLoadingList = !1
  637. xavatar.setAvatarVisible(!0)
  638. return resolve(xavatar);
  639. }
  640. this.loadAnimation(xavatar.avatarType, this._defaultAnims).then(l => {
  641. if (!l) {
  642. xavatar.removeAvatarFromScene()
  643. xavatar.isInLoadingList = !1
  644. return reject(new AvatarAnimationError);
  645. }
  646. const u = [];
  647. xavatar.clothesList.length > 0 && xavatar.clothesList.forEach(c => {
  648. u.push(this.loadDecoration(c.type, c.id, t))
  649. }),
  650. Promise.all(u).then(c => {
  651. c.forEach(v=>{
  652. if (v && !v.isRender) {
  653. xavatar.attachDecoration(v);
  654. } else {
  655. xavatar.isInLoadingList = !1,
  656. xavatar.removeAvatarFromScene()
  657. return reject(new AvatarAssetLoadingError)
  658. }
  659. }),
  660. xavatar.isRender = !0,
  661. xavatar.controller == null || xavatar.controller.playAnimation(xavatar.controller.onPlay, xavatar.controller.loop),
  662. xavatar.setAvatarVisible(!0);
  663. const h = avatarLoader.mshPath.get("meshes/ygb.glb")
  664. , f = avatarLoader.matPath.get(avatarResources.ygb.mesh);
  665. if(h && f) {
  666. this.loadExtra(f, h).then(v => {
  667. xavatar.isRender = !0,
  668. xavatar.isInLoadingList = !1,
  669. xavatar.distLevel = t,
  670. this._sceneManager == null || this._sceneManager.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - startTime),
  671. resolve(xavatar)
  672. })
  673. } else {
  674. xavatar.isRender = !0,
  675. xavatar.isInLoadingList = !1,
  676. xavatar.distLevel = t,
  677. this._sceneManager == null || this._sceneManager.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - startTime),
  678. resolve(xavatar)
  679. }
  680. this._sceneManager == null || this._sceneManager.lightComponent.setShadow(xavatar),
  681. xavatar.isInLoadingList = !1,
  682. xavatar.distLevel = t,
  683. this._sceneManager == null || this._sceneManager.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - startTime),
  684. resolve(xavatar)
  685. }
  686. ).catch(()=>reject(new AvatarAssetLoadingError(`[Engine] avatar ${xavatar.id} instanciates failed.`)))
  687. }
  688. ).catch(()=>reject(new AvatarAssetLoadingError(`[Engine] avatar ${xavatar.id} instanciates failed.`)))
  689. }
  690. ).catch(()=>reject(new AvatarAssetLoadingError(`[Engine] avatar ${xavatar.id} instanciates failed.`)))
  691. })
  692. }
  693. loadExtra(e, t) {
  694. const r = avatarResources.ygb.name;
  695. return new Promise((n,o)=>{
  696. var a;
  697. (a = this.sceneManager) == null || a.urlTransformer(e).then(s=>{
  698. BABYLON.SceneLoader.LoadAssetContainerAsync("", s, this.scene, null, avatarSetting.fileType).then(l=>{
  699. var c;
  700. this.extraComps.set(r, l.meshes[0]);
  701. const u = new NodeMaterial(`material_${r}`,this._scene,{
  702. emitComments: !1
  703. });
  704. (c = this.sceneManager) == null || c.urlTransformer(t).then(h=>{
  705. u.loadAsync(h).then(()=>{
  706. l.meshes[2].material.dispose(!0, !0),
  707. u.build(!1),
  708. l.meshes[2].material = u,
  709. n(l.meshes[2])
  710. }
  711. )
  712. }
  713. )
  714. }
  715. )
  716. }
  717. )
  718. }
  719. )
  720. }
  721. getAvatarList() {
  722. const e = [];
  723. return this.characterMap.forEach((t,r)=>{
  724. t.forEach((n,o)=>{
  725. e.push(n)
  726. }
  727. )
  728. }
  729. ),
  730. e
  731. }
  732. _debug_avatar() {
  733. var t, r;
  734. console.error("===>currentLODUsers", this.currentLODUsers),
  735. console.error("===>maxLODUsers", this._maxLODUsers),
  736. console.error("===>Loddist", this.getLoDLevels()),
  737. console.error("===> main character loc", (r = (t = this._mainUser) == null ? void 0 : t.rootNode) == null ? void 0 : r.position);
  738. let e = 0;
  739. this.getAvatarList().forEach(n=>{
  740. n.isRender && (console.error(`avatar id : ${n.id},lod ${n.distLevel},is Hide ${n.isHide}, distance ${n.distance}, is pending ${n.isInLoadingList}`),
  741. e++)
  742. }
  743. ),
  744. console.error("========= avatar num", e),
  745. console.error("loop:", this._updateLoopObserver ? "on" : "false", "=> process", this._process, "===> comp", this._processList),
  746. console.error("===>maxLODUsers", this._maxLODUsers)
  747. }
  748. }