XAnimationController.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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(skeleton => {
  36. if (!skeleton) return reject(new AvatarAnimationError("animation group does not exist"));
  37. // skeleton是AnimationGroup类型
  38. skeleton = this._mappingSkeleton(skeleton);
  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)
  46. aniType == 1 && (this.iFaceAnim.animGroup = skeleton)
  47. if (!this._playAnimation(aniType)) return reject(
  48. new AvatarAnimationError("[Engine] play animation failed, animtion resource does not match current character"));
  49. this._playEffect(),
  50. this.postObserver = skeleton.onAnimationEndObservable.addOnce(()=>(
  51. this._postprocess(aniType),
  52. resolve(null)
  53. ))
  54. })
  55. })
  56. stopAnimation = (i=0)=>{
  57. var o, s, c, d;
  58. switch (i) {
  59. case 0:
  60. this.iBodyAnim && this.iBodyAnim.animGroup && ((o = this.iBodyAnim) == null || o.animGroup.stop());
  61. break;
  62. case 1:
  63. this.iFaceAnim && this.iFaceAnim.animGroup && ((s = this.iFaceAnim) == null || s.animGroup.stop());
  64. break;
  65. case 2:
  66. this.iBodyAnim && this.iBodyAnim.animGroup && ((c = this.iBodyAnim) == null || c.animGroup.stop()),
  67. this.iFaceAnim && this.iFaceAnim.animGroup && ((d = this.iFaceAnim) == null || d.animGroup.stop());
  68. break
  69. }
  70. }
  71. pauseAnimation = (i=0)=>{
  72. var o, s, c, d;
  73. switch (i) {
  74. case 0:
  75. this.iBodyAnim && this.iBodyAnim.animGroup && ((o = this.iBodyAnim) == null || o.animGroup.pause());
  76. break;
  77. case 1:
  78. this.iFaceAnim && this.iFaceAnim.animGroup && ((s = this.iFaceAnim) == null || s.animGroup.pause());
  79. break;
  80. case 2:
  81. this.iBodyAnim && this.iBodyAnim.animGroup && ((c = this.iBodyAnim) == null || c.animGroup.pause()),
  82. this.iFaceAnim && this.iFaceAnim.animGroup && ((d = this.iFaceAnim) == null || d.animGroup.pause());
  83. break
  84. }
  85. }
  86. resetAnimation = (i=0)=>{
  87. var o, s, c, d;
  88. switch (i) {
  89. case 0:
  90. this.iBodyAnim && this.iBodyAnim.animGroup && ((o = this.iBodyAnim) == null || o.animGroup.reset());
  91. break;
  92. case 1:
  93. this.iFaceAnim && this.iFaceAnim.animGroup && ((s = this.iFaceAnim) == null || s.animGroup.reset());
  94. break;
  95. case 2:
  96. this.iBodyAnim && this.iBodyAnim.animGroup && ((c = this.iBodyAnim) == null || c.animGroup.reset()),
  97. this.iFaceAnim && this.iFaceAnim.animGroup && ((d = this.iFaceAnim) == null || d.animGroup.reset());
  98. break
  99. }
  100. }
  101. _isPlaying(e, i) {
  102. 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)
  103. }
  104. activeAnimation(e=0) {
  105. var i, o;
  106. switch (e) {
  107. case 0:
  108. return (i = this.iBodyAnim) == null ? void 0 : i.animGroup;
  109. case 1:
  110. return (o = this.iFaceAnim) == null ? void 0 : o.animGroup;
  111. default:
  112. return
  113. }
  114. }
  115. enableAnimationBlend(e=.1, i=0) {
  116. var o, s, c, d;
  117. if (i == 0 && ((o = this.iBodyAnim) == null ? void 0 : o.animGroup))
  118. for (const _ of (s = this.iBodyAnim) == null ? void 0 : s.animGroup.targetedAnimations)
  119. _.animation.enableBlending = !0,
  120. _.animation.blendingSpeed = e;
  121. else if (i == 0 && ((c = this.iFaceAnim) == null ? void 0 : c.animGroup))
  122. for (const _ of (d = this.iFaceAnim) == null ? void 0 : d.animGroup.targetedAnimations)
  123. _.animation.enableBlending = !0,
  124. _.animation.blendingSpeed = e
  125. }
  126. disableAnimationBlend(e=0) {
  127. var i, o, s, c;
  128. if (e == 0 && ((i = this.iBodyAnim) == null ? void 0 : i.animGroup))
  129. for (const d of (o = this.iBodyAnim) == null ? void 0 : o.animGroup.targetedAnimations)
  130. d.animation.enableBlending = !1;
  131. else if (e == 0 && ((s = this.iFaceAnim) == null ? void 0 : s.animGroup))
  132. for (const d of (c = this.iFaceAnim) == null ? void 0 : c.animGroup.targetedAnimations)
  133. d.animation.enableBlending = !1
  134. }
  135. skeletonMask(e, aniType=0) {
  136. if (aniType == 0) {
  137. const o = this._lodMask.get(this._avatar.distLevel);
  138. if (o)
  139. for (let s = 0; s < e.targetedAnimations.length; ++s)
  140. o.includes(e.targetedAnimations[s].target.name) || (
  141. e.targetedAnimations.splice(s, 1),
  142. s--
  143. );
  144. return !0
  145. }
  146. return !1
  147. }
  148. detachAnimation(aniType=2) {
  149. switch (aniType) {
  150. case 0:
  151. // 身体动画
  152. this.iBodyAnim && this.iBodyAnim.animGroup && (
  153. this.iBodyAnim.animGroup._parentContainer.xReferenceCount && this.iBodyAnim.animGroup._parentContainer.xReferenceCount--,
  154. this.iBodyAnim.animGroup.stop(),
  155. this.iBodyAnim.animGroup.dispose(),
  156. this.iBodyAnim.animGroup = void 0
  157. );
  158. break;
  159. case 1:
  160. // 脸部动画
  161. this.iFaceAnim && this.iFaceAnim.animGroup && (
  162. this.iFaceAnim.animGroup._parentContainer.xReferenceCount && this.iFaceAnim.animGroup._parentContainer.xReferenceCount--,
  163. this.iFaceAnim.animGroup.stop(),
  164. this.iFaceAnim.animGroup.dispose(),
  165. this.iFaceAnim.animGroup = void 0
  166. );
  167. break;
  168. case 2:
  169. this.iBodyAnim && this.iBodyAnim.animGroup && (
  170. this.iBodyAnim.animGroup._parentContainer.xReferenceCount && this.iBodyAnim.animGroup._parentContainer.xReferenceCount--,
  171. this.iBodyAnim.animGroup.stop(),
  172. this.iBodyAnim.animGroup.dispose(),
  173. this.iBodyAnim.animGroup = void 0
  174. ),
  175. this.iFaceAnim && this.iFaceAnim.animGroup && (
  176. this.iFaceAnim.animGroup._parentContainer.xReferenceCount && this.iFaceAnim.animGroup._parentContainer.xReferenceCount--,
  177. this.iFaceAnim.animGroup.stop(),
  178. this.iFaceAnim.animGroup.dispose(),
  179. this.iFaceAnim.animGroup = void 0
  180. );
  181. break
  182. }
  183. }
  184. blendAnimation() {}
  185. getAnimation(e, i) {
  186. return avatarLoader.animations.get(getAnimationKey(i, e))
  187. }
  188. _mappingSkeleton(animationGroup) {
  189. if (animationGroup) {
  190. const animationGroupClone = animationGroup.clone(animationGroup.name, boneOld => {
  191. const name = boneOld.name.split(" ").length > 2 ? boneOld.name.split(" ")[2] : boneOld.name;
  192. if (this._boneMap.size === (this._avatar.skeleton && this._avatar.skeleton.bones.length)) return this._boneMap.get(name);
  193. {
  194. let bone0 = this._avatar.skeleton &&
  195. this._avatar.skeleton.bones.find(bone => bone.name === boneOld.name || bone.name === boneOld.name.split(" ")[2])
  196. const bone = bone0 && bone0.getTransformNode();
  197. bone && (
  198. bone.name = name,
  199. this._boneMap.set(name, bone)
  200. )
  201. return bone
  202. }
  203. });
  204. animationGroupClone._parentContainer = animationGroup._parentContainer
  205. return animationGroupClone
  206. } else
  207. return
  208. }
  209. removeAnimation(e) {
  210. const i = avatarLoader.containers.get(e.name);
  211. i && (i.dispose(),
  212. avatarLoader.containers.delete(e.name),
  213. avatarLoader.animations.delete(getAnimationKey(e.name, e.skType)))
  214. }
  215. _setPosition(e, i) {
  216. this._avatar.priority === 0 && this._avatar.isRender && e === this.defaultAnimation && e != this.onPlay && !this._avatar.isSelected && this._avatar.setPosition(this._avatar.position, !0)
  217. }
  218. _registerAnimInfo(e, i, o=0, s, c, d) {
  219. const _ = {
  220. name: e,
  221. skType: this._avatar.avatarType,
  222. loop: i,
  223. playSpeed: s,
  224. currentFrame: 0,
  225. startFrame: c,
  226. endFrame: d
  227. };
  228. o == 0 ? this.iBodyAnim == null ? this.iBodyAnim = _ : (this.iBodyAnim.name = e,
  229. this.iBodyAnim.skType = this._avatar.avatarType,
  230. this.iBodyAnim.loop = i,
  231. this.iBodyAnim.playSpeed = s,
  232. this.iBodyAnim.currentFrame = 0,
  233. this.iBodyAnim.startFrame = c,
  234. this.iBodyAnim.endFrame = d) : o == 1 && (this.iFaceAnim == null ? this.iFaceAnim = _ : (this.iFaceAnim.name = e,
  235. this.iFaceAnim.skType = this._avatar.avatarType,
  236. this.iFaceAnim.loop = i,
  237. this.iFaceAnim.playSpeed = s,
  238. this.iFaceAnim.currentFrame = 0,
  239. this.iFaceAnim.startFrame = c,
  240. this.iFaceAnim.endFrame = d)),
  241. this.onPlay = e,
  242. this.loop = i
  243. }
  244. _isAnimate() {
  245. var e;
  246. return !(!this._avatar.isRender || !this._avatar.skeleton || ((e = this._avatar.rootNode) == null ? void 0 : e.getChildMeshes().length) == 0)
  247. }
  248. _prerocess(animationName, isLoop) {
  249. this._avatar.isRayCastEnable && this._setPosition(animationName, isLoop),
  250. this._avatar.priority === 0 && logger.info(`start play animation: ${animationName} on avatar ${this._avatar.id}`)
  251. }
  252. _playEffect() {
  253. this.animationExtras.indexOf(this.iBodyAnim.name) != -1 && action.Cheering.attachPair.forEach(i=>{
  254. 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)),
  255. this._avatar.showExtra(i.obj)
  256. }
  257. )
  258. }
  259. _playAnimation(aniType=0) {
  260. return aniType == 0 && this.iBodyAnim && this.iBodyAnim.animGroup ? (
  261. // 身体动画
  262. this.onPlayObservable.notifyObservers(this._scene),
  263. this.iBodyAnim.animGroup.start(this.loop, this.iBodyAnim.playSpeed, this.iBodyAnim.startFrame, this.iBodyAnim.endFrame, !1),
  264. !0
  265. ) : aniType == 1 && this.iFaceAnim && this.iFaceAnim.animGroup ? (
  266. // 脸部动画
  267. this.iFaceAnim.animGroup.start(this.loop, this.iFaceAnim.playSpeed, this.iFaceAnim.startFrame, this.iFaceAnim.endFrame, !1),
  268. !0
  269. ) : !1
  270. }
  271. _postprocess(e) {
  272. var o, s;
  273. let i;
  274. e == 0 ? i = (o = this.iBodyAnim) == null ? void 0 : o.name : e == 1 && (i = (s = this.iFaceAnim) == null ? void 0 : s.name),
  275. i === action.Cheering.animName && this._avatar.disposeExtra()
  276. }
  277. _isAnimationValid(skeleton) {
  278. for (let i = 0; i < skeleton.targetedAnimations.length; ++i)
  279. if (skeleton.targetedAnimations[i].target)
  280. return !1;
  281. return !0
  282. }
  283. }