modelAnimation.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { AnimationGroup, Animatable, Skeleton, IDisposable } from "babylonjs";
  2. export enum AnimationPlayMode {
  3. ONCE,
  4. LOOP
  5. }
  6. export enum AnimationState {
  7. INIT,
  8. PLAYING,
  9. PAUSED,
  10. STOPPED,
  11. ENDED
  12. }
  13. export interface IModelAnimation extends IDisposable {
  14. readonly state: AnimationState;
  15. readonly name: string;
  16. readonly frames: number;
  17. readonly currentFrame: number;
  18. readonly fps: number;
  19. speedRatio: number;
  20. playMode: AnimationPlayMode;
  21. start();
  22. stop();
  23. pause();
  24. reset();
  25. restart();
  26. goToFrame(frameNumber: number);
  27. }
  28. export class GroupModelAnimation implements IModelAnimation {
  29. private _playMode: AnimationPlayMode;
  30. private _state: AnimationState;
  31. constructor(private _animationGroup: AnimationGroup) {
  32. this._state = AnimationState.INIT;
  33. this._playMode = AnimationPlayMode.LOOP;
  34. this._animationGroup.onAnimationEndObservable.add(() => {
  35. this.stop();
  36. this._state = AnimationState.ENDED;
  37. })
  38. }
  39. public get name() {
  40. return this._animationGroup.name;
  41. }
  42. public get state() {
  43. return this._state;
  44. }
  45. /**
  46. * Gets or sets the speed ratio to use for all animations
  47. */
  48. public get speedRatio(): number {
  49. return this._animationGroup.speedRatio;
  50. }
  51. /**
  52. * Gets or sets the speed ratio to use for all animations
  53. */
  54. public set speedRatio(value: number) {
  55. this._animationGroup.speedRatio = value;
  56. }
  57. public get frames(): number {
  58. let animationFrames = this._animationGroup.targetedAnimations.map(ta => {
  59. let keys = ta.animation.getKeys();
  60. return keys[keys.length - 1].frame;
  61. });
  62. return Math.max.apply(null, animationFrames);
  63. }
  64. public get currentFrame(): number {
  65. // get the first currentFrame found
  66. for (let i = 0; i < this._animationGroup['_animatables'].length; ++i) {
  67. let animatable: Animatable = this._animationGroup['_animatables'][i];
  68. let animations = animatable.getAnimations();
  69. if (!animations || !animations.length) {
  70. continue;
  71. }
  72. for (let idx = 0; idx < animations.length; ++idx) {
  73. if (animations[idx].currentFrame) {
  74. return animations[idx].currentFrame;
  75. }
  76. }
  77. }
  78. return 0;
  79. }
  80. public get fps(): number {
  81. // get the first currentFrame found
  82. for (let i = 0; i < this._animationGroup['_animatables'].length; ++i) {
  83. let animatable: Animatable = this._animationGroup['_animatables'][i];
  84. let animations = animatable.getAnimations();
  85. if (!animations || !animations.length) {
  86. continue;
  87. }
  88. for (let idx = 0; idx < animations.length; ++idx) {
  89. if (animations[idx].animation && animations[idx].animation.framePerSecond) {
  90. return animations[idx].animation.framePerSecond;
  91. }
  92. }
  93. }
  94. return 0;
  95. }
  96. public get playMode(): AnimationPlayMode {
  97. return this._playMode;
  98. }
  99. public set playMode(value: AnimationPlayMode) {
  100. if (value === this._playMode) {
  101. return;
  102. }
  103. this._playMode = value;
  104. if (this.state === AnimationState.PLAYING) {
  105. this._animationGroup.play(this._playMode === AnimationPlayMode.LOOP);
  106. } else {
  107. this._animationGroup.reset();
  108. this._state = AnimationState.INIT;
  109. }
  110. }
  111. reset() {
  112. this._animationGroup.reset();
  113. }
  114. restart() {
  115. this._animationGroup.restart();
  116. }
  117. goToFrame(frameNumber: number) {
  118. // this._animationGroup.goToFrame(frameNumber);
  119. this._animationGroup['_animatables'].forEach(a => {
  120. a.goToFrame(frameNumber);
  121. })
  122. }
  123. public start() {
  124. this._animationGroup.start(this.playMode === AnimationPlayMode.LOOP, this.speedRatio);
  125. if (this._animationGroup.isStarted) {
  126. this._state = AnimationState.PLAYING;
  127. }
  128. }
  129. pause() {
  130. this._animationGroup.pause();
  131. this._state = AnimationState.PAUSED;
  132. }
  133. public stop() {
  134. this._animationGroup.stop();
  135. if (!this._animationGroup.isStarted) {
  136. this._state = AnimationState.STOPPED;
  137. }
  138. }
  139. public dispose() {
  140. this._animationGroup.dispose();
  141. }
  142. }