modelAnimation.ts 4.6 KB

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