/*global define*/ define([ '../Core/defaultValue', '../Core/defineProperties', '../Core/Event', '../Core/JulianDate', './ModelAnimationLoop', './ModelAnimationState' ], function( defaultValue, defineProperties, Event, JulianDate, ModelAnimationLoop, ModelAnimationState) { "use strict"; /** * An active glTF animation. A glTF asset can contain animations. An active animation * is an animation that is currently playing or scheduled to be played because it was * added to a model's {@link ModelAnimationCollection}. An active animation is an * instance of an animation; for example, there can be multiple active animations * for the same glTF animation, each with a different start time. *

* Create this by calling {@link ModelAnimationCollection#add}. *

* * @alias ModelAnimation * @internalConstructor * * @see ModelAnimationCollection#add */ var ModelAnimation = function(options, model, runtimeAnimation) { this._name = options.name; this._startTime = JulianDate.clone(options.startTime); this._delay = defaultValue(options.delay, 0.0); // in seconds this._stopTime = options.stopTime; /** * When true, the animation is removed after it stops playing. * This is slightly more efficient that not removing it, but if, for example, * time is reversed, the animation is not played again. * * @type {Boolean} * @default false */ this.removeOnStop = defaultValue(options.removeOnStop, false); this._speedup = defaultValue(options.speedup, 1.0); this._reverse = defaultValue(options.reverse, false); this._loop = defaultValue(options.loop, ModelAnimationLoop.NONE); /** * The event fired when this animation is started. This can be used, for * example, to play a sound or start a particle system, when the animation starts. *

* This event is fired at the end of the frame after the scene is rendered. *

* * @type {Event} * @default new Event() * * @example * animation.start.addEventListener(function(model, animation) { * console.log('Animation started: ' + animation.name); * }); */ this.start = new Event(); /** * The event fired when on each frame when this animation is updated. The * current time of the animation, relative to the glTF animation time span, is * passed to the event, which allows, for example, starting new animations at a * specific time relative to a playing animation. *

* This event is fired at the end of the frame after the scene is rendered. *

* * @type {Event} * @default new Event() * * @example * animation.update.addEventListener(function(model, animation, time) { * console.log('Animation updated: ' + animation.name + '. glTF animation time: ' + time); * }); */ this.update = new Event(); /** * The event fired when this animation is stopped. This can be used, for * example, to play a sound or start a particle system, when the animation stops. *

* This event is fired at the end of the frame after the scene is rendered. *

* * @type {Event} * @default new Event() * * @example * animation.stop.addEventListener(function(model, animation) { * console.log('Animation stopped: ' + animation.name); * }); */ this.stop = new Event(); this._state = ModelAnimationState.STOPPED; this._runtimeAnimation = runtimeAnimation; // Set during animation update this._computedStartTime = undefined; this._duration = undefined; // To avoid allocations in ModelAnimationCollection.update var that = this; this._raiseStartEvent = function() { that.start.raiseEvent(model, that); }; this._updateEventTime = 0.0; this._raiseUpdateEvent = function() { that.update.raiseEvent(model, that, that._updateEventTime); }; this._raiseStopEvent = function() { that.stop.raiseEvent(model, that); }; }; defineProperties(ModelAnimation.prototype, { /** * The glTF animation name that identifies this animation. * * @memberof ModelAnimation.prototype * * @type {String} * @readonly */ name : { get : function() { return this._name; } }, /** * The scene time to start playing this animation. When this is undefined, * the animation starts at the next frame. * * @memberof ModelAnimation.prototype * * @type {JulianDate} * @readonly * * @default undefined */ startTime : { get : function() { return this._startTime; } }, /** * The delay, in seconds, from {@link ModelAnimation#startTime} to start playing. * * @memberof ModelAnimation.prototype * * @type {Number} * @readonly * * @default undefined */ delay : { get : function() { return this._delay; } }, /** * The scene time to stop playing this animation. When this is undefined, * the animation is played for its full duration and perhaps repeated depending on * {@link ModelAnimation#loop}. * * @memberof ModelAnimation.prototype * * @type {JulianDate} * @readonly * * @default undefined */ stopTime : { get : function() { return this._stopTime; } }, /** * Values greater than 1.0 increase the speed that the animation is played relative * to the scene clock speed; values less than 1.0 decrease the speed. A value of * 1.0 plays the animation at the speed in the glTF animation mapped to the scene * clock speed. For example, if the scene is played at 2x real-time, a two-second glTF animation * will play in one second even if speedup is 1.0. * * @memberof ModelAnimation.prototype * * @type {Number} * @readonly * * @default 1.0 */ speedup : { get : function() { return this._speedup; } }, /** * When true, the animation is played in reverse. * * @memberof ModelAnimation.prototype * * @type {Boolean} * @readonly * * @default false */ reverse : { get : function() { return this._reverse; } }, /** * Determines if and how the animation is looped. * * @memberof ModelAnimation.prototype * * @type {ModelAnimationLoop} * @readonly * * @default {@link ModelAnimationLoop.NONE} */ loop : { get : function() { return this._loop; } } }); return ModelAnimation; });