function ModelAnimation(model, animation, options) {
  this._animation = animation;
  this._name = animation.name;
  this._runtimeChannels = undefined;

  this._startTime = JulianDate.clone(options.startTime);
  this._delay = options.delay ?? 0.0; // in seconds
  this._stopTime = JulianDate.clone(options.stopTime);

  /**
   * When <code>true</code>, 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 = options.removeOnStop ?? false;
  this._multiplier = options.multiplier ?? 1.0;
  this._reverse = options.reverse ?? false;
  this._loop = options.loop ?? ModelAnimationLoop.NONE;
  this._animationTime = options.animationTime;
  this._prevAnimationDelta = undefined;

  /**
   * 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.
   * <p>
   * This event is fired at the end of the frame after the scene is rendered.
   * </p>
   *
   * @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.
   * <p>
   * This event is fired at the end of the frame after the scene is rendered.
   * </p>
   *
   * @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.
   * <p>
   * This event is fired at the end of the frame after the scene is rendered.
   * </p>
   *
   * @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;

  // Set during animation update
  this._computedStartTime = undefined;
  this._duration = undefined;

  // To avoid allocations in ModelAnimationCollection.update
  const 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);
  };

  this._model = model;

  this._localStartTime = undefined;
  this._localStopTime = undefined;

  initialize(this);
}
<div class="notice">
Create animations by calling {@link ModelAnimationCollection#add}. Do not call the constructor directly.
</div>

An active animation derived from a glTF asset. An active animation is an
animation that is either currently playing or scheduled to be played due to
being 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.

@alias ModelAnimation
@internalConstructor
@class

@see ModelAnimationCollection#add