/// <summary>
        /// Plays the specified animation.
        /// </summary>
        /// <param name="mode">The animation mode.</param>
        /// <param name="animation">The animation to play.</param>
        /// <param name="speedMultiplier">The relative speed at which to play the animation.</param>
        /// <param name="easeInFunction">The easing function to apply when easing in the animation.</param>
        /// <param name="easeInDuration">The number of seconds over which to ease in the animation.</param>
        /// <param name="easeOutFunction">The easing function to apply when easing out the animation.</param>
        /// <param name="easeOutDuration">The number of seconds over which to ease out the animation.</param>
        /// <param name="callbacks">The set of callbacks to invoke for this animation.</param>
        public void Play(SkinnedAnimationMode mode, SkinnedAnimation animation, Single speedMultiplier,
                         EasingFunction easeInFunction, Double easeInDuration, EasingFunction easeOutFunction, Double easeOutDuration, SkinnedAnimationCallbacks?callbacks = null)
        {
            Contract.Require(animation, nameof(animation));
            Contract.Require(easeInFunction, nameof(easeInFunction));
            Contract.EnsureRange(easeInDuration >= 0, nameof(easeInDuration));
            Contract.Require(easeOutFunction, nameof(easeOutFunction));
            Contract.EnsureRange(easeOutDuration >= 0, nameof(easeOutDuration));

            this.currentAnimationMode = mode;
            this.CurrentAnimation     = animation;
            this.currentAnimationTime = 0.0;
            this.SpeedMultiplier      = speedMultiplier;

            if (mode != SkinnedAnimationMode.Manual)
            {
                this.easeInFunction  = easeInFunction;
                this.easeInDuration  = easeInDuration;
                this.easeOutFunction = easeOutFunction;
                this.easeOutDuration = easeOutDuration;
            }
            else
            {
                this.easeInFunction  = null;
                this.easeInDuration  = 0;
                this.easeOutFunction = null;
                this.easeOutDuration = 0;
            }

            this.easeInElasped  = 0;
            this.easeOutElapsed = 0;
            this.BlendingWeight = 1f;

            this.callbacks = callbacks;
        }
Пример #2
0
        /// <summary>
        /// Allocates a track to play the specified animation.
        /// </summary>
        private KeyValuePair <Int32, SkinnedAnimationTrack> AllocateTrack(SkinnedAnimation animation)
        {
            var existing = GetTrackForAnimationInternal(animation);

            if (existing.Value != null)
            {
                return(existing);
            }

            // If no existing controller, find one that isn't playing.
            var leastRecentlyPlayed      = default(SkinnedAnimationTrack);
            var leastRecentlyPlayedIndex = -1;
            var leastRecentlyPlayedOrder = Int64.MaxValue;

            for (var i = 0; i < tracks.Length; i++)
            {
                var controller = tracks[i];
                var order      = ordering[i];

                if (leastRecentlyPlayed == null || order < leastRecentlyPlayedOrder)
                {
                    leastRecentlyPlayed      = controller;
                    leastRecentlyPlayedIndex = i;
                    leastRecentlyPlayedOrder = order;
                }

                if (!controller.IsPlaying)
                {
                    return(new KeyValuePair <Int32, SkinnedAnimationTrack>(i, controller));
                }
            }

            // If no stopped controller, override the one that was least recently played.
            return(new KeyValuePair <Int32, SkinnedAnimationTrack>(leastRecentlyPlayedIndex, leastRecentlyPlayed));
        }
Пример #3
0
        /// <summary>
        /// Plays the specified animation. If the animation is already playing,
        /// it will be restarted using the specified mode.
        /// </summary>
        /// <param name="mode">A <see cref="SkinnedAnimationMode"/> value which describes the animation mode.</param>
        /// <param name="animation">The animation to play.</param>
        /// <param name="speedMultiplier">The relative speed at which to play the animation.</param>
        /// <param name="callbacks">The set of callbacks to invoke for this animation.</param>
        /// <returns>The <see cref="SkinnedAnimationTrack"/> which is playing the animation, or <see langword="null"/> if the animation could not be played.</returns>
        public SkinnedAnimationTrack PlayAnimation(SkinnedAnimationMode mode, SkinnedAnimation animation, Single speedMultiplier = 1f, SkinnedAnimationCallbacks?callbacks = null)
        {
            var controllerAllocation = AllocateTrack(animation);
            var controller           = controllerAllocation.Value;

            controller.Play(mode, animation, speedMultiplier, callbacks);
            ordering[controllerAllocation.Key] = ++orderingCounter;
            UpdateAnimationState();

            return(controller);
        }
Пример #4
0
        /// <summary>
        /// Immediately stops the specified animation without performing any easing.
        /// </summary>
        /// <param name="animation">The animation to stop.</param>
        /// <returns>The <see cref="SkinnedAnimationTrack"/> which was playing the animation, or <see langword="null"/> if the animation was not being played.</returns>
        public SkinnedAnimationTrack StopAnimationImmediate(SkinnedAnimation animation)
        {
            var controller = GetTrackForAnimation(animation);

            if (controller != null)
            {
                controller.StopImmediate();
                UpdateAnimationState();

                return(controller);
            }
            return(null);
        }
        /// <summary>
        /// Processes the node's animations.
        /// </summary>
        private static IEnumerable <SkinnedAnimation> ProcessAnimations(ModelRoot input, IEnumerable <ModelScene> scenes, Int32 nodesCount)
        {
            var uvAnimations = new List <SkinnedAnimation>(input.LogicalAnimations.Count);

            foreach (var animation in input.LogicalAnimations)
            {
                var uvNodeAnimations = new SkinnedModelNodeAnimation[nodesCount];
                TraverseModelNodes(scenes, (n, state) =>
                {
                    var gltfNode = input.LogicalNodes[n.LogicalIndex];

                    var animScale        = animation.FindScaleSampler(gltfNode);
                    var animTranslation  = animation.FindTranslationSampler(gltfNode);
                    var animRotation     = animation.FindRotationSampler(gltfNode);
                    var animMorphWeights = animation.FindMorphSampler(gltfNode);

                    if (animScale != null || animRotation != null || animTranslation != null || animMorphWeights != null)
                    {
                        var curveScale = CreateCurve(animScale, x => x,
                                                     Vector3CurveStepSampler.Instance, Vector3CurveLinearSampler.Instance, Vector3CurveCubicSplineSampler.Instance);
                        var curveTranslation = CreateCurve(animTranslation, x => x,
                                                           Vector3CurveStepSampler.Instance, Vector3CurveLinearSampler.Instance, Vector3CurveCubicSplineSampler.Instance);
                        var curveRotation = CreateCurve(animRotation, x => x,
                                                        QuaternionCurveStepSampler.Instance, QuaternionCurveLinearSampler.Instance, QuaternionCurveCubicSplineSampler.Instance);
                        var curveMorphWeights = CreateCurve(animMorphWeights, x => new ArraySegment <Single>(x),
                                                            SingleArrayCurveStepSampler.Instance, SingleArrayCurveLinearSampler.Instance, SingleArrayCurveCubicSplineSampler.Instance);

                        var uvNodeAnimation = new SkinnedModelNodeAnimation(n, curveScale, curveTranslation, curveRotation, curveMorphWeights);
                        uvNodeAnimations[gltfNode.LogicalIndex] = uvNodeAnimation;
                    }
                });

                var uvAnimation = new SkinnedAnimation(animation.Name, uvNodeAnimations);
                uvAnimations.Add(uvAnimation);
            }
            return(uvAnimations);
        }
Пример #6
0
 /// <summary>
 /// Gets the track that is currently playing the specified animation.
 /// </summary>
 private KeyValuePair <Int32, SkinnedAnimationTrack> GetTrackForAnimationInternal(SkinnedAnimation animation)
 {
     for (var i = 0; i < tracks.Length; i++)
     {
         var controller = tracks[i];
         if (controller.IsPlayingAnimation(animation))
         {
             return(new KeyValuePair <Int32, SkinnedAnimationTrack>(i, controller));
         }
     }
     return(new KeyValuePair <Int32, SkinnedAnimationTrack>(-1, null));
 }
Пример #7
0
 /// <summary>
 /// Gets the track that is currently playing the specified animation.
 /// </summary>
 /// <param name="animation">The animation to evaluate.</param>
 /// <returns>The <see cref="SkinnedAnimationTrack"/> which is currently playing the specified
 /// animation, or <see langword="null"/> if no track is playing the animation.</returns>
 public SkinnedAnimationTrack GetTrackForAnimation(SkinnedAnimation animation)
 {
     return(GetTrackForAnimationInternal(animation).Value);
 }
        /// <summary>
        /// Gets a value indicating whether the track is currently playing the specified animation.
        /// </summary>
        /// <param name="animation">The animation to evaluate.</param>
        /// <returns><see langword="true"/> if the track is currently playing the specified animation; otherwise, <see langword="false"/>.</returns>
        public Boolean IsPlayingAnimation(SkinnedAnimation animation)
        {
            Contract.Require(animation, nameof(animation));

            return(animation == CurrentAnimation);
        }
 /// <summary>
 /// Plays the specified animation.
 /// </summary>
 /// <param name="mode">The animation mode.</param>
 /// <param name="animation">The animation to play.</param>
 /// <param name="speedMultiplier">The relative speed at which to play the animation.</param>
 /// <param name="callbacks">The set of callbacks to invoke for this animation.</param>
 public void Play(SkinnedAnimationMode mode, SkinnedAnimation animation, Single speedMultiplier = 1f, SkinnedAnimationCallbacks?callbacks = null)
 {
     Play(mode, animation, speedMultiplier, Easings.EaseInLinear, 0.0, Easings.EaseOutLinear, 0.0, callbacks);
 }