XAvatarManager.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  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: e, avatarType: t, priority: r, avatarManager: n, assets: o, status: a}) {
  167. return new Promise((s,l)=>{
  168. if (this.getAvatarById(e))
  169. return l(new DuplicateAvatarIDError(`[Engine] cannot init avatar with the same id = ${e}`));
  170. if (this.getAvatarNums() > this.maxAvatarNum)
  171. return l(new ExceedMaxAvatarNumError(`[Engine] \u8D85\u51FA\u6700\u5927\u89D2\u8272\u9650\u5236 ${this.maxAvatarNum}`));
  172. const u = new XAvatar({
  173. id: e,
  174. avatarType: t,
  175. priority: r,
  176. avatarManager: n,
  177. assets: o,
  178. status: a
  179. });
  180. this.registerAvatar(u);
  181. if (r == 0)
  182. this.setMainAvatar(u.id),
  183. this.addAvatarToScene(u, 0).then(c=>(logger.debug(`[Engine] avatar ${u.id} has been added to scene`),
  184. c ? (this._updateBillboardStatus(c, BillboardStatus.SHOW),
  185. setTimeout(()=>{
  186. this.launchProcessLoadingLoop()
  187. }
  188. , this._delayTime),
  189. s(c)) : (u.removeAvatarFromScene(),
  190. l(new AvatarAssetLoadingError)))).catch(c=>(u.removeAvatarFromScene(),
  191. l(new AvatarAssetLoadingError(c))));
  192. else
  193. return s(u)
  194. // this.setMainAvatar(u.id),
  195. // this.addAvatarToScene(u, 0).then(c=>(logger.debug(`[Engine] avatar ${u.id} has been added to scene`),
  196. // c ? (this._updateBillboardStatus(c, BillboardStatus.SHOW),
  197. // setTimeout(()=>{
  198. // this.launchProcessLoadingLoop()
  199. // }
  200. // , this._delayTime),
  201. // s(c)) : (u.removeAvatarFromScene(),
  202. // l(new AvatarAssetLoadingError)))).catch(c=>(u.removeAvatarFromScene(),
  203. // l(new AvatarAssetLoadingError(c))));
  204. }
  205. )
  206. }
  207. deleteAvatar(e) {
  208. return e.isRender ? (e.removeAvatarFromScene(),
  209. this.currentLODUsers[e.distLevel]--) : e.bbComponent.disposeBillBoard(e),
  210. this._processList = this._processList.filter(t=>t.id !== e.id),
  211. this.unregisterAvatar(e),
  212. e.rootNode && (e.rootNode.dispose(),
  213. e.rootNode = void 0),
  214. e.bbComponent.bbox && e.bbComponent.bbox.dispose(),
  215. e.removeObserver(),
  216. e
  217. }
  218. _checkLODLevel(e) {
  219. if (e < this._distLevels[0])
  220. return 0;
  221. for (let t = 1; t < this._distLevels.length; ++t)
  222. if (e >= this._distLevels[t - 1] && e < this._distLevels[t])
  223. return t;
  224. return this._distLevels.length - 1
  225. }
  226. get sceneManager() {
  227. return this._sceneManager
  228. }
  229. launchProcessLoadingLoop() {
  230. this._updateAvatarStatus()
  231. }
  232. stopProcessLoadingLoop() {
  233. var e;
  234. this._updateLoopObserver && ((e = this._scene) == null || e.onBeforeRenderObservable.remove(this._updateLoopObserver))
  235. }
  236. _distToMain(e) {
  237. var n;
  238. const t = (n = this._mainUser) == null ? void 0 : n.position
  239. , r = e.position;
  240. if (r && t) {
  241. const o = this.sceneManager.cameraComponent.MainCamera.getFrontPosition(1).subtract(this.sceneManager.cameraComponent.MainCamera.position).normalize()
  242. , a = e.rootNode.position.subtract(this.sceneManager.cameraComponent.MainCamera.position).normalize();
  243. let s = 1;
  244. if (o && a) {
  245. const l = a.multiply(o);
  246. s = Math.acos(l.x + l.y + l.z) < this.sceneManager.cameraComponent.MainCamera.fov / 2 ? 1 : 1e11
  247. }
  248. return calcDistance3D(t, r) * s
  249. } else
  250. logger.warn("user position or camera position is not correct!");
  251. return 1e11
  252. }
  253. _distToCamera(e) {
  254. var n;
  255. const t = (n = this._sceneManager) == null ? void 0 : n.cameraComponent.getCameraPose().position
  256. , r = e.position;
  257. return r && t ? calcDistance3D(t, r) : (logger.warn("user position or camera position is not correct!"),
  258. 1e11)
  259. }
  260. showAll(e) {
  261. this.characterMap.forEach((t,r)=>{
  262. e && r == 0 && t.forEach((n,o)=>{
  263. n.show()
  264. }
  265. ),
  266. r != 0 && t.forEach((n,o)=>{
  267. n.show()
  268. }
  269. )
  270. }
  271. )
  272. }
  273. hideAll(e) {
  274. this.characterMap.forEach((t,r)=>{
  275. e && r == 0 && t.forEach((n,o)=>{
  276. n.hide()
  277. }
  278. ),
  279. r != 0 && t.forEach((n,o)=>{
  280. n.hide()
  281. }
  282. )
  283. }
  284. )
  285. }
  286. _assemblyAvatar(e, t) {
  287. var n, o;
  288. const r = e.get(avatarSetting.body);
  289. if (r && !t.attachBody(r)) {
  290. t.isInLoadingList = !1,
  291. e.clear();
  292. return
  293. }
  294. for (const a of e)
  295. if (a[0] != avatarSetting.body && a[0] != avatarSetting.animations && !t.attachDecoration(a[1])) {
  296. t.isInLoadingList = !1,
  297. t.removeAvatarFromScene(),
  298. e.clear();
  299. return
  300. }
  301. t.isRender = !0,
  302. (n = t.controller) == null || n.playAnimation(t.controller.onPlay, t.controller.loop),
  303. (o = t.controller) == null || o.onPlayObservable.addOnce(()=>{
  304. var a, s;
  305. if (!this.getAvatarById(t.id)) {
  306. t.isInLoadingList = !1,
  307. t.removeAvatarFromScene(),
  308. this.currentLODUsers[t.distLevel]--;
  309. return
  310. }
  311. if (this.getAvatarById(t.id).rootNode.getChildMeshes().length < e.size) {
  312. 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}`),
  313. t.isInLoadingList = !1,
  314. t.removeAvatarFromScene(),
  315. this.currentLODUsers[t.distLevel]--;
  316. return
  317. }
  318. t.setIsPickable(!0),
  319. t.isInLoadingList = !1,
  320. t.setAvatarVisible(!0),
  321. (s = this._sceneManager) == null || s.lightComponent.setShadow(t),
  322. t.getBbox(),
  323. t.nameBoard && t.nickName.length > 0 && t.setNickName(t.nickName, t.nameBoard.DEFAULT_CONFIGS),
  324. t.bubble && t.words.length > 0 && t.say(t.words, t.bubble.DEFAULT_CONFIGS),
  325. logger.debug(`[Engine] avatar ${t.id} has been added to scene, current number of users : ${this.currentLODUsers}`)
  326. }
  327. )
  328. }
  329. _disposeUnusedAssets() {
  330. this._tickDispose++,
  331. this._tickDispose > this._disposeTime && (avatarLoader.disposeContainer(),
  332. this._tickDispose = 0)
  333. }
  334. _addResourcesToList(e, t) {
  335. return e.clothesList.forEach(r=>{
  336. r.lod = t,
  337. this._queue.push(r)
  338. }
  339. ),
  340. this._queue.push({
  341. type: avatarSetting.animations,
  342. id: this._defaultAnims
  343. }),
  344. this._queue.push({
  345. type: avatarSetting.body,
  346. id: e.avatarType,
  347. lod: t
  348. }),
  349. !0
  350. }
  351. _updateBillboardStatus(e, t) {
  352. e.bbComponent.updateBillboardStatus(e, t)
  353. }
  354. _processLayer(e) {
  355. const t = this.characterMap.get(e)
  356. , r = [];
  357. for (t == null || t.forEach(n=>{
  358. n.distToCam = this._distToCamera(n);
  359. const o = n.distToCam < this._cullingDistance;
  360. if (n.isRender && (!n.isHide && o ? n._hide_culling() : n._show_culling()),
  361. n.priority != 0) {
  362. n.distance = this._distToMain(n);
  363. let a = BillboardStatus.SHOW;
  364. n.distance < this._maxDistRange && (o ? a = BillboardStatus.HIDE : n._show_culling(),
  365. this._updateBillboardStatus(n, a)),
  366. n.isHide || (n.isInLoadingList ? this.currentLODUsers[n.distLevel]++ : r.push(n))
  367. }
  368. }
  369. ),
  370. r.sort((n,o)=>o.distance - n.distance); r.length > 0 && this.curRenderNum() < this.maxRenderNum(); ) {
  371. const n = r.pop();
  372. let o = this._checkLODLevel(n.distance)
  373. , a = !1;
  374. for (let s = 0; s < this._maxLODUsers.length; ++s)
  375. if (this.currentLODUsers[s] < this._maxLODUsers[s]) {
  376. o = s,
  377. a = !0;
  378. break
  379. }
  380. if (!a || n.distance > this._maxDistRange) {
  381. if (n.isRender) {
  382. n._removeAvatarFromScene();
  383. let s = BillboardStatus.HIDE;
  384. n.distance < this._maxDistRange && (s = BillboardStatus.SHOW),
  385. this._updateBillboardStatus(n, s)
  386. }
  387. break
  388. }
  389. o != n.distLevel ? (n.isRender && (n.pendingLod = !0),
  390. n.distLevel = o,
  391. this._processList.push(n),
  392. n.isInLoadingList = !0) : n.isRender || (this._processList.push(n),
  393. n.isInLoadingList = !0),
  394. this.currentLODUsers[o]++
  395. }
  396. return this.curRenderNum() >= this.maxRenderNum() && r.forEach(n=>{
  397. if (n.isRender) {
  398. n._removeAvatarFromScene();
  399. let o = BillboardStatus.HIDE;
  400. n.distance < this._maxDistRange && (o = BillboardStatus.SHOW),
  401. this._updateBillboardStatus(n, o)
  402. }
  403. }
  404. ),
  405. this.curRenderNum() < this.maxRenderNum()
  406. }
  407. _updateAvatar() {
  408. this.currentLODUsers = [0, 0, 0];
  409. const e = [5, 4, 3, 2, 1, 0];
  410. for (; e.length > 0; ) {
  411. const t = e.pop();
  412. if (!this._processLayer(t)) {
  413. e.forEach(n=>{
  414. var o;
  415. (o = this.characterMap.get(n)) == null || o.forEach(a=>{
  416. a.distance = this._distToMain(a);
  417. let s = BillboardStatus.HIDE;
  418. a.distToCam < this._maxDistRange && (s = BillboardStatus.SHOW,
  419. a.isRender && a._removeAvatarFromScene()),
  420. this._updateBillboardStatus(a, s)
  421. }
  422. )
  423. }
  424. );
  425. break
  426. }
  427. }
  428. }
  429. _updateAvatarStatus() {
  430. const e = new Map;
  431. this._updateLoopObserver = this.scene.onBeforeRenderObservable.add(()=>{
  432. var t;
  433. if (this._disposeUnusedAssets(),
  434. !(this.getAvatarNums() <= 0)) {
  435. if (!this._process && this._processList.length == 0 && this._updateAvatar(),
  436. !this._process && this._processList.length > 0) {
  437. const r = this._processList.shift();
  438. r != this._process && !r.isCulling ? this._addResourcesToList(r, r.distLevel) ? (this._process = r,
  439. this._queueLength = this._queue.length) : (this._process = void 0,
  440. this._queue = [],
  441. r.isInLoadingList = !1) : r.isInLoadingList = !1
  442. }
  443. if (e.size === this._queueLength && this._process) {
  444. this._process.pendingLod && (this._process.pendingLod = !1,
  445. this._process._removeAvatarFromScene());
  446. const r = Date.now();
  447. this._assemblyAvatar(e, this._process),
  448. (t = this._sceneManager) == null || t.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
  449. this._updateBillboardStatus(this._process, BillboardStatus.SHOW),
  450. e.clear(),
  451. this._queue = [],
  452. this._process.isInLoadingList = !1,
  453. this._process = void 0,
  454. this._disposeUnusedAssets()
  455. }
  456. this._loadResByList(e)
  457. }
  458. }
  459. )
  460. }
  461. _loadResByList(e) {
  462. let t = 0;
  463. const r = 5;
  464. if (!this._process) {
  465. e.clear();
  466. return
  467. }
  468. for (; t < r && this._queue.length > 0; ) {
  469. const n = Date.now()
  470. , o = this._queue.pop();
  471. setTimeout(()=>{
  472. o ? o.type === avatarSetting.body ? this.loadBody(o.type, o.id, o.lod).then(a=>{
  473. a && e.set(avatarSetting.body, a),
  474. t += Date.now() - n
  475. }
  476. ).catch(a=>{
  477. this._process && (this._process.isHide = !0,
  478. this.currentLODUsers[this._process.distLevel]--,
  479. e.clear(),
  480. this._queue = [],
  481. this._process.isInLoadingList = !1,
  482. this._process = void 0,
  483. t += 100),
  484. logger.warn(`[Engine] body ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
  485. }
  486. ) : o.type === avatarSetting.animations ? this.loadAnimation(this._process.avatarType, o.id).then(a=>{
  487. a && e.set(avatarSetting.animations, a),
  488. t += Date.now() - n
  489. }
  490. ).catch(a=>{
  491. this._process && (this._process.isHide = !0,
  492. this.currentLODUsers[this._process.distLevel]--,
  493. e.clear(),
  494. this._queue = [],
  495. this._process.isInLoadingList = !1,
  496. this._process = void 0,
  497. t += 100),
  498. logger.warn(`animation ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
  499. }
  500. ) : this.loadDecoration(o.type, o.id, o.lod).then(a=>{
  501. a && e.set(a.type, a),
  502. t += Date.now() - n
  503. }
  504. ).catch(a=>{
  505. this._process && (this._process.isHide = !0,
  506. this.currentLODUsers[this._process.distLevel]--,
  507. e.clear(),
  508. this._queue = [],
  509. this._process.isInLoadingList = !1,
  510. this._process = void 0,
  511. t += 100),
  512. logger.warn(`component ${o.id} uri error, type ${o.type}, avatar has been hided` + a)
  513. }
  514. ) : t += 100
  515. }
  516. , 0)
  517. }
  518. }
  519. _validateContainer(e) {
  520. return !e.meshes || e.meshes.length <= 1 ? (logger.warn("import container has no valid meshes"),
  521. !1) : !e.skeletons || e.skeletons.length == 0 ? (logger.warn("import container has no valid skeletons"),
  522. !1) : !0
  523. }
  524. _getAssetContainer(e, t) {
  525. return new Promise((r,n)=>{
  526. const o = this._getSourceKey(e, t || 0)
  527. , a = avatarLoader.containers.get(o);
  528. if (a)
  529. return r(a);
  530. avatarLoader.load(this.sceneManager, e, t).then(s=>s ? this._validateContainer(s) ? (avatarLoader.containers.set(o, s),
  531. 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}.`)))
  532. }
  533. )
  534. }
  535. _clipContainerRes(e) {
  536. e.transformNodes.forEach(t=>{
  537. t.dispose()
  538. }
  539. ),
  540. e.transformNodes = [],
  541. e.skeletons.forEach(t=>{
  542. t.dispose()
  543. }
  544. ),
  545. e.skeletons = []
  546. }
  547. loadBody(e, t, r) {
  548. return new Promise((n,o)=>avatarLoader.load(this.sceneManager, t, r).then(a=>{
  549. if (a) {
  550. const s = a.instantiateModelsToScene();
  551. // 周恩光加 此时body_man缩放已经0.01
  552. console.log("body_man缩放", s.rootNodes[0]._children[0]._scaling)
  553. a.xReferenceCount++;
  554. const l = {
  555. isRender: !1,
  556. uId: Math.random(),
  557. root: s.rootNodes[0],
  558. skeletonType: e,
  559. name: t,
  560. animations: s.animationGroups,
  561. skeleton: s.skeletons[0],
  562. lod: r
  563. };
  564. return s.rootNodes[0]._parentContainer = a,
  565. s.rootNodes[0].setEnabled(!1),
  566. n(l)
  567. } else
  568. return o(new ContainerLoadingFailedError("[Engine] container failed instanciates failed"))
  569. }
  570. ).catch(()=>o(new ContainerLoadingFailedError(`[Engine] body type ${e} instanciates failed`))))
  571. }
  572. updateAnimationLists(e, t) {
  573. return new Promise((r,n)=>(avatarLoader.avaliableAnimation.set(t, e),
  574. r()))
  575. }
  576. loadAnimation(e, t) {
  577. return new Promise((r,n)=>avatarLoader.loadAnimRes(this.sceneManager, t, e).then(o=>{
  578. if (o) {
  579. let a;
  580. const s = this.avatarLoader.animations;
  581. return o.animationGroups.forEach(l=>{
  582. l.stop(),
  583. l.name === t && (a = l,
  584. a.pContainer = o),
  585. s.set(getAnimationKey(l.name, e), l)
  586. }
  587. ),
  588. this._clipContainerRes(o),
  589. o.xReferenceCount++,
  590. r(a)
  591. } else
  592. return n(new ContainerLoadingFailedError("[Engine] container failed instanciates failed"))
  593. }
  594. ))
  595. }
  596. loadDecoration(e, t, r) {
  597. return new Promise((n,o)=>avatarLoader.load(this.sceneManager, t, r).then(a=>{
  598. if (a) {
  599. this._clipContainerRes(a);
  600. const s = a.meshes[1].clone(a.meshes[1].name, null);
  601. // 周恩光加 装饰模型scale矫正
  602. s.scaling = new BABYLON.Vector3(-0.01, 0.01, -0.01)
  603. if (!s) {
  604. logger.warn("[Engine] decoration does not exist!"),
  605. n(null);
  606. return
  607. }
  608. const l = {
  609. isRender: !1,
  610. uId: Math.random(),
  611. root: s,
  612. type: e,
  613. name: t,
  614. isSelected: !1,
  615. lod: r
  616. };
  617. if (a.xReferenceCount++,
  618. s._parentContainer = a,
  619. a.meshes.length > 1)
  620. for (let u = 2; u < a.meshes.length; u++)
  621. s.addChild(a.meshes[u].clone(a.meshes[u].name, null));
  622. s.setEnabled(!1),
  623. l.isSelected = !0,
  624. n(l)
  625. } else
  626. return o(new ContainerLoadingFailedError("[Engine] container failed, instanciates failed."))
  627. }
  628. ).catch(()=>o(new ContainerLoadingFailedError(`[Engine] body type ${e} instanciates failed.`))))
  629. }
  630. _getSourceKey(e, t) {
  631. return t && avatarSetting.lod[t] ? e + avatarSetting.lod[t].fileName.split(".")[0] : e
  632. }
  633. addAvatarToScene(e, t) {
  634. const r = Date.now();
  635. return new Promise((n,o)=>{
  636. this.loadBody(e.avatarType, e.avatarType, t).then(a=>{
  637. // console.error(a.root._children[0]._scaling)
  638. var s;
  639. if (!a)
  640. return e.isInLoadingList = !1,
  641. o(new ContainerLoadingFailedError(`[Engine] avatar ${e.id} instanciates failed`));
  642. if (e.attachBody(a),
  643. a.animations.length > 0)
  644. return a.animations.forEach(l=>{
  645. l.stop()
  646. }
  647. ),
  648. e.setAnimations(a.animations),
  649. (s = e.controller) == null || s.playAnimation(e.controller.onPlay, !0),
  650. e.isRender = !0,
  651. e.isInLoadingList = !1,
  652. e.setAvatarVisible(!0),
  653. n(e);
  654. this.loadAnimation(e.avatarType, this._defaultAnims).then(l=>{
  655. if (!l)
  656. return e.removeAvatarFromScene(),
  657. e.isInLoadingList = !1,
  658. o(new AvatarAnimationError);
  659. const u = [];
  660. e.clothesList.length > 0 && e.clothesList.forEach(c=>{
  661. u.push(this.loadDecoration(c.type, c.id, t))
  662. }
  663. ),
  664. Promise.all(u).then(c=>{
  665. var d, _, g, m;
  666. c.forEach(v=>{
  667. if (v && !v.isRender)
  668. e.attachDecoration(v);
  669. else
  670. return e.isInLoadingList = !1,
  671. e.removeAvatarFromScene(),
  672. o(new AvatarAssetLoadingError)
  673. }
  674. ),
  675. e.isRender = !0,
  676. (d = e.controller) == null || d.playAnimation(e.controller.onPlay, e.controller.loop),
  677. e.setAvatarVisible(!0);
  678. const h = avatarLoader.mshPath.get("meshes/ygb.glb")
  679. , f = avatarLoader.matPath.get(avatarResources.ygb.mesh);
  680. h && f ? this.loadExtra(f, h).then(v=>{
  681. var y;
  682. e.isRender = !0,
  683. e.isInLoadingList = !1,
  684. e.distLevel = t,
  685. (y = this._sceneManager) == null || y.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
  686. n(e)
  687. }
  688. ) : (e.isRender = !0,
  689. e.isInLoadingList = !1,
  690. e.distLevel = t,
  691. (_ = this._sceneManager) == null || _.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
  692. n(e)),
  693. (g = this._sceneManager) == null || g.lightComponent.setShadow(e),
  694. e.isInLoadingList = !1,
  695. e.distLevel = t,
  696. (m = this._sceneManager) == null || m.engineRunTimeStats.timeArray_addAvatarToScene.add(Date.now() - r),
  697. n(e)
  698. }
  699. ).catch(()=>o(new AvatarAssetLoadingError(`[Engine] avatar ${e.id} instanciates failed.`)))
  700. }
  701. ).catch(()=>o(new AvatarAssetLoadingError(`[Engine] avatar ${e.id} instanciates failed.`)))
  702. }
  703. ).catch(()=>o(new AvatarAssetLoadingError(`[Engine] avatar ${e.id} instanciates failed.`)))
  704. }
  705. )
  706. }
  707. loadExtra(e, t) {
  708. const r = avatarResources.ygb.name;
  709. return new Promise((n,o)=>{
  710. var a;
  711. (a = this.sceneManager) == null || a.urlTransformer(e).then(s=>{
  712. BABYLON.SceneLoader.LoadAssetContainerAsync("", s, this.scene, null, avatarSetting.fileType).then(l=>{
  713. var c;
  714. this.extraComps.set(r, l.meshes[0]);
  715. const u = new NodeMaterial(`material_${r}`,this._scene,{
  716. emitComments: !1
  717. });
  718. (c = this.sceneManager) == null || c.urlTransformer(t).then(h=>{
  719. u.loadAsync(h).then(()=>{
  720. l.meshes[2].material.dispose(!0, !0),
  721. u.build(!1),
  722. l.meshes[2].material = u,
  723. n(l.meshes[2])
  724. }
  725. )
  726. }
  727. )
  728. }
  729. )
  730. }
  731. )
  732. }
  733. )
  734. }
  735. getAvatarList() {
  736. const e = [];
  737. return this.characterMap.forEach((t,r)=>{
  738. t.forEach((n,o)=>{
  739. e.push(n)
  740. }
  741. )
  742. }
  743. ),
  744. e
  745. }
  746. _debug_avatar() {
  747. var t, r;
  748. console.error("===>currentLODUsers", this.currentLODUsers),
  749. console.error("===>maxLODUsers", this._maxLODUsers),
  750. console.error("===>Loddist", this.getLoDLevels()),
  751. console.error("===> main character loc", (r = (t = this._mainUser) == null ? void 0 : t.rootNode) == null ? void 0 : r.position);
  752. let e = 0;
  753. this.getAvatarList().forEach(n=>{
  754. n.isRender && (console.error(`avatar id : ${n.id},lod ${n.distLevel},is Hide ${n.isHide}, distance ${n.distance}, is pending ${n.isInLoadingList}`),
  755. e++)
  756. }
  757. ),
  758. console.error("========= avatar num", e),
  759. console.error("loop:", this._updateLoopObserver ? "on" : "false", "=> process", this._process, "===> comp", this._processList),
  760. console.error("===>maxLODUsers", this._maxLODUsers)
  761. }
  762. }