Причина, по которой мне нужно анимировать кисть, состоит в том, чтобы анимировать кисть в материале, который я использую в трехмерном объекте. Я думал, что анимировать кисть будет легче, чем материал.
Я уже использовал описанный выше метод для объединения кистей, но здесь это не сработало.
Подумав немного, я решил оживить Материал, а не кисть.
Это оказалось проще, чем анимация кисти.
[Примечание]
Этот класс анимации адаптирован для моих нужд. Это только оживляет кисть в материале. Я использую этот класс для замены кисти материала на другой.
[Примечание]
«Материал» в конце полностью заменит «материал», он не будет заканчиваться MaterialGroup.
Вот класс MaterialAnimation для тех, кому это нужно. У меня также есть класс Point3DCollectionAnimation. Он может быть использован для анимации трехмерных сеток. Это очень полезно.
Вы можете найти его ниже этого.
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;
}
}
}
Вот класс анимации Point3DCollection.
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;
}
}
}
Я надеюсь, что эти классы полезны для тех, кто в них нуждается. Я искал их по интернету, но не нашел. Я уверен, что есть больше людей, которые нуждаются в этих классах.
Пожалуйста, оставляйте комментарии.