XAvatarManager.js 30 KB

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