ModelAnimation.js 7.7 KB

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