The reason I need to animate a brush is to animate the brush in a material that I am using in a 3d object. I thought it would be easier to animate the brush than the material.
I have already used the method above to combinate brushes, but it didn't work here.
After thinking a little bit I decided to animate the Material and not the brush. It resulted to be easier than animating a brush.
[NOTE]
This animation class is adapted for my needs. It only animates the brush in the material. I am using this class to replace the brush of a material for an other.
[NOTE]
The 'to material' will at the end replace completely the 'from material', it will not end with a MaterialGroup.
Here is the MaterialAnimation Class for who needs it. I also have a Point3DCollectionAnimation Class. It can be used to animate 3D meshes. It's very useful. You can find it below this one.
MaterialAnimation
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Media.Animation; using System.Windows; using System.Windows.Media; using System.Windows.Controls; using System.Windows.Media.Media3D; namespace System.Windows.Media.Animation { class MaterialAnimation : AnimationTimeline { protected override Freezable CreateInstanceCore() { return new MaterialAnimation(); } public override Type TargetPropertyType { get { return typeof(Material); } } static MaterialAnimation() { FromProperty = DependencyProperty.Register("From", typeof(Material), typeof(MaterialAnimation)); ToProperty = DependencyProperty.Register("To", typeof(Material), typeof(MaterialAnimation)); } public static readonly DependencyProperty FromProperty; public Material From { get { return (Material)GetValue(MaterialAnimation.FromProperty); } set { SetValue(MaterialAnimation.FromProperty, value); } } public static readonly DependencyProperty ToProperty; public Material To { get { return (Material)GetValue(MaterialAnimation.ToProperty); } set { SetValue(MaterialAnimation.ToProperty, value); } } public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock) { Material fromVal = ((Material)GetValue(MaterialAnimation.FromProperty)).CloneCurrentValue(); Material toVal = ((Material)GetValue(MaterialAnimation.ToProperty)).CloneCurrentValue(); if ((double)animationClock.CurrentProgress == 0.0) return fromVal; //Here it workes fine. if ((double)animationClock.CurrentProgress == 1.0) return toVal; //It workes also here fine. if (toVal.GetType() == (new DiffuseMaterial()).GetType()) ((DiffuseMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress; else if (toVal.GetType() == (new SpecularMaterial()).GetType()) ((SpecularMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress; else ((EmissiveMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress; MaterialGroup MG = new MaterialGroup(); MG.Children.Add(fromVal); MG.Children.Add(toVal); return MG; } } }
Here is the Point3DCollectionAnimation Class.
Point3DCollectionAnimation
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Media.Animation; using System.Windows; using System.Windows.Media.Media3D; namespace System.Windows.Media.Animation { public class Point3DCollectionAnimation : AnimationTimeline { protected override Freezable CreateInstanceCore() { return new Point3DCollectionAnimation(); } public override Type TargetPropertyType { get { return typeof(Point3DCollection); } } static Point3DCollectionAnimation() { FromProperty = DependencyProperty.Register("From", typeof(Point3DCollection), typeof(Point3DCollectionAnimation)); ToProperty = DependencyProperty.Register("To", typeof(Point3DCollection), typeof(Point3DCollectionAnimation)); } public static readonly DependencyProperty FromProperty; public Point3DCollection From { get { return (Point3DCollection)GetValue(Point3DCollectionAnimation.FromProperty); } set { SetValue(Point3DCollectionAnimation.FromProperty, value); } } public static readonly DependencyProperty ToProperty; public Point3DCollection To { get { return (Point3DCollection)GetValue(Point3DCollectionAnimation.ToProperty); } set { SetValue(Point3DCollectionAnimation.ToProperty, value); } } public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock) { Point3DCollection fromVal = ((Point3DCollection)GetValue(Point3DCollectionAnimation.FromProperty)); Point3DCollection toVal = ((Point3DCollection)GetValue(Point3DCollectionAnimation.ToProperty)); Point3DCollection ret; int t = 0; if (fromVal.Count > toVal.Count) { ret = fromVal.Clone(); foreach (Point3D tov in toVal) { Point3D frov = fromVal[t]; Point3D newv = new Point3D(); newv.X = (double)animationClock.CurrentProgress * (tov.X - frov.X) + frov.X; newv.Y = (double)animationClock.CurrentProgress * (tov.Y - frov.Y) + frov.Y; newv.Z = (double)animationClock.CurrentProgress * (tov.Z - frov.Z) + frov.Z; ret[t] = newv; t++; } } else { ret = toVal.Clone(); foreach (Point3D frov in fromVal) { Point3D tov = toVal[t]; Point3D newv = new Point3D(); newv.X = (double)animationClock.CurrentProgress * (tov.X - frov.X) + frov.X; newv.Y = (double)animationClock.CurrentProgress * (tov.Y - frov.Y) + frov.Y; newv.Z = (double)animationClock.CurrentProgress * (tov.Z - frov.Z) + frov.Z; ret[t] = newv; t++; } } return ret; } } } I hope these classes are usefull for who needs them. I searched for them allot on the internet, but didn't find them. I'm sure that there are more people who needs these classes.
Please leave comments.