ModelAnimation.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import defaultValue from "../Core/defaultValue.js";
  2. import Event from "../Core/Event.js";
  3. import JulianDate from "../Core/JulianDate.js";
  4. import ModelAnimationLoop from "./ModelAnimationLoop.js";
  5. import ModelAnimationState from "./ModelAnimationState.js";
  6. /**
  7. * An active glTF animation. A glTF asset can contain animations. An active animation
  8. * is an animation that is currently playing or scheduled to be played because it was
  9. * added to a model's {@link ModelAnimationCollection}. An active animation is an
  10. * instance of an animation; for example, there can be multiple active animations
  11. * for the same glTF animation, each with a different start time.
  12. * <p>
  13. * Create this by calling {@link ModelAnimationCollection#add}.
  14. * </p>
  15. *
  16. * @alias ModelAnimation
  17. * @internalConstructor
  18. * @class
  19. *
  20. * @see ModelAnimationCollection#add
  21. */
  22. function ModelAnimation(options, model, runtimeAnimation) {
  23. this._name = runtimeAnimation.name;
  24. this._startTime = JulianDate.clone(options.startTime);
  25. this._delay = defaultValue(options.delay, 0.0); // in seconds
  26. this._stopTime = options.stopTime;
  27. /**
  28. * When <code>true</code>, the animation is removed after it stops playing.
  29. * This is slightly more efficient that not removing it, but if, for example,
  30. * time is reversed, the animation is not played again.
  31. *
  32. * @type {Boolean}
  33. * @default false
  34. */
  35. this.removeOnStop = defaultValue(options.removeOnStop, false);
  36. this._multiplier = defaultValue(options.multiplier, 1.0);
  37. this._reverse = defaultValue(options.reverse, false);
  38. this._loop = defaultValue(options.loop, ModelAnimationLoop.NONE);
  39. /**
  40. * The event fired when this animation is started. This can be used, for
  41. * example, to play a sound or start a particle system, when the animation starts.
  42. * <p>
  43. * This event is fired at the end of the frame after the scene is rendered.
  44. * </p>
  45. *
  46. * @type {Event}
  47. * @default new Event()
  48. *
  49. * @example
  50. * animation.start.addEventListener(function(model, animation) {
  51. * console.log('Animation started: ' + animation.name);
  52. * });
  53. */
  54. this.start = new Event();
  55. /**
  56. * The event fired when on each frame when this animation is updated. The
  57. * current time of the animation, relative to the glTF animation time span, is
  58. * passed to the event, which allows, for example, starting new animations at a
  59. * specific time relative to a playing animation.
  60. * <p>
  61. * This event is fired at the end of the frame after the scene is rendered.
  62. * </p>
  63. *
  64. * @type {Event}
  65. * @default new Event()
  66. *
  67. * @example
  68. * animation.update.addEventListener(function(model, animation, time) {
  69. * console.log('Animation updated: ' + animation.name + '. glTF animation time: ' + time);
  70. * });
  71. */
  72. this.update = new Event();
  73. /**
  74. * The event fired when this animation is stopped. This can be used, for
  75. * example, to play a sound or start a particle system, when the animation stops.
  76. * <p>
  77. * This event is fired at the end of the frame after the scene is rendered.
  78. * </p>
  79. *
  80. * @type {Event}
  81. * @default new Event()
  82. *
  83. * @example
  84. * animation.stop.addEventListener(function(model, animation) {
  85. * console.log('Animation stopped: ' + animation.name);
  86. * });
  87. */
  88. this.stop = new Event();
  89. this._state = ModelAnimationState.STOPPED;
  90. this._runtimeAnimation = runtimeAnimation;
  91. // Set during animation update
  92. this._computedStartTime = undefined;
  93. this._duration = undefined;
  94. // To avoid allocations in ModelAnimationCollection.update
  95. const that = this;
  96. this._raiseStartEvent = function () {
  97. that.start.raiseEvent(model, that);
  98. };
  99. this._updateEventTime = 0.0;
  100. this._raiseUpdateEvent = function () {
  101. that.update.raiseEvent(model, that, that._updateEventTime);
  102. };
  103. this._raiseStopEvent = function () {
  104. that.stop.raiseEvent(model, that);
  105. };
  106. }
  107. Object.defineProperties(ModelAnimation.prototype, {
  108. /**
  109. * The glTF animation name that identifies this animation.
  110. *
  111. * @memberof ModelAnimation.prototype
  112. *
  113. * @type {String}
  114. * @readonly
  115. */
  116. name: {
  117. get: function () {
  118. return this._name;
  119. },
  120. },
  121. /**
  122. * The scene time to start playing this animation. When this is <code>undefined</code>,
  123. * the animation starts at the next frame.
  124. *
  125. * @memberof ModelAnimation.prototype
  126. *
  127. * @type {JulianDate}
  128. * @readonly
  129. *
  130. * @default undefined
  131. */
  132. startTime: {
  133. get: function () {
  134. return this._startTime;
  135. },
  136. },
  137. /**
  138. * The delay, in seconds, from {@link ModelAnimation#startTime} to start playing.
  139. *
  140. * @memberof ModelAnimation.prototype
  141. *
  142. * @type {Number}
  143. * @readonly
  144. *
  145. * @default undefined
  146. */
  147. delay: {
  148. get: function () {
  149. return this._delay;
  150. },
  151. },
  152. /**
  153. * The scene time to stop playing this animation. When this is <code>undefined</code>,
  154. * the animation is played for its full duration and perhaps repeated depending on
  155. * {@link ModelAnimation#loop}.
  156. *
  157. * @memberof ModelAnimation.prototype
  158. *
  159. * @type {JulianDate}
  160. * @readonly
  161. *
  162. * @default undefined
  163. */
  164. stopTime: {
  165. get: function () {
  166. return this._stopTime;
  167. },
  168. },
  169. /**
  170. * Values greater than <code>1.0</code> increase the speed that the animation is played relative
  171. * to the scene clock speed; values less than <code>1.0</code> decrease the speed. A value of
  172. * <code>1.0</code> plays the animation at the speed in the glTF animation mapped to the scene
  173. * clock speed. For example, if the scene is played at 2x real-time, a two-second glTF animation
  174. * will play in one second even if <code>multiplier</code> is <code>1.0</code>.
  175. *
  176. * @memberof ModelAnimation.prototype
  177. *
  178. * @type {Number}
  179. * @readonly
  180. *
  181. * @default 1.0
  182. */
  183. multiplier: {
  184. get: function () {
  185. return this._multiplier;
  186. },
  187. },
  188. /**
  189. * When <code>true</code>, the animation is played in reverse.
  190. *
  191. * @memberof ModelAnimation.prototype
  192. *
  193. * @type {Boolean}
  194. * @readonly
  195. *
  196. * @default false
  197. */
  198. reverse: {
  199. get: function () {
  200. return this._reverse;
  201. },
  202. },
  203. /**
  204. * Determines if and how the animation is looped.
  205. *
  206. * @memberof ModelAnimation.prototype
  207. *
  208. * @type {ModelAnimationLoop}
  209. * @readonly
  210. *
  211. * @default {@link ModelAnimationLoop.NONE}
  212. */
  213. loop: {
  214. get: function () {
  215. return this._loop;
  216. },
  217. },
  218. });
  219. export default ModelAnimation;