XAvatarManager.js 30 KB

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