mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Implemented basic keyframes
This commit is contained in:
1 parent
e8570a6dd9
commit
0958c3af9f
41 files changed
+951
-123
No files matched your search
@@ -9,10 +9,13 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
{
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(float)};
|
||||
|
||||
public override object GetCurrentValue()
|
||||
protected override object GetInterpolatedValue()
|
||||
{
|
||||
// Nothing fancy for now, just return the base value
|
||||
return ((LayerProperty<float>) LayerProperty).Value;
|
||||
var currentKeyframe = (Keyframe<float>) CurrentKeyframe;
|
||||
var nextKeyframe = (Keyframe<float>) NextKeyframe;
|
||||
|
||||
var diff = nextKeyframe.Value - currentKeyframe.Value;
|
||||
return currentKeyframe.Value + diff * KeyframeProgress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,13 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
{
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(int)};
|
||||
|
||||
public override object GetCurrentValue()
|
||||
protected override object GetInterpolatedValue()
|
||||
{
|
||||
// Nothing fancy for now, just return the base value
|
||||
return ((LayerProperty<int>) LayerProperty).Value;
|
||||
var currentKeyframe = (Keyframe<int>) CurrentKeyframe;
|
||||
var nextKeyframe = (Keyframe<int>) NextKeyframe;
|
||||
|
||||
var diff = nextKeyframe.Value - currentKeyframe.Value;
|
||||
return currentKeyframe.Value + diff * KeyframeProgress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.Exceptions;
|
||||
using Artemis.Core.Models.Profile.LayerProperties;
|
||||
|
||||
@@ -15,12 +16,27 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
/// <summary>
|
||||
/// The layer property this keyframe engine applies to.
|
||||
/// </summary>
|
||||
public BaseLayerProperty LayerProperty { get; set; }
|
||||
public BaseLayerProperty LayerProperty { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The keyframe progress in milliseconds.
|
||||
/// The total progress
|
||||
/// </summary>
|
||||
public double Progress { get; set; }
|
||||
public TimeSpan Progress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The progress from the current keyframe to the next 0 to 1
|
||||
/// </summary>
|
||||
public float KeyframeProgress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current keyframe
|
||||
/// </summary>
|
||||
public BaseKeyframe CurrentKeyframe { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The next keyframe
|
||||
/// </summary>
|
||||
public BaseKeyframe NextKeyframe { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The types this keyframe engine supports.
|
||||
@@ -39,6 +55,7 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
throw new ArtemisCoreException($"This property engine does not support the provided type {layerProperty.Type.Name}");
|
||||
|
||||
LayerProperty = layerProperty;
|
||||
LayerProperty.KeyframeEngine = this;
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
@@ -51,15 +68,52 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
if (!Initialized)
|
||||
return;
|
||||
|
||||
Progress += deltaTime;
|
||||
Progress = Progress.Add(TimeSpan.FromMilliseconds(deltaTime));
|
||||
|
||||
// TODO Keep them sorted somewhere else, iterating all keyframes multiple times sucks
|
||||
var sortedKeyframes = LayerProperty.UntypedKeyframes.ToList().OrderBy(k => k.Position).ToList();
|
||||
|
||||
CurrentKeyframe = sortedKeyframes.LastOrDefault(k => k.Position <= Progress);
|
||||
NextKeyframe = sortedKeyframes.FirstOrDefault(k => k.Position > Progress);
|
||||
if (CurrentKeyframe == null)
|
||||
KeyframeProgress = 0;
|
||||
else if (NextKeyframe == null)
|
||||
KeyframeProgress = 1;
|
||||
else
|
||||
{
|
||||
var timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
|
||||
KeyframeProgress = (float) ((Progress - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
|
||||
}
|
||||
|
||||
// TODO Apply easing and store it separately
|
||||
|
||||
// LayerProperty determines what's next: reset, stop, continue
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the engine's progress to the provided value
|
||||
/// </summary>
|
||||
/// <param name="progress"></param>
|
||||
public void OverrideProgress(TimeSpan progress)
|
||||
{
|
||||
Progress = TimeSpan.Zero;
|
||||
Update(progress.TotalMilliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value, if the progress is in between two keyframes the value will be interpolated
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract object GetCurrentValue();
|
||||
public object GetCurrentValue()
|
||||
{
|
||||
if (CurrentKeyframe == null)
|
||||
return LayerProperty.BaseValue;
|
||||
if (NextKeyframe == null)
|
||||
return CurrentKeyframe.BaseValue;
|
||||
|
||||
return GetInterpolatedValue();
|
||||
}
|
||||
|
||||
protected abstract object GetInterpolatedValue();
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,14 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
{
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(SKPoint)};
|
||||
|
||||
public override object GetCurrentValue()
|
||||
protected override object GetInterpolatedValue()
|
||||
{
|
||||
// Nothing fancy for now, just return the base value
|
||||
return ((LayerProperty<SKPoint>) LayerProperty).Value;
|
||||
var currentKeyframe = (Keyframe<SKPoint>) CurrentKeyframe;
|
||||
var nextKeyframe = (Keyframe<SKPoint>) NextKeyframe;
|
||||
|
||||
var xDiff = nextKeyframe.Value.X - currentKeyframe.Value.X;
|
||||
var yDiff = nextKeyframe.Value.Y - currentKeyframe.Value.Y;
|
||||
return new SKPoint(currentKeyframe.Value.X + xDiff * KeyframeProgress, currentKeyframe.Value.Y + yDiff * KeyframeProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,14 @@ namespace Artemis.Core.Models.Profile.KeyframeEngines
|
||||
{
|
||||
public sealed override List<Type> CompatibleTypes { get; } = new List<Type> {typeof(SKSize)};
|
||||
|
||||
public override object GetCurrentValue()
|
||||
protected override object GetInterpolatedValue()
|
||||
{
|
||||
// Nothing fancy for now, just return the base value
|
||||
return ((LayerProperty<SKSize>) LayerProperty).Value;
|
||||
var currentKeyframe = (Keyframe<SKSize>)CurrentKeyframe;
|
||||
var nextKeyframe = (Keyframe<SKSize>)NextKeyframe;
|
||||
|
||||
var widthDiff = nextKeyframe.Value.Width - currentKeyframe.Value.Width;
|
||||
var heightDiff = nextKeyframe.Value.Height - currentKeyframe.Value.Height;
|
||||
return new SKSize(currentKeyframe.Value.Width + widthDiff * KeyframeProgress, currentKeyframe.Value.Height + heightDiff * KeyframeProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
{
|
||||
public class BaseKeyframe
|
||||
{
|
||||
protected internal BaseKeyframe(Layer layer, BaseLayerProperty property)
|
||||
protected BaseKeyframe(Layer layer, BaseLayerProperty property)
|
||||
{
|
||||
Layer = layer;
|
||||
BaseProperty = property;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
{
|
||||
private object _baseValue;
|
||||
|
||||
protected internal BaseLayerProperty(Layer layer, BaseLayerProperty parent, string id, string name, string description, Type type)
|
||||
protected BaseLayerProperty(Layer layer, BaseLayerProperty parent, string id, string name, string description, Type type)
|
||||
{
|
||||
Layer = layer;
|
||||
Parent = parent;
|
||||
@@ -125,7 +125,37 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
|
||||
BaseKeyframes.Clear();
|
||||
foreach (var keyframeEntity in propertyEntity.KeyframeEntities)
|
||||
BaseKeyframes.Add(new BaseKeyframe(Layer, this) {BaseValue = DeserializePropertyValue(keyframeEntity.Value)});
|
||||
{
|
||||
// Create a strongly typed keyframe or else it cannot be cast later on
|
||||
var keyframeType = typeof(Keyframe<>);
|
||||
var keyframe = (BaseKeyframe) Activator.CreateInstance(keyframeType.MakeGenericType(Type), Layer, this);
|
||||
keyframe.BaseValue = DeserializePropertyValue(keyframeEntity.Value);
|
||||
BaseKeyframes.Add(keyframe);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new keyframe for this base property without knowing the type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public BaseKeyframe CreateNewKeyframe(TimeSpan position)
|
||||
{
|
||||
// Create a strongly typed keyframe or else it cannot be cast later on
|
||||
var keyframeType = typeof(Keyframe<>);
|
||||
var keyframe = (BaseKeyframe) Activator.CreateInstance(keyframeType.MakeGenericType(Type), Layer, this);
|
||||
keyframe.Position = position;
|
||||
keyframe.BaseValue = BaseValue;
|
||||
BaseKeyframes.Add(keyframe);
|
||||
|
||||
return keyframe;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all keyframes from the property.
|
||||
/// </summary>
|
||||
public void ClearKeyframes()
|
||||
{
|
||||
BaseKeyframes.Clear();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
||||
@@ -18,6 +18,11 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
set => BaseValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value of the property with keyframes applied
|
||||
/// </summary>
|
||||
public T CurrentValue => (T) KeyframeEngine.GetCurrentValue();
|
||||
|
||||
/// <summary>
|
||||
/// A list of keyframes defining different values of the property in time, this list contains the strongly typed
|
||||
/// <see cref="Keyframe{T}" />
|
||||
@@ -43,20 +48,12 @@ namespace Artemis.Core.Models.Profile.LayerProperties
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all keyframes from the property.
|
||||
/// </summary>
|
||||
public void ClearKeyframes()
|
||||
{
|
||||
BaseKeyframes.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value using the keyframes
|
||||
/// Gets the current value using the keyframes
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T GetCurrentValue()
|
||||
{
|
||||
if (KeyframeEngine == null)
|
||||
if (KeyframeEngine == null || !Keyframes.Any())
|
||||
return Value;
|
||||
|
||||
return (T) KeyframeEngine.GetCurrentValue();
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
||||
Layer.SizeProperty.Value = new SKSize((float) (100f / width * rect.Width) / 100f, (float) (100f / height * rect.Height) / 100f);
|
||||
|
||||
// TODO: Update keyframes
|
||||
CalculateRenderProperties(Layer.PositionProperty.Value, Layer.SizeProperty.Value);
|
||||
CalculateRenderProperties(Layer.PositionProperty.CurrentValue, Layer.SizeProperty.CurrentValue);
|
||||
}
|
||||
|
||||
public SKRect GetUnscaledRectangle()
|
||||
@@ -74,10 +74,10 @@ namespace Artemis.Core.Models.Profile.LayerShapes
|
||||
var height = Layer.Leds.Max(l => l.RgbLed.AbsoluteLedRectangle.Location.Y + l.RgbLed.AbsoluteLedRectangle.Size.Height) - y;
|
||||
|
||||
return SKRect.Create(
|
||||
(float) (x + width * Layer.PositionProperty.Value.X),
|
||||
(float) (y + height * Layer.PositionProperty.Value.Y),
|
||||
(float) (width * Layer.SizeProperty.Value.Width),
|
||||
(float) (height * Layer.SizeProperty.Value.Height)
|
||||
(float) (x + width * Layer.PositionProperty.CurrentValue.X),
|
||||
(float) (y + height * Layer.PositionProperty.CurrentValue.Y),
|
||||
(float) (width * Layer.SizeProperty.CurrentValue.Width),
|
||||
(float) (height * Layer.SizeProperty.CurrentValue.Height)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user