XAnimationController.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import {avatarLoader} from "./XAvatarLoader.js"
  2. import AvatarAnimationError from "./error/AvatarAnimationError.js"
  3. import Logger from "./Logger.js"
  4. const logger = new Logger('AnimationController')
  5. export default class XAnimationController {
  6. constructor(avatar) {
  7. this.iBodyAnim = void 0,
  8. this.animations = [],
  9. this.defaultAnimation = "Idle",
  10. this.onPlay = "Idle",
  11. this.loop = !0,
  12. this.animationExtras = [],
  13. this.enableBlend = !1,
  14. this.enableSkLod = !1,
  15. this._boneMap = new Map,
  16. this._lodMask = new Map,
  17. this.activeFaceAnimation = void 0,
  18. this.iFaceAnim = void 0,
  19. this.onPlayObservable = new Observable,
  20. this._avatar = avatar,
  21. this._scene = avatar.avatarManager.scene,
  22. this.animationExtras.push(action.Cheering.animName),
  23. this._boneMap = new Map
  24. }
  25. // aniType :0 身体动画 :1 脸部动画
  26. playAnimation = (animationName, isLoop, aniType=0, c, d, _)=>new Promise((resolve, reject)=>{
  27. // zeg 传入i为任意动画名即可播放该动画,比如"GiftClap"
  28. // window.room.avatarManager.avatars.get(window.room.userId).playAnimation({"animationName": "GiftClap", "loop":true})
  29. if (
  30. this._isPlaying(animationName, aniType) ||
  31. (this._registerAnimInfo(animationName, isLoop, aniType, c, d, _), !this._isAnimate())
  32. )
  33. return resolve(null);
  34. this._prerocess(animationName, isLoop),
  35. this._avatar.avatarManager.loadAnimation(this._avatar.avatarType, animationName).then(animationGroup => {
  36. if (!animationGroup) return reject(new AvatarAnimationError("animation group does not exist"));
  37. // 实际上skeleton还是AnimationGroup类型
  38. const skeleton = this._mappingSkeleton(animationGroup);
  39. if (!skeleton) return reject(new AvatarAnimationError("mapping animation failed"))
  40. if (skeleton && this._isAnimationValid(skeleton))
  41. return skeleton.dispose(),
  42. reject(new AvatarAnimationError("mapping animation failed"));
  43. this.enableSkLod && this.skeletonMask(skeleton, aniType)
  44. this.detachAnimation(aniType)
  45. aniType == 0 ? this.iBodyAnim.animGroup = skeleton : aniType == 1 && (this.iFaceAnim.animGroup = skeleton)
  46. if (!this._playAnimation(aniType))
  47. return reject(new AvatarAnimationError("[Engine] play animation failed, animtion resource does not match current character"));
  48. this._playEffect(),
  49. this.postObserver = skeleton.onAnimationEndObservable.addOnce(()=>(
  50. this._postprocess(aniType),
  51. resolve(null)
  52. ))
  53. })
  54. })
  55. stopAnimation = (i=0)=>{
  56. var o, s, c, d;
  57. switch (i) {
  58. case 0:
  59. this.iBodyAnim && this.iBodyAnim.animGroup && ((o = this.iBodyAnim) == null || o.animGroup.stop());
  60. break;
  61. case 1:
  62. this.iFaceAnim && this.iFaceAnim.animGroup && ((s = this.iFaceAnim) == null || s.animGroup.stop());
  63. break;
  64. case 2:
  65. this.iBodyAnim && this.iBodyAnim.animGroup && ((c = this.iBodyAnim) == null || c.animGroup.stop()),
  66. this.iFaceAnim && this.iFaceAnim.animGroup && ((d = this.iFaceAnim) == null || d.animGroup.stop());
  67. break
  68. }
  69. }
  70. pauseAnimation = (i=0)=>{
  71. var o, s, c, d;
  72. switch (i) {
  73. case 0:
  74. this.iBodyAnim && this.iBodyAnim.animGroup && ((o = this.iBodyAnim) == null || o.animGroup.pause());
  75. break;
  76. case 1:
  77. this.iFaceAnim && this.iFaceAnim.animGroup && ((s = this.iFaceAnim) == null || s.animGroup.pause());
  78. break;
  79. case 2:
  80. this.iBodyAnim && this.iBodyAnim.animGroup && ((c = this.iBodyAnim) == null || c.animGroup.pause()),
  81. this.iFaceAnim && this.iFaceAnim.animGroup && ((d = this.iFaceAnim) == null || d.animGroup.pause());
  82. break
  83. }
  84. }
  85. resetAnimation = (i=0)=>{
  86. var o, s, c, d;
  87. switch (i) {
  88. case 0:
  89. this.iBodyAnim && this.iBodyAnim.animGroup && ((o = this.iBodyAnim) == null || o.animGroup.reset());
  90. break;
  91. case 1:
  92. this.iFaceAnim && this.iFaceAnim.animGroup && ((s = this.iFaceAnim) == null || s.animGroup.reset());
  93. break;
  94. case 2:
  95. this.iBodyAnim && this.iBodyAnim.animGroup && ((c = this.iBodyAnim) == null || c.animGroup.reset()),
  96. this.iFaceAnim && this.iFaceAnim.animGroup && ((d = this.iFaceAnim) == null || d.animGroup.reset());
  97. break
  98. }
  99. }
  100. _isPlaying(e, i) {
  101. return i == 0 && this.iBodyAnim != null && this.iBodyAnim.animGroup && e == this.iBodyAnim.name ? !0 : !!(i == 1 && this.iFaceAnim != null && this.iFaceAnim.animGroup && e == this.iFaceAnim.name)
  102. }
  103. activeAnimation(e=0) {
  104. var i, o;
  105. switch (e) {
  106. case 0:
  107. return (i = this.iBodyAnim) == null ? void 0 : i.animGroup;
  108. case 1:
  109. return (o = this.iFaceAnim) == null ? void 0 : o.animGroup;
  110. default:
  111. return
  112. }
  113. }
  114. enableAnimationBlend(e=.1, i=0) {
  115. var o, s, c, d;
  116. if (i == 0 && ((o = this.iBodyAnim) == null ? void 0 : o.animGroup))
  117. for (const _ of (s = this.iBodyAnim) == null ? void 0 : s.animGroup.targetedAnimations)
  118. _.animation.enableBlending = !0,
  119. _.animation.blendingSpeed = e;
  120. else if (i == 0 && ((c = this.iFaceAnim) == null ? void 0 : c.animGroup))
  121. for (const _ of (d = this.iFaceAnim) == null ? void 0 : d.animGroup.targetedAnimations)
  122. _.animation.enableBlending = !0,
  123. _.animation.blendingSpeed = e
  124. }
  125. disableAnimationBlend(e=0) {
  126. var i, o, s, c;
  127. if (e == 0 && ((i = this.iBodyAnim) == null ? void 0 : i.animGroup))
  128. for (const d of (o = this.iBodyAnim) == null ? void 0 : o.animGroup.targetedAnimations)
  129. d.animation.enableBlending = !1;
  130. else if (e == 0 && ((s = this.iFaceAnim) == null ? void 0 : s.animGroup))
  131. for (const d of (c = this.iFaceAnim) == null ? void 0 : c.animGroup.targetedAnimations)
  132. d.animation.enableBlending = !1
  133. }
  134. skeletonMask(e, i=0) {
  135. if (i == 0) {
  136. const o = this._lodMask.get(this._avatar.distLevel);
  137. if (o)
  138. for (let s = 0; s < e.targetedAnimations.length; ++s)
  139. o.includes(e.targetedAnimations[s].target.name) || (e.targetedAnimations.splice(s, 1),
  140. s--);
  141. return !0
  142. }
  143. return !1
  144. }
  145. detachAnimation(e=2) {
  146. var i, o;
  147. switch (e) {
  148. case 0:
  149. this.iBodyAnim && this.iBodyAnim.animGroup && (this.iBodyAnim.animGroup._parentContainer.xReferenceCount && this.iBodyAnim.animGroup._parentContainer.xReferenceCount--,
  150. this.iBodyAnim.animGroup.stop(),
  151. this.iBodyAnim.animGroup.dispose(),
  152. this.iBodyAnim.animGroup = void 0);
  153. break;
  154. case 1:
  155. this.iFaceAnim && this.iFaceAnim.animGroup && (this.iFaceAnim.animGroup._parentContainer.xReferenceCount && this.iFaceAnim.animGroup._parentContainer.xReferenceCount--,
  156. this.iFaceAnim.animGroup.stop(),
  157. this.iFaceAnim.animGroup.dispose(),
  158. this.iFaceAnim.animGroup = void 0);
  159. break;
  160. case 2:
  161. this.iBodyAnim && this.iBodyAnim.animGroup && (this.iBodyAnim.animGroup._parentContainer.xReferenceCount && this.iBodyAnim.animGroup._parentContainer.xReferenceCount--,
  162. (i = this.iBodyAnim) == null || i.animGroup.stop(),
  163. (o = this.iBodyAnim) == null || o.animGroup.dispose(),
  164. this.iBodyAnim.animGroup = void 0),
  165. this.iFaceAnim && this.iFaceAnim.animGroup && (this.iFaceAnim.animGroup._parentContainer.xReferenceCount && this.iFaceAnim.animGroup._parentContainer.xReferenceCount--,
  166. this.iFaceAnim.animGroup.stop(),
  167. this.iFaceAnim.animGroup.dispose(),
  168. this.iFaceAnim.animGroup = void 0);
  169. break
  170. }
  171. }
  172. blendAnimation() {}
  173. getAnimation(e, i) {
  174. return avatarLoader.animations.get(getAnimationKey(i, e))
  175. }
  176. _mappingSkeleton(animationGroup) {
  177. if (animationGroup) {
  178. const animationGroupClone = animationGroup.clone(animationGroup.name, boneOld => {
  179. const name = boneOld.name.split(" ").length > 2 ? boneOld.name.split(" ")[2] : boneOld.name;
  180. if (this._boneMap.size === (this._avatar.skeleton && this._avatar.skeleton.bones.length)) return this._boneMap.get(name);
  181. {
  182. let bone0 = this._avatar.skeleton && this._avatar.skeleton.bones.find(bone => bone.name === boneOld.name || bone.name === boneOld.name.split(" ")[2])
  183. const bone = bone0 && bone0.getTransformNode();
  184. bone && (
  185. bone.name = name,
  186. this._boneMap.set(name, bone)
  187. )
  188. return bone
  189. }
  190. });
  191. animationGroupClone._parentContainer = animationGroup._parentContainer
  192. return animationGroupClone
  193. } else
  194. return
  195. }
  196. removeAnimation(e) {
  197. const i = avatarLoader.containers.get(e.name);
  198. i && (i.dispose(),
  199. avatarLoader.containers.delete(e.name),
  200. avatarLoader.animations.delete(getAnimationKey(e.name, e.skType)))
  201. }
  202. _setPosition(e, i) {
  203. this._avatar.priority === 0 && this._avatar.isRender && e === this.defaultAnimation && e != this.onPlay && !this._avatar.isSelected && this._avatar.setPosition(this._avatar.position, !0)
  204. }
  205. _registerAnimInfo(e, i, o=0, s, c, d) {
  206. const _ = {
  207. name: e,
  208. skType: this._avatar.avatarType,
  209. loop: i,
  210. playSpeed: s,
  211. currentFrame: 0,
  212. startFrame: c,
  213. endFrame: d
  214. };
  215. o == 0 ? this.iBodyAnim == null ? this.iBodyAnim = _ : (this.iBodyAnim.name = e,
  216. this.iBodyAnim.skType = this._avatar.avatarType,
  217. this.iBodyAnim.loop = i,
  218. this.iBodyAnim.playSpeed = s,
  219. this.iBodyAnim.currentFrame = 0,
  220. this.iBodyAnim.startFrame = c,
  221. this.iBodyAnim.endFrame = d) : o == 1 && (this.iFaceAnim == null ? this.iFaceAnim = _ : (this.iFaceAnim.name = e,
  222. this.iFaceAnim.skType = this._avatar.avatarType,
  223. this.iFaceAnim.loop = i,
  224. this.iFaceAnim.playSpeed = s,
  225. this.iFaceAnim.currentFrame = 0,
  226. this.iFaceAnim.startFrame = c,
  227. this.iFaceAnim.endFrame = d)),
  228. this.onPlay = e,
  229. this.loop = i
  230. }
  231. _isAnimate() {
  232. var e;
  233. return !(!this._avatar.isRender || !this._avatar.skeleton || ((e = this._avatar.rootNode) == null ? void 0 : e.getChildMeshes().length) == 0)
  234. }
  235. _prerocess(e, i) {
  236. this._avatar.isRayCastEnable && this._setPosition(e, i),
  237. this._avatar.priority === 0 && logger.info(`start play animation: ${e} on avatar ${this._avatar.id}`)
  238. }
  239. _playEffect() {
  240. this.animationExtras.indexOf(this.iBodyAnim.name) != -1 && action.Cheering.attachPair.forEach(i=>{
  241. this._avatar.attachExtraProp(i.obj, i.bone, new Vector3(i.offset.x,i.offset.y,i.offset.z), new Vector3(i.rotate.x,i.rotate.y,i.rotate.z)),
  242. this._avatar.showExtra(i.obj)
  243. }
  244. )
  245. }
  246. _playAnimation(e=0) {
  247. return e == 0 && this.iBodyAnim && this.iBodyAnim.animGroup ? (
  248. // 身体动画
  249. this.onPlayObservable.notifyObservers(this._scene),
  250. this.iBodyAnim.animGroup.start(this.loop, this.iBodyAnim.playSpeed, this.iBodyAnim.startFrame, this.iBodyAnim.endFrame, !1),
  251. !0
  252. ) : e == 1 && this.iFaceAnim && this.iFaceAnim.animGroup ? (
  253. // 脸部动画
  254. this.iFaceAnim.animGroup.start(this.loop, this.iFaceAnim.playSpeed, this.iFaceAnim.startFrame, this.iFaceAnim.endFrame, !1),
  255. !0
  256. ) : !1
  257. }
  258. _postprocess(e) {
  259. var o, s;
  260. let i;
  261. e == 0 ? i = (o = this.iBodyAnim) == null ? void 0 : o.name : e == 1 && (i = (s = this.iFaceAnim) == null ? void 0 : s.name),
  262. i === action.Cheering.animName && this._avatar.disposeExtra()
  263. }
  264. _isAnimationValid(e) {
  265. for (let i = 0; i < e.targetedAnimations.length; ++i)
  266. if (e.targetedAnimations[i].target)
  267. return !1;
  268. return !0
  269. }
  270. }