Exemple #1
0
    public EasingSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Initialize array of easing functions.
      _easingFunctions = new EasingFunction[]
       {
         null,
         new BackEase { Amplitude = 0.5f },
         new BounceEase { Bounces = 3, Bounciness = 3 },
         new CircleEase(),
         new CubicEase(),
         new ElasticEase { Oscillations = 3, Springiness = 10 },
         new ExponentialEase(),
         new LogarithmicEase(),
         new HermiteEase(),
         new PowerEase { Power = 2 },
         new QuadraticEase(),
         new QuinticEase(),
         new SineEase()
       };


      // Create and start a horizontal from/to animation.
      Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea;
      _fromToAnimation = new SingleFromToByAnimation
      {
        From = bounds.Left + 200,
        To = bounds.Right - 200,
        Duration = TimeSpan.FromSeconds(1.5),
        EasingFunction = _easingFunctions[_selectedEasingFunctionIndex],
      };
      _animationController = AnimationService.StartAnimation(_fromToAnimation, _animatableFloat);
      _animationController.UpdateAndApply();
    }
Exemple #2
0
        public void CreateInstanceTest()
        {
            var animation1 = new SingleFromToByAnimation();
              var animation2 = new SingleFromToByAnimation();
              var animation3 = new SingleFromToByAnimation();

              var childGroup = new TimelineGroup();
              childGroup.Add(animation2);
              childGroup.Add(animation3);

              var rootGroup = new TimelineGroup();
              rootGroup.Add(animation1);
              rootGroup.Add(childGroup);

              var animationInstance = rootGroup.CreateInstance();
              Assert.IsNotNull(animationInstance);
              Assert.AreEqual(2, animationInstance.Children.Count);
              Assert.That(animationInstance.Children[0], Is.TypeOf<AnimationInstance<float>>());
              Assert.That(animationInstance.Children[0].Animation, Is.EqualTo(animation1));
              Assert.That(animationInstance.Children[1], Is.TypeOf<AnimationInstance>());
              Assert.That(animationInstance.Children[1].Animation, Is.EqualTo(childGroup));
              Assert.That(animationInstance.Children[1].Children[0], Is.TypeOf<AnimationInstance<float>>());
              Assert.That(animationInstance.Children[1].Children[0].Animation, Is.EqualTo(animation2));
              Assert.That(animationInstance.Children[1].Children[1], Is.TypeOf<AnimationInstance<float>>());
              Assert.That(animationInstance.Children[1].Children[1].Animation, Is.EqualTo(animation3));
        }
        public void AnimationWeight()
        {
            var manager   = new AnimationManager();
            var property  = new AnimatableProperty <float>();
            var animation = new SingleFromToByAnimation
            {
                Duration = TimeSpan.FromSeconds(1.0),
                From     = 100.0f,
                To       = 200.0f,
            };

            var controller = manager.StartAnimation(animation, property);

            controller.AutoRecycle();
            controller.UpdateAndApply();
            Assert.AreEqual(1.0f, controller.Weight);
            Assert.AreEqual(100.0f, property.Value);

            controller.Weight = 0.5f;
            manager.Update(TimeSpan.Zero);
            manager.ApplyAnimations();
            Assert.AreEqual(50.0f, property.Value);

            controller.Stop();
            Assert.IsNaN(controller.Weight);
        }
Exemple #4
0
        public FadingWindow(IServiceLocator services)
            : base(services)
        {
            Title = "FadingWindow";

            Width  = 200;
            Height = 100;

            Content = new TextBlock
            {
                Margin   = new Vector4(8),
                Text     = "The 'Opacity' of this window is animated.",
                WrapText = true,
            };

            LoadingAnimation = new SingleFromToByAnimation
            {
                TargetProperty = "Opacity",                 // Transition the property UIControl.Opacity
                From           = 0,                         // from 0 to its actual value
                Duration       = TimeSpan.FromSeconds(0.3), // over a duration of 0.3 seconds.
            };

            ClosingAnimation = new SingleFromToByAnimation
            {
                TargetProperty = "Opacity",                 // Transition the property UIControl.Opacity
                To             = 0,                         // from its current value to 0
                Duration       = TimeSpan.FromSeconds(0.3), // over a duration 0.3 seconds.
            };
        }
        public void EasingFunctionTest()
        {
            var animation = new SingleFromToByAnimation();

            animation.From = 0.0f;
            animation.To   = 100.0f;

            animation.EasingFunction = new CubicEase {
                Mode = EasingMode.EaseIn
            };
            Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f));
            Assert.Greater(25.0f, animation.GetValue(TimeSpan.FromSeconds(0.25), 0.0f, 100.0f));
            Assert.Greater(50.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f));
            Assert.Greater(75.0f, animation.GetValue(TimeSpan.FromSeconds(0.75), 0.0f, 100.0f));
            Assert.AreEqual(100.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f));

            animation.EasingFunction = new CubicEase {
                Mode = EasingMode.EaseOut
            };
            Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f));
            Assert.Less(25.0f, animation.GetValue(TimeSpan.FromSeconds(0.25), 0.0f, 100.0f));
            Assert.Less(50.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f));
            Assert.Less(75.0f, animation.GetValue(TimeSpan.FromSeconds(0.75), 0.0f, 100.0f));
            Assert.AreEqual(100.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f));

            animation.EasingFunction = new CubicEase {
                Mode = EasingMode.EaseInOut
            };
            Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f));
            Assert.Greater(25.0f, animation.GetValue(TimeSpan.FromSeconds(0.25), 0.0f, 100.0f));
            Assert.AreEqual(50.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f));
            Assert.Less(75.0f, animation.GetValue(TimeSpan.FromSeconds(0.75), 0.0f, 100.0f));
            Assert.AreEqual(100.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f));
        }
        public void FadeOutAnimation()
        {
            var manager   = new AnimationManager();
            var property  = new AnimatableProperty <float>();
            var animation = new SingleFromToByAnimation
            {
                Duration = TimeSpan.Zero,
                To       = 100.0f,
            };
            var controller = manager.StartAnimation(animation, property);

            controller.UpdateAndApply();
            Assert.AreEqual(100.0f, property.Value);
            Assert.AreEqual(AnimationState.Playing, controller.State);

            controller.Stop(TimeSpan.FromSeconds(1.0));
            Assert.AreEqual(100.0f, property.Value);
            Assert.AreEqual(AnimationState.Playing, controller.State);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(50.0f, property.Value);
            Assert.AreEqual(AnimationState.Filling, controller.State);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(0.0f, property.Value);
            Assert.AreEqual(AnimationState.Filling, controller.State);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(0.0f, property.Value);
            Assert.AreEqual(AnimationState.Stopped, controller.State);
        }
Exemple #7
0
        public void CreateInstanceTest()
        {
            var animation1 = new SingleFromToByAnimation();
            var animation2 = new SingleFromToByAnimation();
            var animation3 = new SingleFromToByAnimation();

            var childGroup = new TimelineGroup();

            childGroup.Add(animation2);
            childGroup.Add(animation3);

            var rootGroup = new TimelineGroup();

            rootGroup.Add(animation1);
            rootGroup.Add(childGroup);

            var animationInstance = rootGroup.CreateInstance();

            Assert.IsNotNull(animationInstance);
            Assert.AreEqual(2, animationInstance.Children.Count);
            Assert.That(animationInstance.Children[0], Is.TypeOf <AnimationInstance <float> >());
            Assert.That(animationInstance.Children[0].Animation, Is.EqualTo(animation1));
            Assert.That(animationInstance.Children[1], Is.TypeOf <AnimationInstance>());
            Assert.That(animationInstance.Children[1].Animation, Is.EqualTo(childGroup));
            Assert.That(animationInstance.Children[1].Children[0], Is.TypeOf <AnimationInstance <float> >());
            Assert.That(animationInstance.Children[1].Children[0].Animation, Is.EqualTo(animation2));
            Assert.That(animationInstance.Children[1].Children[1], Is.TypeOf <AnimationInstance <float> >());
            Assert.That(animationInstance.Children[1].Children[1].Animation, Is.EqualTo(animation3));
        }
        public void InvalidParameters()
        {
            var objectA   = new AnimatableObject("ObjectA");
            var objectB   = new AnimatableObject("ObjectA");
            var property  = new AnimatableProperty <float>();
            var animation = new SingleFromToByAnimation();
            var objects   = new[] { objectA, objectB };

            var manager = new AnimationManager();

            // Should throw exception.
            Assert.That(() => { manager.IsAnimated((IAnimatableObject)null); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.IsAnimated((IAnimatableProperty)null); }, Throws.TypeOf <ArgumentNullException>());

            // Should throw exception.
            Assert.That(() => { manager.CreateController(null, objects); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.CreateController(animation, (IEnumerable <IAnimatableObject>)null); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.CreateController(null, objectA); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.CreateController(animation, (IAnimatableObject)null); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.CreateController(null, property); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.CreateController(animation, (IAnimatableProperty)null); }, Throws.TypeOf <ArgumentNullException>());

            // Should throw exception.
            Assert.That(() => { manager.StartAnimation(null, objects); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.StartAnimation(animation, (IEnumerable <IAnimatableObject>)null); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.StartAnimation(null, objectA); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.StartAnimation(animation, (IAnimatableObject)null); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.StartAnimation(null, property); }, Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => { manager.StartAnimation(animation, (IAnimatableProperty)null); }, Throws.TypeOf <ArgumentNullException>());

            // Should not throw exception.
            Assert.That(() => manager.StopAnimation((IEnumerable <IAnimatableObject>)null), Throws.Nothing);
            Assert.That(() => manager.StopAnimation((IAnimatableObject)null), Throws.Nothing);
            Assert.That(() => manager.StopAnimation((IAnimatableProperty)null), Throws.Nothing);
        }
Exemple #9
0
        public void AnimationWeight()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation
              {
            Duration = TimeSpan.FromSeconds(1.0),
            From = 100.0f,
            To = 200.0f,
              };

              var controller = manager.StartAnimation(animation, property);
              controller.AutoRecycle();
              controller.UpdateAndApply();
              Assert.AreEqual(1.0f, controller.Weight);
              Assert.AreEqual(100.0f, property.Value);

              controller.Weight = 0.5f;
              manager.Update(TimeSpan.Zero);
              manager.ApplyAnimations();
              Assert.AreEqual(50.0f, property.Value);

              controller.Stop();
              Assert.IsNaN(controller.Weight);
        }
Exemple #10
0
        public void CopyTo()
        {
            var blendGroup = new BlendGroup();

            ITimeline[] array = new ITimeline[0];
            Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(null, 0), Throws.TypeOf <ArgumentNullException>());
            Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, -1), Throws.TypeOf <ArgumentOutOfRangeException>());
            Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, 1), Throws.ArgumentException);
            Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, 0), Throws.Nothing);

            var animation0 = new SingleFromToByAnimation();
            var animation1 = new SingleFromToByAnimation();

            blendGroup = new BlendGroup {
                animation0, animation1
            };

            array = new ITimeline[1];
            Assert.That(() => ((IList <ITimeline>)blendGroup).CopyTo(array, 0), Throws.ArgumentException);

            array = new ITimeline[2];
            ((IList <ITimeline>)blendGroup).CopyTo(array, 0);
            Assert.AreEqual(animation0, array[0]);
            Assert.AreEqual(animation1, array[1]);

            array = new ITimeline[3];
            ((IList <ITimeline>)blendGroup).CopyTo(array, 1);
            Assert.AreEqual(null, array[0]);
            Assert.AreEqual(animation0, array[1]);
            Assert.AreEqual(animation1, array[2]);
        }
        // Called when the "Animate" button was clicked.
        private void OnButtonClicked(object sender, EventArgs eventArgs)
        {
            // Get the selected easing function from the DropDownButton.
            EasingFunction easingFunction = (EasingFunction)_functionDropDown.Items[_functionDropDown.SelectedIndex];

            // Set the selected easing mode.
            easingFunction.Mode = (EasingMode)_modeDropDown.Items[_modeDropDown.SelectedIndex];

            // The current slider value:
            float startValue = _slider.Value;

            // Set the slider to the target value.
            _slider.Value = (startValue > 0.5f) ? 0 : 1;

            // Create a from-animation that uses the easing function. It animates the slider
            // value from startValue to the new value.
            SingleFromToByAnimation animation = new SingleFromToByAnimation
            {
                TargetProperty = "Value",
                From           = startValue,
                Duration       = TimeSpan.FromSeconds(1),
                EasingFunction = easingFunction,
                FillBehavior   = FillBehavior.Stop, // Stop the animation when it is finished.
            };

            // Start the animation.
            // (Use the Replace transition to replace any currently running animations.
            // This is necessary because the user could press the Animate button while
            // an animation is running.)
            _animationService.StartAnimation(animation, _slider, AnimationTransitions.Replace())
            .UpdateAndApply();             // Apply new animation value immediately.
        }
Exemple #12
0
        public void GetSelfAndAncestors()
        {
            var animationA = new TimelineGroup();
            var animationB = new SingleFromToByAnimation();
            var animationC = new SingleFromToByAnimation();
            var animationD = new TimelineGroup();
            var animationE = new TimelineGroup();
            var animationF = new SingleFromToByAnimation();
            var animationG = new TimelineGroup();

            animationA.Add(animationB);
            animationA.Add(animationC);
            animationA.Add(animationD);
            animationD.Add(animationE);
            animationD.Add(animationF);
            animationE.Add(animationG);

            Assert.That(() => AnimationHelper.GetSelfAndAncestors(null), Throws.TypeOf <ArgumentNullException>());

            var animationInstance = animationA.CreateInstance();
            var ancestors         = animationInstance.Children[2].Children[0].GetSelfAndAncestors().ToArray();

            Assert.AreEqual(3, ancestors.Length);
            Assert.AreEqual(animationInstance.Children[2].Children[0], ancestors[0]);
            Assert.AreEqual(animationInstance.Children[2], ancestors[1]);
            Assert.AreEqual(animationInstance, ancestors[2]);
        }
Exemple #13
0
    public FadingWindow(IServiceLocator services) 
      : base(services)
    {
      Title = "FadingWindow";

      Width = 200;
      Height = 100;

      Content = new TextBlock
      {
        Margin = new Vector4F(8),
        Text = "The 'Opacity' of this window is animated.",
        WrapText = true,
      };

      LoadingAnimation = new SingleFromToByAnimation
      {
        TargetProperty = "Opacity",           // Transition the property UIControl.Opacity 
        From = 0,                             // from 0 to its actual value
        Duration = TimeSpan.FromSeconds(0.3), // over a duration of 0.3 seconds.
      };

      ClosingAnimation = new SingleFromToByAnimation
      {
        TargetProperty = "Opacity",           // Transition the property UIControl.Opacity
        To = 0,                               // from its current value to 0
        Duration = TimeSpan.FromSeconds(0.3), // over a duration 0.3 seconds.
      };
    }
        public void StartStopAnimationWithinOneFrame()
        {
            var property = new AnimatableProperty <float> {
                Value = 123.4f
            };
            var manager = new AnimationManager();

            var animation = new SingleFromToByAnimation
            {
                Duration     = TimeSpan.Zero,
                To           = 234.5f,
                FillBehavior = FillBehavior.Stop,
            };

            var controller = manager.CreateController(animation, property);

            Assert.AreEqual(123.4f, property.Value);

            // Start
            controller.Start();
            controller.UpdateAndApply();
            Assert.AreEqual(234.5f, property.Value);

            // Stop
            controller.Stop();
            controller.UpdateAndApply();
            Assert.AreEqual(123.4f, property.Value);
        }
Exemple #15
0
        public void GetDescendantsDepthFirst()
        {
            var animationA = new TimelineGroup();
            var animationB = new SingleFromToByAnimation();
            var animationC = new SingleFromToByAnimation();
            var animationD = new TimelineGroup();
            var animationE = new TimelineGroup();
            var animationF = new SingleFromToByAnimation();
            var animationG = new TimelineGroup();

            animationA.Add(animationB);
            animationA.Add(animationC);
            animationA.Add(animationD);
            animationD.Add(animationE);
            animationD.Add(animationF);
            animationE.Add(animationG);

            Assert.That(() => AnimationHelper.GetDescendants(null), Throws.TypeOf <ArgumentNullException>());

            var animationInstance = animationA.CreateInstance();
            var descendants       = animationInstance.GetDescendants().ToArray();

            Assert.AreEqual(6, descendants.Length);
            Assert.AreEqual(animationInstance.Children[0], descendants[0]);
            Assert.AreEqual(animationInstance.Children[1], descendants[1]);
            Assert.AreEqual(animationInstance.Children[2], descendants[2]);
            Assert.AreEqual(animationInstance.Children[2].Children[0], descendants[3]);
            Assert.AreEqual(animationInstance.Children[2].Children[0].Children[0], descendants[4]);
            Assert.AreEqual(animationInstance.Children[2].Children[1], descendants[5]);
        }
        public void ShouldDoNothingIfInvalid()
        {
            var manager    = new AnimationManager();
            var property   = new AnimatableProperty <float>();
            var animation  = new SingleFromToByAnimation();
            var controller = manager.CreateController(animation, property);

            controller.Recycle();
            Assert.IsFalse(controller.IsValid);

            // The following has no effect.
            controller.AutoRecycleEnabled = false;
            controller.Time = TimeSpan.Zero;
            controller.AutoRecycle();
            controller.Recycle();
            controller.Pause();
            controller.Resume();
            controller.Stop();
            controller.Stop(TimeSpan.Zero);
            controller.Stop(TimeSpan.FromSeconds(1.0));

            // Only Start and UpdateAndApply should throw an exceptions.
            Assert.That(() => controller.Start(), Throws.TypeOf <AnimationException>());
            Assert.That(() => controller.UpdateAndApply(), Throws.TypeOf <AnimationException>());
        }
Exemple #17
0
    public BasicAnimationSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var titleSafeArea = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea;
      float minX = titleSafeArea.Left + 100;
      float maxX = titleSafeArea.Right - 100;

      // A from/to/by animation that animates a float value from minX to maxX over 2 seconds
      // using an easing function smooth movement.
      SingleFromToByAnimation xAnimation = new SingleFromToByAnimation
      {
        From = minX,
        To = maxX,
        Duration = TimeSpan.FromSeconds(2),
        EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut },
      };

      // From-To-By animations do not loop by default.
      // Use an AnimationClip to turn the 2 second xAnimation into an animation that
      // oscillates forever.
      _oscillatingXAnimation = new AnimationClip<float>(xAnimation)
      {
        LoopBehavior = LoopBehavior.Oscillate,
        Duration = TimeSpan.MaxValue,
      };


      // A color key-frame animation.
      ColorKeyFrameAnimation colorAnimation = new ColorKeyFrameAnimation
      {
        //EnableInterpolation = true,  // Interpolation is enabled by default.
      };
      // Add the key-frames.
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0.0), Color.Red));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0.5), Color.Orange));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1.0), Color.Yellow));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1.5), Color.Green));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(2.0), Color.Blue));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(2.5), Color.Indigo));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.0), Color.Violet));

      // The last-key frame defines the length of the animation (3.5 seconds). This is a
      // "loop frame", which means the value is the same as in the first key to create a looping
      // animation.
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.5), Color.Red));

      // If the key-frames are not sorted, call Sort().
      //colorAnimation.KeyFrames.Sort();

      // Use an AnimationClip to turn the 3.5 second colorAnimation into an animation that
      // loops forever.
      _loopedColorAnimation = new AnimationClip<Color>(colorAnimation)
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };

      StartAnimations();
    }
Exemple #18
0
        public void CreateInstanceTest()
        {
            var animationInstance = new SingleFromToByAnimation().CreateInstance();
              Assert.IsNotNull(animationInstance);

              var timelineInstance = ((ITimeline)new SingleFromToByAnimation()).CreateInstance();
              Assert.IsNotNull(timelineInstance);
        }
        public void AnimateProperty()
        {
            var property = new AnimatableProperty <float> {
                Value = 10.0f
            };

            var animationA = new SingleFromToByAnimation
            {
                From           = 100.0f,
                To             = 200.0f,
                TargetObject   = "ObjectA",   // Should be ignored.
                TargetProperty = "PropertyA", // Should be ignored.
            };
            var animationB = new SingleFromToByAnimation
            {
                From           = 200.0f,
                To             = 300.0f,
                TargetObject   = "ObjectB",   // Should be ignored.
                TargetProperty = "PropertyB", // Should be ignored.
            };
            var animationGroup = new TimelineGroup();

            animationGroup.Add(animationA);
            animationGroup.Add(animationB);

            var manager = new AnimationManager();

            // Should assign both animations to 'property'.
            var controller = manager.CreateController(animationGroup, property);

            Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[0]).Property);
            Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property);
            Assert.IsFalse(manager.IsAnimated(property));

            // When started then animationB (last in the composition chain) should be active.
            controller.Start();
            controller.UpdateAndApply();
            Assert.AreEqual(200.0f, property.Value);
            Assert.IsTrue(manager.IsAnimated(property));

            controller.Stop();
            controller.UpdateAndApply();
            Assert.AreEqual(10.0f, property.Value);
            Assert.IsFalse(manager.IsAnimated(property));

            // Same test for AnimationManager.StartAnimation()
            controller = manager.StartAnimation(animationGroup, property);
            controller.UpdateAndApply();
            Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[0]).Property);
            Assert.AreEqual(property, ((AnimationInstance <float>)controller.AnimationInstance.Children[1]).Property);
            Assert.AreEqual(200.0f, property.Value);
            Assert.IsTrue(manager.IsAnimated(property));

            manager.StopAnimation(property);
            manager.UpdateAndApplyAnimation(property);
            Assert.AreEqual(10.0f, property.Value);
            Assert.IsFalse(manager.IsAnimated(property));
        }
Exemple #20
0
        public void BlendGroupWithTwoAnimationsSynchronized()
        {
            var property1 = new AnimatableProperty <float> {
                Value = 123.45f
            };

            var blendGroup = new BlendGroup {
                FillBehavior = FillBehavior.Stop
            };
            var animation1 = new SingleFromToByAnimation {
                From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0)
            };
            var animation2 = new SingleFromToByAnimation {
                From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0)
            };

            blendGroup.Add(animation1);
            blendGroup.Add(animation2);
            Assert.AreEqual(1.0f, blendGroup.GetWeight(0));
            Assert.AreEqual(1.0f, blendGroup.GetWeight(1));
            Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration());

            blendGroup.SynchronizeDurations();
            Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration());

            var manager    = new AnimationManager();
            var controller = manager.StartAnimation(blendGroup, property1);

            controller.UpdateAndApply();
            Assert.AreEqual(50.0f, property1.Value);

            manager.Update(TimeSpan.FromSeconds(0.75)); // t = 0.75
            manager.ApplyAnimations();
            Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration());
            Assert.AreEqual(0.5f * 50.0f + 0.5f * 200.0f, property1.Value);

            blendGroup.SetWeight(0, 0);
            Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration());
            manager.Update(TimeSpan.FromSeconds(0.25)); // t = 1.0
            manager.ApplyAnimations();
            Assert.AreEqual(200.0f, property1.Value);

            blendGroup.SetWeight(0, 10);
            blendGroup.SetWeight(1, 0);
            Assert.AreEqual(TimeSpan.FromSeconds(1.0), blendGroup.GetTotalDuration());
            manager.Update(TimeSpan.Zero); // t = 1.0
            manager.ApplyAnimations();
            Assert.AreEqual(100.0f, property1.Value);

            blendGroup.SetWeight(0, 10);
            blendGroup.SetWeight(1, 1);
            Assert.AreEqual(new TimeSpan((long)((1.0f * 10.0f / 11.0f + 2.0f * 1.0f / 11.0f) * TimeSpan.TicksPerSecond)), blendGroup.GetTotalDuration());
            manager.Update(TimeSpan.FromSeconds(0.5)); // t = 1.5
            manager.ApplyAnimations();
            Assert.AreEqual(123.45f, property1.Value);
            Assert.AreEqual(AnimationState.Stopped, controller.State);
        }
        public void ComposeAfterWithFadeIn()
        {
            var property = new AnimatableProperty <float> {
                Value = 100.0f
            };
            var animationA = new SingleFromToByAnimation
            {
                Duration = TimeSpan.Zero,
                To       = 200.0f,
            };

            var manager = new AnimationManager();

            var controllerA = manager.CreateController(animationA, property);

            Assert.AreEqual(100.0f, property.Value);

            controllerA.Start(AnimationTransitions.Compose(TimeSpan.FromSeconds(1.0)));
            Assert.AreEqual(100.0f, property.Value);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(150.0f, property.Value);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(200.0f, property.Value);

            var animationB = new SingleFromToByAnimation
            {
                Duration = TimeSpan.Zero,
                By       = 10.0f,
            };

            var controllerB = manager.CreateController(animationB, property);

            Assert.AreEqual(200.0f, property.Value);

            controllerB.Start(AnimationTransitions.Compose(controllerA.AnimationInstance, TimeSpan.FromSeconds(1.0)));
            Assert.AreEqual(200.0f, property.Value);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(205.0f, property.Value);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(210.0f, property.Value);

            controllerA.Stop();
            controllerA.UpdateAndApply();
            Assert.AreEqual(110.0f, property.Value);

            controllerB.Stop();
            controllerB.UpdateAndApply();
            Assert.AreEqual(100.0f, property.Value);
        }
Exemple #22
0
        /// <summary>
        /// Called every frame when "Start" state is active.
        /// </summary>
        private void OnUpdateStartScreen(object sender, StateEventArgs eventArgs)
        {
            if (_exitAnimationIsPlaying)
            {
                return;
            }

            bool transitionToMenu = false;

            // Check if the user presses A or START on any connected gamepad.
            for (var controller = PlayerIndex.One; controller <= PlayerIndex.Four; controller++)
            {
                if (InputService.IsDown(Buttons.A, controller) || InputService.IsDown(Buttons.Start, controller))
                {
                    // A or START was pressed. Assign this controller to the first "logical player".
                    InputService.SetLogicalPlayer(LogicalPlayerIndex.One, controller);
                    transitionToMenu = true;
                }
            }

            if (InputService.IsDown(MouseButtons.Left) ||
                InputService.IsDown(Keys.Enter) ||
                InputService.IsDown(Keys.Escape) ||
                InputService.IsDown(Keys.Space))
            {
                // The users has pressed the left mouse button or a key on the keyboard.

                if (!InputService.GetLogicalPlayer(LogicalPlayerIndex.One).HasValue)
                {
                    // No controller has been assigned to the first "logical player". Maybe
                    // there is no gamepad connected.
                    // --> Just guess which controller is the primary player and continue.
                    InputService.SetLogicalPlayer(LogicalPlayerIndex.One, PlayerIndex.One);
                }

                transitionToMenu = true;
            }

            if (transitionToMenu)
            {
                // Play a fade-out animation which changes the opacity from its current
                // value to 0.
                var fadeOutAnimation = new SingleFromToByAnimation
                {
                    To       = 0,                         // Animate the opacity from the current value to 0
                    Duration = TimeSpan.FromSeconds(0.5), // over a duration of 0.5 seconds.
                };
                var opacityProperty = _startTextBlock.Properties.Get <float>(TextBlock.OpacityPropertyId).AsAnimatable();
                _exitAnimationController = AnimationService.StartAnimation(fadeOutAnimation, opacityProperty);

                // When the fade-out animation finished trigger the transition from the "Start"
                // screen to the "Menu" screen.
                _exitAnimationController.Completed += (s, e) => _stateMachine.States.ActiveState.Transitions["StartToMenu"].Fire();

                _exitAnimationIsPlaying = true;
            }
        }
Exemple #23
0
 public void AnimateTo()
 {
     var animation = new SingleFromToByAnimation();
       animation.From = null;
       animation.To = 20.0f;
       animation.By = null;
       Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f));
       Assert.AreEqual(10.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f));
       Assert.AreEqual(20.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f));
 }
        public void CreateInstanceTest()
        {
            var animationInstance = new SingleFromToByAnimation().CreateInstance();

            Assert.IsNotNull(animationInstance);

            var timelineInstance = ((ITimeline) new SingleFromToByAnimation()).CreateInstance();

            Assert.IsNotNull(timelineInstance);
        }
Exemple #25
0
        // The following code contains two helper methods to animate the opacity and offset
        // of a group of UI controls. The methods basically do the same, they animate the
        // properties from/to a specific value. However the methods demonstrate two different
        // approaches.
        //
        // The AnimateFrom method uses a more direct approach. It directly starts an
        // animation for each UI control in list, thereby creating several independently
        // running animations.
        //
        // The AnimateTo method uses a more declarative approach. All animations are
        // defined and assigned to the target objects by setting the name of the UI control
        // in the TargetObject property. Then all animations are grouped together into
        // a single animation. When the resulting animation is started the animation system
        // creates the required animation instances and assigns the instances to the correct
        // objects and properties by matching the TargetObject and TargetProperty with the
        // name of the UI controls and their properties.
        //
        // Both methods achieve a similar result. The advantage of the first method is more
        // direct control. The advantage of the seconds method is that only a single animation
        // controller is required to control all animations at once.

        /// <summary>
        /// Animates the opacity and offset of a group of controls from the specified value to their
        /// current value.
        /// </summary>
        /// <param name="controls">The UI controls to be animated.</param>
        /// <param name="opacity">The initial opacity.</param>
        /// <param name="offset">The initial offset.</param>
        private void AnimateFrom(IList <UIControl> controls, float opacity, Vector2F offset)
        {
            TimeSpan duration = TimeSpan.FromSeconds(0.8);

            // First, let's define the animation that is going to be applied to a control.
            // Animate the "Opacity" from the specified value to its current value.
            var opacityAnimation = new SingleFromToByAnimation
            {
                TargetProperty = "Opacity",
                From           = opacity,
                Duration       = duration,
                EasingFunction = new CubicEase {
                    Mode = EasingMode.EaseOut
                },
            };

            // Animate the "RenderTranslation" property from the specified offset to its
            // its current value, which is usually (0, 0).
            var offsetAnimation = new Vector2FFromToByAnimation
            {
                TargetProperty = "RenderTranslation",
                From           = offset,
                Duration       = duration,
                EasingFunction = new CubicEase {
                    Mode = EasingMode.EaseOut
                },
            };

            // Group the opacity and offset animation together using a TimelineGroup.
            var timelineGroup = new TimelineGroup();

            timelineGroup.Add(opacityAnimation);
            timelineGroup.Add(offsetAnimation);

            // Run the animation on each control using a negative delay to give the first controls
            // a slight head start.
            var numberOfControls = controls.Count;

            for (int i = 0; i < controls.Count; i++)
            {
                var clip = new TimelineClip(timelineGroup)
                {
                    Delay        = TimeSpan.FromSeconds(-0.04 * (numberOfControls - i)),
                    FillBehavior = FillBehavior.Stop, // Stop and remove the animation when it is done.
                };
                var animationController = AnimationService.StartAnimation(clip, controls[i]);

                animationController.UpdateAndApply();

                // Enable "auto-recycling" to ensure that the animation resources are recycled once
                // the animation stops or the target objects are garbage collected.
                animationController.AutoRecycle();
            }
        }
        public void ShouldIgnoreByIfToIsSet()
        {
            var animation = new SingleFromToByAnimation();

            animation.From = null;
            animation.To   = 40.0f;
            animation.By   = 100.0f;
            Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f));
            Assert.AreEqual(20.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f));
            Assert.AreEqual(40.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f));
        }
        public void AnimateTo()
        {
            var animation = new SingleFromToByAnimation();

            animation.From = null;
            animation.To   = 20.0f;
            animation.By   = null;
            Assert.AreEqual(0.0f, animation.GetValue(TimeSpan.FromSeconds(0.0), 0.0f, 100.0f));
            Assert.AreEqual(10.0f, animation.GetValue(TimeSpan.FromSeconds(0.5), 0.0f, 100.0f));
            Assert.AreEqual(20.0f, animation.GetValue(TimeSpan.FromSeconds(1.0), 0.0f, 100.0f));
        }
        public void TargetObjectTest()
        {
            var animation = new SingleFromToByAnimation();

            Assert.IsNull(animation.TargetObject);

            animation.TargetObject = "";
            Assert.IsEmpty(animation.TargetObject);

            animation.TargetObject = "Object XY";
            Assert.AreEqual("Object XY", animation.TargetObject);
        }
        public void SetAnimationTime()
        {
            var manager    = new AnimationManager();
            var property   = new AnimatableProperty <float>();
            var animation  = new SingleFromToByAnimation();
            var controller = manager.StartAnimation(animation, property);

            Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);
            controller.Time = TimeSpan.FromSeconds(0.5);
            Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time);
            Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.AnimationInstance.Time);
        }
        public void TargetPropertyTest()
        {
            var animation = new SingleFromToByAnimation();

            Assert.IsNull(animation.TargetProperty);

            animation.TargetProperty = "";
            Assert.IsEmpty(animation.TargetProperty);

            animation.TargetProperty = "Property XY";
            Assert.AreEqual("Property XY", animation.TargetProperty);
        }
Exemple #31
0
 /// <inheritdoc/>
 protected override void OnInitialize(AnimationManager animationManager)
 {
     // Start fade-out animation on animation weight.
       var fadeOutAnimation = new SingleFromToByAnimation
       {
     To = 0,
     Duration = _fadeOutDuration,
     EasingFunction = DefaultEase,
     FillBehavior = FillBehavior.Stop,
       };
       _fadeOutController = animationManager.StartAnimation(fadeOutAnimation, AnimationInstance.WeightProperty);
 }
Exemple #32
0
        public void BlendGroupWithOneAnimation()
        {
            var property1 = new AnimatableProperty <float> {
                Value = 123.45f
            };

            var blendGroup = new BlendGroup {
                FillBehavior = FillBehavior.Stop
            };
            var animation = new SingleFromToByAnimation {
                From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0)
            };

            blendGroup.Add(animation);
            Assert.AreEqual(1.0f, blendGroup.GetWeight(0));
            Assert.AreEqual(1.0f, blendGroup.GetWeight(animation));

            blendGroup.SetWeight(0, 10.0f);
            Assert.AreEqual(10.0f, blendGroup.GetWeight(0));
            Assert.AreEqual(10.0f, blendGroup.GetWeight(animation));

            blendGroup.SetWeight(animation, 0.5f);
            Assert.AreEqual(0.5f, blendGroup.GetWeight(0));
            Assert.AreEqual(0.5f, blendGroup.GetWeight(animation));

            var manager    = new AnimationManager();
            var controller = manager.StartAnimation(blendGroup, property1);

            controller.UpdateAndApply();
            Assert.AreEqual(0.0f, property1.Value);

            manager.Update(TimeSpan.FromSeconds(0.25));
            manager.ApplyAnimations();
            Assert.AreEqual(25.0f, property1.Value);

            manager.Update(TimeSpan.FromSeconds(0.25));
            manager.ApplyAnimations();
            Assert.AreEqual(50.0f, property1.Value);

            manager.Update(TimeSpan.FromSeconds(0.25));
            manager.ApplyAnimations();
            Assert.AreEqual(75.0f, property1.Value);

            manager.Update(TimeSpan.FromSeconds(0.25));
            manager.ApplyAnimations();
            Assert.AreEqual(100.0f, property1.Value);

            manager.Update(TimeSpan.FromSeconds(0.25));
            manager.ApplyAnimations();
            Assert.AreEqual(123.45f, property1.Value);
            Assert.AreEqual(AnimationState.Stopped, controller.State);
        }
Exemple #33
0
        private AnimationController _exitAnimationController; // Controls the fade-out animation.


        /// <summary>
        /// Called when "Start" state is entered.
        /// </summary>
        private void OnEnterStartScreen(object sender, StateEventArgs eventArgs)
        {
            // Show the "Press Start button" text centered on the screen.
            _startTextBlock = new TextBlock
            {
                Name = "StartTextBlock",
                Text = "Press Start button",
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment   = VerticalAlignment.Center,
            };
            _uiScreen.Children.Add(_startTextBlock);

            // The text should pulse to indicate that a user interaction is required.
            // To achieve this we can animate the opacity of the TextBlock.
            var opacityAnimation = new SingleFromToByAnimation
            {
                From           = 1,                         // Animate from opaque (Opacity == 1)
                To             = 0.25f,                     // to nearly transparent (Opacity == 0.25)
                Duration       = TimeSpan.FromSeconds(0.5), // over a duration of 0.5 seconds.
                EasingFunction = new SineEase {
                    Mode = EasingMode.EaseInOut
                }
            };

            // A SingleFromToByAnimation plays only once, but the animation should be
            // played back-and-forth until the user presses a button.
            // We need wrap the SingleFromToByAnimation in an AnimationClip or TimelineClip.
            // Animation clips can be used to cut and loop other animations.
            var loopingOpacityAnimation = new AnimationClip <float>(opacityAnimation)
            {
                LoopBehavior = LoopBehavior.Oscillate, // Play back-and-forth.
                Duration     = TimeSpan.MaxValue       // Loop forever.
            };

            // We want to apply the animation to the "Opacity" property of the TextBlock.
            // All "game object properties" of a UIControl can be made "animatable".
            // First, get a handle to the "Opacity" property.
            var opacityProperty = _startTextBlock.Properties.Get <float>(TextBlock.OpacityPropertyId);

            // Then cast the "Opacity" property to an IAnimatableProperty.
            var animatableOpacityProperty = opacityProperty.AsAnimatable();

            // Start the pulse animation.
            var animationController = AnimationService.StartAnimation(loopingOpacityAnimation, animatableOpacityProperty);

            // Enable "automatic recycling". This step is optional. It ensures that the
            // associated resources are recycled when either the animation is stopped or
            // the target object (the TextBlock) is garbage collected.
            // (The associated resources will be reused by future animations, which will
            // reduce the number of required memory allocations at runtime.)
            animationController.AutoRecycle();
        }
        public void CheckDefaultValues()
        {
            var animation = new SingleFromToByAnimation();

            Assert.AreEqual(TimeSpan.FromSeconds(1.0), animation.Duration);
            Assert.AreEqual(FillBehavior.Hold, animation.FillBehavior);
            Assert.IsNull(animation.TargetProperty);
            Assert.IsFalse(animation.From.HasValue);
            Assert.IsFalse(animation.To.HasValue);
            Assert.IsFalse(animation.By.HasValue);
            Assert.IsFalse(animation.IsAdditive);
            Assert.IsNull(animation.EasingFunction);
        }
Exemple #35
0
        /// <inheritdoc/>
        protected override void OnInitialize(AnimationManager animationManager)
        {
            // Start fade-out animation on animation weight.
            var fadeOutAnimation = new SingleFromToByAnimation
            {
                To             = 0,
                Duration       = _fadeOutDuration,
                EasingFunction = DefaultEase,
                FillBehavior   = FillBehavior.Stop,
            };

            _fadeOutController = animationManager.StartAnimation(fadeOutAnimation, AnimationInstance.WeightProperty);
        }
Exemple #36
0
        public void ShouldThrowWhenAnimationWeightIsOutOfRange()
        {
            var animationInstance = new SingleFromToByAnimation().CreateInstance();

            // Valid range.
            animationInstance.Weight = 0.0f;
            animationInstance.Weight = 1.0f;

            // Invalid range.
            Assert.That(() => animationInstance.Weight = -0.1f, Throws.TypeOf <ArgumentOutOfRangeException>());
            Assert.That(() => animationInstance.Weight = 1.1f, Throws.TypeOf <ArgumentOutOfRangeException>());
            Assert.That(() => animationInstance.Weight = float.NaN, Throws.TypeOf <ArgumentOutOfRangeException>());
        }
Exemple #37
0
        public void ShouldThrowWhenAnimationWeightIsOutOfRange()
        {
            var animationInstance = new SingleFromToByAnimation().CreateInstance();

              // Valid range.
              animationInstance.Weight = 0.0f;
              animationInstance.Weight = 1.0f;

              // Invalid range.
              Assert.That(() => animationInstance.Weight = -0.1f, Throws.TypeOf<ArgumentOutOfRangeException>());
              Assert.That(() => animationInstance.Weight = 1.1f, Throws.TypeOf<ArgumentOutOfRangeException>());
              Assert.That(() => animationInstance.Weight = float.NaN, Throws.TypeOf<ArgumentOutOfRangeException>());
        }
Exemple #38
0
 /// <inheritdoc/>
 protected override void OnInitialize(AnimationManager animationManager)
 {
     // Start fade-in animation on animation weight.
       var fadeInAnimation = new SingleFromToByAnimation
       {
     From = 0,
     Duration = _fadeInDuration,
     EasingFunction = DefaultEase,
     FillBehavior = FillBehavior.Stop,
       };
       animationManager.StartAnimation(fadeInAnimation, AnimationInstance.WeightProperty);
       animationManager.Add(AnimationInstance, HandoffBehavior.Compose, _previousAnimation);
       animationManager.Remove(this);
 }
        public void ShouldRemoveAnimationsIfInactive()
        {
            var obj      = new AnimatableObject("TestObject");
            var property = new AnimatableProperty <float>();

            obj.Properties.Add("Value", property);

            var animation = new SingleFromToByAnimation
            {
                From           = 100.0f,
                To             = 200.0f,
                TargetProperty = "Value",
            };

            var manager     = new AnimationManager();
            var controllerA = manager.StartAnimation(animation, obj);

            controllerA.AutoRecycle();
            controllerA.UpdateAndApply();
            Assert.AreEqual(100.0f, property.Value);
            Assert.IsTrue(controllerA.IsValid);

            manager.Update(TimeSpan.FromSeconds(0.5));
            manager.ApplyAnimations();
            Assert.AreEqual(150.0f, property.Value);
            Assert.IsTrue(controllerA.IsValid);

            // Replace animation instance with new instance.
            var controllerB = manager.StartAnimation(animation, obj);

            controllerB.AutoRecycle();
            controllerB.UpdateAndApply();
            Assert.AreEqual(100.0f, property.Value);
            Assert.IsTrue(controllerA.IsValid);
            Assert.IsTrue(controllerB.IsValid);

            // controllerA should be removed automatically.
            // (Note: Cleanup is done incrementally, not every frame.
            // It is okay if it takes a few updates.)
            manager.Update(TimeSpan.FromSeconds(0.1));
            manager.Update(TimeSpan.FromSeconds(0.1));
            manager.Update(TimeSpan.FromSeconds(0.1));
            manager.Update(TimeSpan.FromSeconds(0.1));
            manager.Update(TimeSpan.FromSeconds(0.1));
            manager.ApplyAnimations();
            Assert.AreEqual(150.0f, property.Value);
            Assert.IsFalse(controllerA.IsValid);
            Assert.IsTrue(controllerB.IsValid);
        }
Exemple #40
0
        /// <inheritdoc/>
        protected override void OnInitialize(AnimationManager animationManager)
        {
            // Start fade-in animation on animation weight.
              var fadeInAnimation = new SingleFromToByAnimation
              {
            From = 0,
            Duration = _fadeInDuration,
            EasingFunction = DefaultEase,
            FillBehavior = FillBehavior.Stop,
              };
              _fadeInController = animationManager.StartAnimation(fadeInAnimation, AnimationInstance.WeightProperty);

              // Add animation.
              animationManager.Add(AnimationInstance, HandoffBehavior.Compose, null);
        }
        /// <inheritdoc/>
        protected override void OnInitialize(AnimationManager animationManager)
        {
            // Start fade-in animation on animation weight.
            var fadeInAnimation = new SingleFromToByAnimation
            {
                From           = 0,
                Duration       = _fadeInDuration,
                EasingFunction = DefaultEase,
                FillBehavior   = FillBehavior.Stop,
            };

            animationManager.StartAnimation(fadeInAnimation, AnimationInstance.WeightProperty);
            animationManager.Add(AnimationInstance, HandoffBehavior.Compose, _previousAnimation);
            animationManager.Remove(this);
        }
Exemple #42
0
        public void AutoRecycleEnabled()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation();
              var controller = manager.CreateController(animation, property);

              controller.Start();
              controller.Stop();
              Assert.IsTrue(controller.IsValid);

              controller.AutoRecycleEnabled = true;

              controller.Start();
              controller.Stop();
              Assert.IsFalse(controller.IsValid);
        }
Exemple #43
0
        public void AdditiveAnimation()
        {
            var property = new AnimatableProperty<float> { Value = 123.4f };
              var manager = new AnimationManager();

              // Start base animation.
              var animation0 = new SingleFromToByAnimation
              {
            Duration = TimeSpan.FromSeconds(1.0),
            To = 234.5f,
            FillBehavior = FillBehavior.Stop,
              };
              var controller0 = manager.StartAnimation(animation0, property);
              Assert.AreEqual(123.4f, property.Value);

              // Start additive animation.
              var animation1 = new SingleFromToByAnimation
              {
            Duration = TimeSpan.FromSeconds(1.0),
            From = 0.0f,
            To = 10.0f,
            IsAdditive = true,
            FillBehavior = FillBehavior.Hold,
              };
              var controller1 = manager.StartAnimation(animation1, property, AnimationTransitions.Compose());
              Assert.AreEqual(123.4f, property.Value);

              manager.Update(TimeSpan.FromSeconds(1.0));
              Assert.AreEqual(123.4f, property.Value);

              manager.ApplyAnimations();
              Assert.AreEqual(234.5f + 10.0f, property.Value);

              manager.Update(new TimeSpan(166666));
              Assert.AreEqual(234.5f + 10.0f, property.Value);

              manager.ApplyAnimations();
              Assert.AreEqual(123.4f + 10.0f, property.Value);

              // Stop additive animation.
              controller1.Stop();
              controller1.UpdateAndApply();
              Assert.AreEqual(123.4f, property.Value);
        }
Exemple #44
0
        public void BlendGroupWithOneAnimation()
        {
            var property1 = new AnimatableProperty<float> { Value = 123.45f };

              var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop };
              var animation = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) };
              blendGroup.Add(animation);
              Assert.AreEqual(1.0f, blendGroup.GetWeight(0));
              Assert.AreEqual(1.0f, blendGroup.GetWeight(animation));

              blendGroup.SetWeight(0, 10.0f);
              Assert.AreEqual(10.0f, blendGroup.GetWeight(0));
              Assert.AreEqual(10.0f, blendGroup.GetWeight(animation));

              blendGroup.SetWeight(animation, 0.5f);
              Assert.AreEqual(0.5f, blendGroup.GetWeight(0));
              Assert.AreEqual(0.5f, blendGroup.GetWeight(animation));

              var manager = new AnimationManager();
              var controller = manager.StartAnimation(blendGroup, property1);
              controller.UpdateAndApply();
              Assert.AreEqual(0.0f, property1.Value);

              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(25.0f, property1.Value);

              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(50.0f, property1.Value);

              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(75.0f, property1.Value);

              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(100.0f, property1.Value);

              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(123.45f, property1.Value);
              Assert.AreEqual(AnimationState.Stopped, controller.State);
        }
Exemple #45
0
        public void AnimateProperty()
        {
            var testObject = new TestObject { Value = 10.0f };
              Func<float> getter = () => testObject.Value;
              Action<float> setter = f => { testObject.Value = f; };
              var property = new DelegateAnimatableProperty<float>(null, null);

              var animation = new SingleFromToByAnimation
              {
            From = 100,
            To = 200,
            Duration = TimeSpan.FromSeconds(1.0),
            IsAdditive = true,
              };

              var manager = new AnimationManager();
              var controller = manager.StartAnimation(animation, property);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();

              property.GetValue = getter;
              property.SetValue = setter;

              manager.ApplyAnimations();

              Assert.AreEqual(150.0f, testObject.Value);
              Assert.IsTrue(((IAnimatableProperty)property).IsAnimated);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();

              Assert.AreEqual(200.0f, testObject.Value);
              Assert.IsTrue(((IAnimatableProperty)property).IsAnimated);

              controller.Stop();
              controller.UpdateAndApply();
              Assert.AreEqual(200.0f, testObject.Value);
              Assert.IsFalse(((IAnimatableProperty)property).IsAnimated);
        }
        protected override void LoadContent()
        {
            Rectangle bounds = GraphicsDevice.Viewport.TitleSafeArea;

              // A single from/to animation.
              SingleFromToByAnimation fromToAnimation = new SingleFromToByAnimation
              {
            From = bounds.Top + 200,
            To = bounds.Bottom - 200,
            Duration = TimeSpan.FromSeconds(2),
            EasingFunction = new SineEase { Mode = EasingMode.EaseInOut },
              };

              // Create an animation that oscillates forever.
              AnimationClip<float> loopedSingleAnimationX = new AnimationClip<float>(fromToAnimation)
              {
            LoopBehavior = LoopBehavior.Oscillate,
            Duration = TimeSpan.MaxValue,
              };

              // Create an animation that oscillates forever. The animations starts 1 second into
              // the fromToAnimation - that means, loopedSingleAnimationX is 1 second "behind" this
              // animation.
              AnimationClip<float> loopedSingleAnimationY = new AnimationClip<float>(fromToAnimation)
              {
            LoopBehavior = LoopBehavior.Oscillate,
            Duration = TimeSpan.MaxValue,
            Delay = TimeSpan.FromSeconds(-1),
              };

              // Create a composite animation that combines the two float animations to animate
              // a Vector2 value.
              Vector2Animation compositeAnimation = new Vector2Animation(loopedSingleAnimationX, loopedSingleAnimationY);

              // Start animation.
              AnimationService.StartAnimation(compositeAnimation, _animatablePosition);

              base.LoadContent();
        }
Exemple #47
0
        public void ComposeAfter()
        {
            var property = new AnimatableProperty<float> { Value = 100.0f };
              var animationA = new SingleFromToByAnimation
              {
            Duration = TimeSpan.Zero,
            To = 200.0f,
              };

              var manager = new AnimationManager();

              var controllerA = manager.CreateController(animationA, property);
              Assert.AreEqual(100.0f, property.Value);

              controllerA.Start(AnimationTransitions.Compose());
              controllerA.UpdateAndApply();
              Assert.AreEqual(200.0f, property.Value);

              var animationB = new SingleFromToByAnimation
              {
            Duration = TimeSpan.Zero,
            By = 10.0f,
              };

              var controllerB = manager.CreateController(animationB, property);
              Assert.AreEqual(200.0f, property.Value);

              controllerB.Start(AnimationTransitions.Compose(controllerB.AnimationInstance));
              controllerB.UpdateAndApply();
              Assert.AreEqual(210.0f, property.Value);

              controllerA.Stop();
              controllerA.UpdateAndApply();
              Assert.AreEqual(110.0f, property.Value);

              controllerB.Stop();
              controllerB.UpdateAndApply();
              Assert.AreEqual(100.0f, property.Value);
        }
Exemple #48
0
        public void AnimationBlending()
        {
            var animation = new SingleFromToByAnimation
              {
            From = 100,
            To = 200,
            IsAdditive = true,
            Duration = TimeSpan.FromSeconds(1),
              };

              var animationInstance = animation.CreateInstance() as AnimationInstance<float>;
              animationInstance.Time = TimeSpan.FromSeconds(0.5);

              animationInstance.Weight = 0.0f;
              Assert.AreEqual(1.0f, animationInstance.GetValue(1.0f, 2.0f));

              animationInstance.Weight = 1.0f;
              Assert.AreEqual(151.0f, animationInstance.GetValue(1.0f, 2.0f));

              animationInstance.Weight = 0.75f;
              Assert.AreEqual(1.0f + 0.75f * 150.0f, animationInstance.GetValue(1.0f, 2.0f));
        }
Exemple #49
0
        public void StopAnimationImmediately()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation
              {
            From = 100.0f,
            To = 200.0f,
              };
              var controller = manager.StartAnimation(animation, property);
              controller.UpdateAndApply();
              Assert.AreEqual(100.0f, property.Value);

              controller.Stop(TimeSpan.Zero);
              controller.UpdateAndApply();
              Assert.AreEqual(0.0f, property.Value);
        }
Exemple #50
0
    // Called when the "Animate" button was clicked.
    private void OnButtonClicked(object sender, EventArgs eventArgs)
    {
      // Get the selected easing function from the DropDownButton.
      EasingFunction easingFunction = (EasingFunction)_functionDropDown.Items[_functionDropDown.SelectedIndex];

      // Set the selected easing mode.
      easingFunction.Mode = (EasingMode)_modeDropDown.Items[_modeDropDown.SelectedIndex];

      // The current slider value:
      float startValue = _slider.Value;

      // Set the slider to the target value.
      _slider.Value = (startValue > 0.5f) ? 0 : 1;

      // Create a from-animation that uses the easing function. It animates the slider
      // value from startValue to the new value.
      SingleFromToByAnimation animation = new SingleFromToByAnimation
      {
        TargetProperty = "Value",
        From = startValue,
        Duration = TimeSpan.FromSeconds(1),
        EasingFunction = easingFunction,
        FillBehavior = FillBehavior.Stop,  // Stop the animation when it is finished. 
      };

      // Start the animation.
      // (Use the Replace transition to replace any currently running animations.
      // This is necessary because the user could press the Animate button while 
      // an animation is running.)
      _animationService.StartAnimation(animation, _slider, AnimationTransitions.Replace())
                       .UpdateAndApply();  // Apply new animation value immediately.
    }
Exemple #51
0
        public void CopyTo()
        {
            var blendGroup = new BlendGroup();
              ITimeline[] array = new ITimeline[0];
              Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(null, 0), Throws.TypeOf<ArgumentNullException>());
              Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, -1), Throws.TypeOf<ArgumentOutOfRangeException>());
              Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, 1), Throws.ArgumentException);
              Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, 0), Throws.Nothing);

              var animation0 = new SingleFromToByAnimation();
              var animation1 = new SingleFromToByAnimation();
              blendGroup = new BlendGroup { animation0, animation1 };

              array = new ITimeline[1];
              Assert.That(() => ((IList<ITimeline>)blendGroup).CopyTo(array, 0), Throws.ArgumentException);

              array = new ITimeline[2];
              ((IList<ITimeline>)blendGroup).CopyTo(array, 0);
              Assert.AreEqual(animation0, array[0]);
              Assert.AreEqual(animation1, array[1]);

              array = new ITimeline[3];
              ((IList<ITimeline>)blendGroup).CopyTo(array, 1);
              Assert.AreEqual(null, array[0]);
              Assert.AreEqual(animation0, array[1]);
              Assert.AreEqual(animation1, array[2]);
        }
Exemple #52
0
        public void ShouldDoNothingIfInvalid()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation();
              var controller = manager.CreateController(animation, property);

              controller.Recycle();
              Assert.IsFalse(controller.IsValid);

              // The following has no effect.
              controller.AutoRecycleEnabled = false;
              controller.Time = TimeSpan.Zero;
              controller.AutoRecycle();
              controller.Recycle();
              controller.Pause();
              controller.Resume();
              controller.Stop();
              controller.Stop(TimeSpan.Zero);
              controller.Stop(TimeSpan.FromSeconds(1.0));

              // Only Start and UpdateAndApply should throw an exceptions.
              Assert.That(() => controller.Start(), Throws.TypeOf<AnimationException>());
              Assert.That(() => controller.UpdateAndApply(), Throws.TypeOf<AnimationException>());
        }
Exemple #53
0
        public void Speed()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation
              {
            Duration = TimeSpan.FromSeconds(1),
            From = 100.0f,
            To = 200.0f,
              };

              var controller = manager.StartAnimation(animation, property);
              controller.AutoRecycle();
              controller.UpdateAndApply();
              Assert.AreEqual(1.0f, controller.Speed);

              // Normal speed.
              controller.Speed = 1.0f;
              Assert.AreEqual(100.0f, property.Value);

              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(125.0f, property.Value);

              // Double speed.
              controller.Speed = 2.0f;
              manager.Update(TimeSpan.FromSeconds(0.25));
              manager.ApplyAnimations();
              Assert.AreEqual(175.0f, property.Value);

              // Half speed.
              controller.Speed = 0.5f;
              manager.Update(TimeSpan.FromSeconds(0.2));
              manager.ApplyAnimations();
              Assert.AreEqual(185.0f, property.Value);

              // Negative speed.
              controller.Speed = -0.5f;
              manager.Update(TimeSpan.FromSeconds(0.2));
              manager.ApplyAnimations();
              Assert.AreEqual(175.0f, property.Value);

              controller.Stop();
              Assert.IsNaN(controller.Speed);
        }
Exemple #54
0
        public void StartAnimation()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation();
              var controller = manager.StartAnimation(animation, property);

              Assert.AreEqual(manager, controller.AnimationService);
              Assert.AreEqual(animation, controller.AnimationInstance.Animation);
              Assert.IsFalse(controller.AutoRecycleEnabled);
              Assert.IsTrue(controller.IsValid);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);
        }
Exemple #55
0
        public void EnumeratorTest()
        {
            var blendGroup = new BlendGroup();
              Assert.AreEqual(0, blendGroup.Count());

              var animation0 = new SingleFromToByAnimation();
              var animation1 = new SingleFromToByAnimation();
              blendGroup = new BlendGroup { animation0, animation1 };
              Assert.AreEqual(2, blendGroup.Count());
              Assert.AreEqual(animation0, blendGroup.ElementAt(0));
              Assert.AreEqual(animation1, blendGroup.ElementAt(1));
        }
Exemple #56
0
        public void BlendGroupWithTwoAnimationsSynchronized()
        {
            var property1 = new AnimatableProperty<float> { Value = 123.45f };

              var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop };
              var animation1 = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) };
              var animation2 = new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0) };
              blendGroup.Add(animation1);
              blendGroup.Add(animation2);
              Assert.AreEqual(1.0f, blendGroup.GetWeight(0));
              Assert.AreEqual(1.0f, blendGroup.GetWeight(1));
              Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration());

              blendGroup.SynchronizeDurations();
              Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration());

              var manager = new AnimationManager();
              var controller = manager.StartAnimation(blendGroup, property1);
              controller.UpdateAndApply();
              Assert.AreEqual(50.0f, property1.Value);

              manager.Update(TimeSpan.FromSeconds(0.75));      // t = 0.75
              manager.ApplyAnimations();
              Assert.AreEqual(TimeSpan.FromSeconds(1.5), blendGroup.GetTotalDuration());
              Assert.AreEqual(0.5f * 50.0f + 0.5f * 200.0f, property1.Value);

              blendGroup.SetWeight(0, 0);
              Assert.AreEqual(TimeSpan.FromSeconds(2.0), blendGroup.GetTotalDuration());
              manager.Update(TimeSpan.FromSeconds(0.25));       // t = 1.0
              manager.ApplyAnimations();
              Assert.AreEqual(200.0f, property1.Value);

              blendGroup.SetWeight(0, 10);
              blendGroup.SetWeight(1, 0);
              Assert.AreEqual(TimeSpan.FromSeconds(1.0), blendGroup.GetTotalDuration());
              manager.Update(TimeSpan.Zero);       // t = 1.0
              manager.ApplyAnimations();
              Assert.AreEqual(100.0f, property1.Value);

              blendGroup.SetWeight(0, 10);
              blendGroup.SetWeight(1, 1);
              Assert.AreEqual(new TimeSpan((long)((1.0f * 10.0f / 11.0f + 2.0f * 1.0f / 11.0f) * TimeSpan.TicksPerSecond)), blendGroup.GetTotalDuration());
              manager.Update(TimeSpan.FromSeconds(0.5));       // t = 1.5
              manager.ApplyAnimations();
              Assert.AreEqual(123.45f, property1.Value);
              Assert.AreEqual(AnimationState.Stopped, controller.State);
        }
Exemple #57
0
        public void ControlAnimation()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation
              {
            From = 100.0f,
            To = 200.0f,
              };
              var controller = manager.CreateController(animation, property);

              Assert.AreEqual(0.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Stopped, controller.State);
              Assert.IsFalse(controller.Time.HasValue);

              controller.Pause();
              Assert.AreEqual(0.0f, property.Value);
              Assert.IsTrue(controller.IsPaused);
              Assert.AreEqual(AnimationState.Stopped, controller.State);
              Assert.IsFalse(controller.Time.HasValue);

              controller.Start();
              controller.UpdateAndApply();
              Assert.AreEqual(100.0f, property.Value);
              Assert.IsTrue(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();
              Assert.AreEqual(100.0f, property.Value);
              Assert.IsTrue(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);

              controller.Resume();
              Assert.AreEqual(100.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();
              Assert.AreEqual(150.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();
              Assert.AreEqual(200.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(1.0), controller.Time);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();
              Assert.AreEqual(200.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Filling, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(1.5), controller.Time);

              Assert.That(() => controller.Start(), Throws.TypeOf<AnimationException>());

              controller.Stop();
              controller.UpdateAndApply();
              Assert.AreEqual(0.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Stopped, controller.State);
              Assert.IsFalse(controller.Time.HasValue);

              // Restart
              controller.Start();
              controller.UpdateAndApply();
              Assert.AreEqual(100.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);

              manager.Update(TimeSpan.FromSeconds(0.5));
              manager.ApplyAnimations();
              Assert.AreEqual(150.0f, property.Value);
              Assert.IsFalse(controller.IsPaused);
              Assert.AreEqual(AnimationState.Playing, controller.State);
              Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time);
        }
Exemple #58
0
        public void SetAnimationTime()
        {
            var manager = new AnimationManager();
              var property = new AnimatableProperty<float>();
              var animation = new SingleFromToByAnimation();
              var controller = manager.StartAnimation(animation, property);

              Assert.AreEqual(TimeSpan.FromSeconds(0.0), controller.Time);
              controller.Time = TimeSpan.FromSeconds(0.5);
              Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.Time);
              Assert.AreEqual(TimeSpan.FromSeconds(0.5), controller.AnimationInstance.Time);
        }
Exemple #59
0
        public void ShouldDoNothingWhenWeightsAreZero()
        {
            var blendGroup = new BlendGroup { FillBehavior = FillBehavior.Stop };
              var animation1 = new SingleFromToByAnimation { From = 0, To = 100, Duration = TimeSpan.FromSeconds(1.0) };
              var animation2 = new SingleFromToByAnimation { From = 100, To = 300, Duration = TimeSpan.FromSeconds(2.0) };
              blendGroup.Add(animation1);
              blendGroup.Add(animation2);
              blendGroup.SetWeight(0, 0);
              blendGroup.SetWeight(1, 0);

              Assert.That(() => blendGroup.SynchronizeDurations(), Throws.Nothing);
              blendGroup.Update();
              Assert.AreEqual(0.0f, blendGroup.GetNormalizedWeight(0));
              Assert.AreEqual(0.0f, blendGroup.GetNormalizedWeight(1));
        }
Exemple #60
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      // ----- Create prototype of a lava ball:

      // Use a sphere for physics simulation.
      _bodyPrototype = new RigidBody(new SphereShape(0.5f));

      // Load the graphics model.
      var content = _services.GetInstance<ContentManager>();
      _modelPrototype = content.Load<ModelNode>("LavaBall/LavaBall").Clone();

      // Attach a point light to the model. The light projects the glowing lava 
      // veins (cube map texture) onto the environment.
      _pointLight = new PointLight
      {
        Color = new Vector3F(1, 1, 1),
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
        Range = 1.5f,
        Attenuation = 0.5f,
        Texture = content.Load<TextureCube>("LavaBall/LavaCubeMap"),
      };
      var pointLightNode = new LightNode(_pointLight);
      _modelPrototype.Children.Add(pointLightNode);

      // Get the emissive color binding of the material because the emissive color
      // will be animated.
      // The model contains one mesh node with a single material.
      var meshNode = (MeshNode)_modelPrototype.Children[0];
      var mesh = meshNode.Mesh;
      var material = mesh.Materials[0];

      // The material contains several effect bindings. The "EmissiveColor" is applied
      // in the "Material" pass. 
      // (For reference see material definition file: Samples\Media\LavaBall\Lava.drmat)
      _emissiveColorBinding = (ConstParameterBinding<Vector3>)material["Material"].ParameterBindings["EmissiveColor"];

      // Use the animation service to animate glow intensity of the lava.
      var animationService = _services.GetInstance<IAnimationService>();

      // Create an AnimatableProperty<float>, which stores the animation value.
      _glowIntensity = new AnimatableProperty<float>();

      // Create sine animation and play the animation back-and-forth.
      var animation = new SingleFromToByAnimation
      {
        From = 0.3f,
        To = 3.0f,
        Duration = TimeSpan.FromSeconds(1),
        EasingFunction = new SineEase { Mode = EasingMode.EaseInOut },
      };
      var clip = new AnimationClip<float>
      {
        Animation = animation,
        Duration = TimeSpan.MaxValue,
        LoopBehavior = LoopBehavior.Oscillate
      };
      animationService.StartAnimation(clip, _glowIntensity).AutoRecycle();
    }