XAvatar.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. import BillboardStatus from "./enum/BillboardStatus.js"
  2. import {avatarLoader} from "./XAvatarLoader.js"
  3. import XAnimationController from "./XAnimationController.js"
  4. import XAvatarComopnent from "./XAvatarComopnent.js"
  5. import XAvatarBillboardComponent from "./XAvatarBillboardComponent.js"
  6. import XActor from "./XActor.js"
  7. import XMovementComponent from "./XMovementComponent.js"
  8. import Logger from "./Logger.js"
  9. const logger = new Logger('Avatar')
  10. export default class XAvatar extends XActor{
  11. constructor({id: o, avatarType: s, priority: c, avatarManager: _, assets: b, status: k}) {
  12. var $;
  13. super(),
  14. this.id = "-1",
  15. this.priority = 0,
  16. this.isRender = !1,
  17. this.distLevel = 0,
  18. this.isInLoadingList = !1,
  19. this.isHide = !1,
  20. this.isSelected = !1,
  21. this.pendingLod = !1,
  22. this.isMoving = !1,
  23. this.rootNode = void 0,
  24. this.distToCam = 1e11,
  25. this.enableNickname = !0,
  26. this.distance = 1e11,
  27. this.isCulling = !1,
  28. this.reslevel = 0,
  29. this.isInLoadingQueue = !1,
  30. this._scene = void 0,
  31. this._transparent = 0,
  32. this.hide = ()=>(this.isHide = !0,
  33. this._hide(),
  34. !this.isRender),
  35. this._show = ()=>{
  36. var _e;
  37. this.isHide || (this.setIsPickable(!0),
  38. this.bbComponent._attachmentObservers.forEach((et,tt)=>{
  39. tt.setEnabled(!0)
  40. }
  41. ),
  42. this.priority == 0 && (this.rootNode.setEnabled(!0),
  43. this.isRender = !0,
  44. this.avatarManager._updateBillboardStatus(this, BillboardStatus.SHOW),
  45. this.component.accessoryMap.forEach(et=>{
  46. et.rootComponent.setEnabled(!0)
  47. }
  48. ),
  49. (_e = this.controller) == null || _e.playAnimation(this.controller.onPlay, this.controller.loop)),
  50. this.component.accessoryMap.forEach(et=>{
  51. et.rootComponent.setEnabled(!0)
  52. }
  53. ))
  54. }
  55. ,
  56. this.show = ()=>(this.isHide = !1,
  57. this._show(),
  58. !!this.isRender),
  59. this.setAnimations = _e=>{
  60. this.controller.animations = _e
  61. }
  62. ,
  63. this.attachToAvatar = (_e,et=!1,tt={
  64. x: 0,
  65. y: 0,
  66. z: 0
  67. },rt=!1,it,nt)=>this.bbComponent.attachToAvatar(this, _e, et, tt, rt, nt),
  68. this.detachFromAvatar = (_e,et=!1)=>this.bbComponent.detachFromAvatar(this, _e, et),
  69. this.getBbox = (_e={})=>this.bbComponent.getBbox(this, _e),
  70. this.id = o,
  71. this._avatarManager = _,
  72. this._scene = this.avatarManager.scene,
  73. this._avatarType = s,
  74. this.priority = c || 0,
  75. this.controller = new XAnimationController(this),
  76. this.component = new XAvatarComopnent,
  77. this.component.updateAssetList(b);
  78. const j = ($ = this.assetList.find(_e=>_e.type === "ANIMATION")) == null ? void 0 : $.id;
  79. this.controller.onPlay = this.controller.defaultAnimation = j,
  80. this.bbComponent = new XAvatarBillboardComponent(this._scene),
  81. this.rootNode = new BABYLON.TransformNode(o,this._avatarManager.scene),
  82. this._avatarScale = k.avatarScale == null ? 1 : k.avatarScale,
  83. this._avatarRotation = k.avatarRotation == null ? {
  84. pitch: 0,
  85. yaw: 0,
  86. roll: 0
  87. } : k.avatarRotation,
  88. this._avatarPosition = k.avatarPosition == null ? {
  89. x: 0,
  90. y: 0,
  91. z: 0
  92. } : k.avatarPosition,
  93. this._isRayCastEnable = avatarSetting.isRayCastEnable,
  94. this.movementComponent = new XMovementComponent(this._avatarManager.sceneManager),
  95. this.movementComponent.registerTo(this),
  96. this._isRayCastEnable = avatarSetting.isRayCastEnable,
  97. this.movementComponent.updatePosition(this._avatarPosition, !0),
  98. this.setRotation(this._avatarRotation),
  99. this.setScale(this.scale),
  100. this._observer = this._scene.onBeforeRenderObservable.add(()=>{
  101. this.tick()
  102. }
  103. )
  104. }
  105. tick() {
  106. this.cullingTick()
  107. }
  108. cullingTick() {
  109. var o;
  110. this.isCulling && ((o = this.rootNode) == null || o.getChildMeshes().forEach(s=>{
  111. this.distToCam < 50 ? s.visibility = 0 : s.visibility = this._transparent
  112. }
  113. ))
  114. }
  115. setMaterial(o) {
  116. var s;
  117. (s = this.rootNode) == null || s.getChildMeshes().forEach(c=>{
  118. c.material instanceof BABYLON.NodeMaterial && c.material.getInputBlocks().forEach(_=>{
  119. _._storedValue instanceof BABYLON.Color3 && (_._storedValue = new BABYLON.Color3)
  120. }
  121. )
  122. }
  123. )
  124. }
  125. get assetList() {
  126. return this.component.assetList
  127. }
  128. setTransParentThresh(o) {
  129. this._transparent = o
  130. }
  131. get isNameVisible() {
  132. return this.bbComponent.isNameVisible
  133. }
  134. get isBubbleVisible() {
  135. return this.bbComponent.isBubbleVisible
  136. }
  137. get isGiftButtonsVisible() {
  138. return this.bbComponent.isGiftButtonsVisible
  139. }
  140. get words() {
  141. return this.bbComponent.words
  142. }
  143. get nickName() {
  144. return this.bbComponent.nickName
  145. }
  146. get giftButtons() {
  147. return this.bbComponent.giftButtons
  148. }
  149. get bubble() {
  150. return this.bbComponent.bubble
  151. }
  152. get nameBoard() {
  153. return this.bbComponent.nameBoard
  154. }
  155. get avatarManager() {
  156. return this._avatarManager
  157. }
  158. set withinVisibleRange(o) {
  159. this.bbComponent.withinVisualRange = o
  160. }
  161. setNicknameStatus(o) {
  162. return this.bbComponent.setNicknameStatus(o)
  163. }
  164. setBubbleStatus(o) {
  165. return this.bbComponent.setBubbleStatus(o)
  166. }
  167. setButtonsStatus(o) {
  168. return this.bbComponent.setButtonsStatus(o)
  169. }
  170. setGiftButtonsVisible(o) {
  171. return this.bbComponent.setGiftButtonsVisible(o)
  172. }
  173. get avatarType() {
  174. return this._avatarType
  175. }
  176. attachBody(o) {
  177. return this.component.addBodyComp(this, o)
  178. }
  179. attachDecoration(o) {
  180. return this.component.addClothesComp(this, o)
  181. }
  182. detachDecoration(o) {
  183. return this.component.clearClothesComp(o)
  184. }
  185. detachDecorationAll() {
  186. return this.component.disposeDress()
  187. }
  188. get skeleton() {
  189. return this.component.skeleton
  190. }
  191. get position() {
  192. return this._avatarPosition
  193. }
  194. get rotation() {
  195. return this._avatarRotation
  196. }
  197. get scale() {
  198. return this._avatarScale
  199. }
  200. _hide_culling() {
  201. this.bbComponent.updateBillboardStatus(this, BillboardStatus.HIDE),
  202. this.isCulling = !0
  203. }
  204. _show_culling() {
  205. this.isCulling && (this.rootNode && this.rootNode.getChildMeshes().forEach(o=>{
  206. o.visibility = 1
  207. }
  208. ),
  209. this.bbComponent.updateBillboardStatus(this, BillboardStatus.SHOW),
  210. this.isCulling = !1)
  211. }
  212. get clothesList() {
  213. return this.assetList.filter(o=>o.type != avatarSetting.animations && o.type != avatarSetting.skeleton)
  214. }
  215. _hide() {
  216. !this.isHide || (this.setIsPickable(!1),
  217. this.bbComponent._attachmentObservers.forEach((o,s)=>{
  218. s.setEnabled(!1)
  219. }
  220. ),
  221. this.priority == 0 ? (this.rootNode.setEnabled(!1),
  222. this.isRender = !1,
  223. this.bbComponent.updateBillboardStatus(this, BillboardStatus.HIDE),
  224. this.component.accessoryMap.forEach(o=>{
  225. o.rootComponent.setEnabled(!1)
  226. }
  227. )) : this.isRender && (this.avatarManager.currentLODUsers[this.distLevel]--,
  228. this.removeAvatarFromScene()),
  229. this.component.accessoryMap.forEach(o=>{
  230. o.rootComponent.setEnabled(!1)
  231. }
  232. ))
  233. }
  234. rotate(o, s, c) {
  235. return this.movementComponent.roll(this, o, s, c)
  236. }
  237. set isRayCastEnable(o) {
  238. this._isRayCastEnable = o
  239. }
  240. get isRayCastEnable() {
  241. return this._isRayCastEnable
  242. }
  243. getAvatarId() {
  244. return this.id
  245. }
  246. getAvaliableAnimations() {
  247. const o = avatarLoader.avaliableAnimation.get(this.avatarType);
  248. return o || []
  249. }
  250. setPosition(o) {
  251. var c;
  252. this._avatarPosition = o;
  253. const s = Date.now();
  254. return this.rootNode && (this.rootNode.position = ue4Position2Xverse(this._avatarPosition)),
  255. (c = this.avatarManager.sceneManager) == null || c.engineRunTimeStats.timeArray_setPosition.add(Date.now() - s),
  256. Promise.resolve(o)
  257. }
  258. setRotation(o) {
  259. if (this._avatarRotation = o,
  260. this.rootNode) {
  261. const s = {
  262. pitch: o.pitch,
  263. yaw: o.yaw + 180,
  264. roll: o.roll
  265. }
  266. , c = ue4Rotation2Xverse(s);
  267. this.rootNode.rotation = c
  268. }
  269. }
  270. setAvatarVisible(o) {
  271. this.rootNode && (this.rootNode.setEnabled(o),
  272. this.rootNode.getChildMeshes().forEach(s=>{
  273. s.setEnabled(o)
  274. }
  275. ))
  276. }
  277. setScale(o) {
  278. this._avatarScale = o,
  279. this.rootNode && (this.rootNode.scaling = new BABYLON.Vector3(o,o,o)),
  280. this.bbComponent.bbox && this.getBbox()
  281. }
  282. _removeAvatarFromScene(o=!1) {
  283. var s, c;
  284. this.component.accessoryMap.forEach(_=>{
  285. _.detachFrom(!1),
  286. _.rootComponent.setEnabled(!1)
  287. }
  288. ),
  289. this.isRender = !1,
  290. this.component.dispose(o),
  291. o && ((s = this.controller) == null || s.detachAnimation(),
  292. (c = this.avatarManager.sceneManager) == null || c.lightComponent.removeShadow(this))
  293. }
  294. removeAvatarFromScene() {
  295. var s;
  296. this.component.accessoryMap.forEach(c=>{
  297. c.dispose()
  298. }
  299. ),
  300. this.component.accessoryMap.clear();
  301. const o = Date.now();
  302. this._removeAvatarFromScene(!0),
  303. this._disposeBillBoard(),
  304. (s = this.avatarManager.sceneManager) == null || s.engineRunTimeStats.timeArray_removeAvatarFromScene.add(Date.now() - o)
  305. }
  306. _disposeBillBoard() {
  307. this.bbComponent.disposeBillBoard(this)
  308. }
  309. addComponent(o, s) {
  310. switch (s) {
  311. case EDressType.PENDANT:
  312. return this.component.attachPendant(this, o);
  313. case (EDressType.BODY || EDressType.CLOTHES || EDressType.HAIR || EDressType.HEAD || EDressType.SHOES || EDressType.SUIT):
  314. return this.component.changeClothesComp(this, o, s);
  315. default:
  316. return Promise.reject("this type cannot add")
  317. }
  318. }
  319. removeComponent(o, s) {
  320. o === EDressType.PENDANT ? s ? this.component.detachPendant(s) : this.component.accessoryMap.forEach((c,_)=>{
  321. this.component.detachPendant(_)
  322. }
  323. ) : this.component.dressMap.forEach((c,_)=>{
  324. c.asset && c.asset.dispose()
  325. }
  326. )
  327. }
  328. getComponentByType(o, s) {
  329. if (o === EDressType.PENDANT)
  330. if (s) {
  331. const c = this.component.accessoryMap.get(s);
  332. return c || []
  333. } else
  334. return Array.from(this.component.accessoryMap).map(c=>c[1]);
  335. else {
  336. const c = [];
  337. return this.component.dressMap.forEach((_,b)=>{
  338. _.type == o && c.push(_)
  339. }
  340. ),
  341. c
  342. }
  343. }
  344. setPickBoxScale(o) {
  345. return this.bbComponent.setPickBoxScale(o)
  346. }
  347. setIsPickable(o) {
  348. return this.bbComponent.setIsPickable(this, o)
  349. }
  350. createPickBoundingbox(o) {
  351. return this.bbComponent.createPickBoundingbox(this, o)
  352. }
  353. scaleBbox(o) {
  354. this.bbComponent.bbox && this.bbComponent.bbox.scale(o)
  355. }
  356. rotateTo(o, s, c) {
  357. return this.movementComponent.rotateTo(this, o, s, c)
  358. }
  359. faceTo(o, s) {
  360. return this.movementComponent.lookAt(this, o, s)
  361. }
  362. removeObserver() {
  363. this._observer && (this._observer.unregisterOnNextCall = !0),
  364. this.movementComponent.disposeObsever(),
  365. this.dispose()
  366. }
  367. moveHermite(o, s, c, _, b, k, j=!0) {
  368. return this.movementComponent.moveToHermite(this, o, s, c, _, b, k, j)
  369. }
  370. moveCardinal(o, s, c, _, b, k, j=!1, $=!0) {
  371. return this.movementComponent.moveToCardinal(this, o, s, c, _, b, k, j, $)
  372. }
  373. move(o, s, c, _, b, k=!1, j=!0) {
  374. return this.movementComponent.moveTo(this, o, s, c, _, b, k, j)
  375. }
  376. initNameboard(o=1) {
  377. return this.bbComponent.initNameboard(this, o)
  378. }
  379. initBubble(o=1) {
  380. return this.bbComponent.initBubble(this, o)
  381. }
  382. say(o, {id: s, isUser: c, background: _, font: b="Arial", fontsize: k=38, fontcolor: j="#ffffff", fontstyle: $="bold", linesize: _e=22, linelimit: et, offsets: tt={
  383. x: 0,
  384. y: 0,
  385. z: 55
  386. }, scale: rt=this._avatarScale, compensationZ: it=11.2, reregistAnyway: nt=!0}) {
  387. return this.bbComponent.say(this, o, {
  388. id: s,
  389. isUser: c,
  390. background: _,
  391. font: b,
  392. fontsize: k,
  393. fontcolor: j,
  394. fontstyle: $,
  395. linesize: _e,
  396. linelimit: et,
  397. offsets: tt,
  398. scale: rt,
  399. compensationZ: it,
  400. reregistAnyway: nt
  401. })
  402. }
  403. silent() {
  404. return this.bbComponent.silent()
  405. }
  406. setNickName(o, {id: s, isUser: c, background: _, font: b="Arial", fontsize: k=40, fontcolor: j="#ffffff", fontstyle: $="bold", linesize: _e=22, linelimit: et, offsets: tt={
  407. x: 0,
  408. y: 0,
  409. z: 30
  410. }, scale: rt=this._avatarScale, compensationZ: it=0, reregistAnyway: nt=!1}) {
  411. return this.bbComponent.setNickName(this, o, {
  412. id: s,
  413. isUser: c,
  414. background: _,
  415. font: b,
  416. fontsize: k,
  417. fontcolor: j,
  418. fontstyle: $,
  419. linesize: _e,
  420. linelimit: et,
  421. offsets: tt,
  422. scale: rt,
  423. compensationZ: it,
  424. reregistAnyway: nt
  425. })
  426. }
  427. generateButtons(o=null, s=this._avatarScale, c=100) {
  428. return this.bbComponent.generateButtons(this, o, s, c)
  429. }
  430. clearButtons() {
  431. return this.bbComponent.clearButtons()
  432. }
  433. getSkeletonPositionByName(o) {
  434. var s;
  435. if (this.skeleton) {
  436. const c = this.skeleton.bones.find(_=>_.name.replace("Clone of ", "") == o);
  437. if (c && c.getTransformNode() && ((s = c.getTransformNode()) == null ? void 0 : s.position)) {
  438. const _ = c.getTransformNode().position;
  439. return xversePosition2Ue4({
  440. x: _.x,
  441. y: _.y,
  442. z: _.z
  443. })
  444. }
  445. }
  446. }
  447. shootTo(o, s, c=2, _=10, b={
  448. x: 0,
  449. y: 0,
  450. z: 150
  451. }) {
  452. return this.movementComponent.sendObjectTo(this, o, s, c, _, b)
  453. }
  454. generateShowName(o) {
  455. return o.split("_")[1]
  456. }
  457. getMaterialInput() {
  458. const o = new Map;
  459. return this.rootNode && this.rootNode.getChildMeshes()[3].material instanceof BABYLON.NodeMaterial && this.rootNode.getChildMeshes()[3].material.getInputBlocks().forEach(s=>{
  460. s.name.includes("Editable") && (s._storedValue instanceof BABYLON.Color3 || s._storedValue instanceof BABYLON.Color4 ? o.set(this.generateShowName(s.name), s._storedValue.asArray()) : o.set(this.generateShowName(s.name), s._storedValue))
  461. }
  462. ),
  463. o
  464. }
  465. setMaterialInput(o, s) {
  466. s ? this.assetList.forEach(c=>{
  467. c.id == s && (c.materialConfig = o)
  468. }
  469. ) : (this.component.assetList.forEach(c=>{
  470. const _ = this.component.dressMap.get(c.id);
  471. _ && _.asset.material instanceof BABYLON.NodeMaterial && o.forEach((b,k)=>{
  472. const j = _.asset.material.getInputBlockByPredicate($=>$.name == generateOriginalName(k));
  473. j && (b.length == 1 ? j._storedValue = b : b.length == 3 ? j._storedValue = BABYLON.Color3.FromArray(b) : b.length == 4 && (j._storedValue = BABYLON.Color3.FromArray(b.slice(0, 3))))
  474. }
  475. )
  476. }
  477. ),
  478. this.assetList.forEach(c=>{
  479. c.materialConfig = o
  480. }
  481. ))
  482. }
  483. }