Implermented Interpolation for CVector

This commit is contained in:
Michel Fedde 2021-03-28 17:33:52 +02:00
parent b45a10b676
commit a4cab567b3
10 changed files with 463 additions and 79 deletions

View file

@ -0,0 +1,20 @@
using OpenTK;
namespace SM.Base.Animation
{
/// <summary>
/// Preset Animation curves.
/// </summary>
public class AnimationCurves
{
/// <summary>
/// Linear Curve
/// </summary>
public static readonly BezierCurve Linear = new BezierCurve(Vector2.Zero, Vector2.One);
/// <summary>
/// Smooth curve
/// </summary>
public static readonly BezierCurve Smooth = new BezierCurve(Vector2.Zero, new Vector2(.5f, 0), new Vector2(.5f, 1), Vector2.One);
}
}

View file

@ -0,0 +1,90 @@
using System;
using OpenTK;
using SM.Base.Time;
using SM.Base.Types;
using SM.Base.Window;
namespace SM.Base.Animation
{
/// <summary>
/// A handle to control the interpolation process.
/// </summary>
public class InterpolationProcess : Timer
{
/// <summary>
/// The CVector object, that is interpolated.
/// </summary>
public CVectorBase TargetVector { get; set; }
/// <summary>
/// From where the interpolation process started.
/// </summary>
public Vector4 From { get; }
/// <summary>
/// To where the interpolation is heading.
/// </summary>
public Vector4 To { get; }
/// <summary>
/// The direction towards the <see cref="To"/>
/// </summary>
public Vector4 Direction { get; }
/// <summary>
/// Gets/Sets the interpolation curve.
/// </summary>
public BezierCurve InterpolationCurve { get; set; }
internal InterpolationProcess(CVectorBase targetVector, TimeSpan timeSpan, Vector4 from, Vector4 to, BezierCurve interpolationCurve) : base(timeSpan)
{
TargetVector = targetVector;
From = from;
To = to;
InterpolationCurve = interpolationCurve;
Direction = to - from;
}
/// <summary>
/// Stops the interpolation process.
/// <para>This keeps the state where the interpolation was.</para>
/// </summary>
public new void Stop()
{
Stop(true);
}
/// <summary>
/// Stops the interplation process.
/// </summary>
/// <param name="keepState">If true, it will not set the state to the <see cref="To"/> state.</param>
public void Stop(bool keepState)
{
if (Active && !keepState) SetTarget(To);
base.Stop();
}
private protected override void Ticking(UpdateContext context)
{
base.Ticking(context);
float posInCurve = InterpolationCurve.CalculatePoint(ElapsedNormalized).Y;
Vector4 nextPos = From + (Direction * posInCurve);
SetTarget(nextPos);
}
/// <inheritdoc />
protected override void Stopping(UpdateContext context)
{
base.Stopping(context);
SetTarget(To);
}
private void SetTarget(Vector4 vec)
{
TargetVector.Set(vec.X, vec.Y, vec.Z, vec.W);
}
}
}

View file

@ -48,6 +48,8 @@
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Animation\AnimationCurves.cs" />
<Compile Include="Animation\InterpolationProcess.cs" />
<Compile Include="Controls\Keyboard.cs" />
<Compile Include="Controls\Mouse.cs" />
<Compile Include="Drawing\DrawingBasis.cs" />
@ -63,6 +65,8 @@
<Compile Include="Drawing\Particles\ParticleStruct.cs" />
<Compile Include="Drawing\Particles\ParticleDrawingBasis.cs" />
<Compile Include="Shaders\SimpleShader.cs" />
<Compile Include="Types\CVector4.cs" />
<Compile Include="Types\CVectorBase.cs" />
<Compile Include="Utility\IInitializable.cs" />
<Compile Include="Utility\Ray.cs" />
<Compile Include="Utility\Util.cs" />
@ -139,5 +143,6 @@
<EmbeddedResource Include="Shaders\Extensions\fragment\textureGamma.glsl" />
<EmbeddedResource Include="Shaders\Extensions\fragment\noise.glsl" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -1,6 +1,9 @@
#region usings
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using OpenTK;
using SM.Base.Animation;
#endregion
@ -9,7 +12,7 @@ namespace SM.Base.Types
/// <summary>
/// A One-dimensional Vector (also known as <see cref="float" />), in a class.
/// </summary>
public class CVector1
public class CVector1 : CVectorBase
{
/// <summary>
/// Creates a class vector
@ -26,45 +29,18 @@ namespace SM.Base.Types
public float X { get; set; }
/// <summary>
/// The length/magnitute of the vector.
/// Interpolates the motion to the target.
/// </summary>
public float Length => GetLength();
/// <summary>
/// Gets the square of the vector length (magnitude).
/// </summary>
/// <remarks>
/// This property avoids the costly square root operation required by the Length property. This makes it more suitable
/// for comparisons.
/// </remarks>
public float LengthSquared => GetLength(true);
/// <summary>
/// This event triggers when a component changed.
/// </summary>
public event Action Changed;
/// <summary>
/// Get the length of the vector.
/// </summary>
/// <param name="squared">If true, it will return the squared product.</param>
/// <returns></returns>
public float GetLength(bool squared = false)
/// <param name="duration">How long the interpolation should take.</param>
/// <param name="to">The value it should interpolate.</param>
/// <param name="interpolationCurve">The curve how he interpolates. Preset values can be found under <see cref="AnimationCurves"/>. Default: <see cref="AnimationCurves.Linear"/></param>
/// <returns>A handle to control the interpolation process.</returns>
public InterpolationProcess Interpolate(TimeSpan duration, float to, BezierCurve? interpolationCurve = null)
{
float length = GetLengthProcess();
if (squared) return length;
return (float) Math.Sqrt(length);
}
InterpolationProcess process = new InterpolationProcess(this, duration, ConvertToVector4(), new Vector4(to, 0, 0, 0), interpolationCurve.GetValueOrDefault(AnimationCurves.Linear));
process.Start();
/// <summary>
/// Normalizes the vector.
/// </summary>
public void Normalize()
{
float length = GetLength();
NormalizationProcess(length);
return process;
}
/// <summary>
@ -76,6 +52,12 @@ namespace SM.Base.Types
if (triggerChanged) TriggerChanged();
}
/// <inheritdoc />
public override void Set(params float[] parameters)
{
X = parameters[0];
}
/// <summary>
/// Adds the value to the components.
/// </summary>
@ -85,20 +67,11 @@ namespace SM.Base.Types
if (triggerChanged) TriggerChanged();
}
/// <summary>
/// Conversion into <see cref="float" />
/// </summary>
public static implicit operator float(CVector1 vector1)
{
return vector1.X;
}
/// <summary>
/// Conversion from <see cref="float" /> to One-dimensional Vector.
/// </summary>
/// <returns></returns>
//public static implicit operator CVector1(float f) => new CVector1(f);
protected virtual float GetLengthProcess()
protected override float GetLengthProcess()
{
return X * X;
}
@ -107,17 +80,16 @@ namespace SM.Base.Types
/// Normalizes the vector.
/// </summary>
/// <param name="length"></param>
protected virtual void NormalizationProcess(float length)
protected override void NormalizationProcess(float length)
{
X *= length;
}
/// <summary>
/// This triggers the <see cref="Changed"/> event.
/// </summary>
protected void TriggerChanged()
/// <inheritdoc />
protected override Vector4 ConvertToVector4()
{
Changed?.Invoke();
return new Vector4(X, 0, 0, 0);
}
/// <inheritdoc />
@ -125,5 +97,13 @@ namespace SM.Base.Types
{
return X.ToString();
}
/// <summary>
/// Conversion into <see cref="float" />
/// </summary>
public static implicit operator float(CVector1 vector1)
{
return vector1.X;
}
}
}

View file

@ -1,6 +1,8 @@
#region usings
using System;
using OpenTK;
using SM.Base.Animation;
#endregion
@ -33,17 +35,23 @@ namespace SM.Base.Types
/// </summary>
public float Y { get; set; }
/// <inheritdoc />
protected override float GetLengthProcess()
/// <summary>
/// Interpolates the motion to the target.
/// </summary>
/// <param name="duration">How long the interpolation should take.</param>
/// <param name="to">The value it should interpolate.</param>
/// <param name="interpolationCurve">The curve how he interpolates.
/// <para>When creating a curve, its recommended the Y-component is always between 0 -> 1. But it could make cool effects if not...</para>
/// <para>Preset curves can be found under <see cref="AnimationCurves"/>.</para>
/// <para>Default: <see cref="AnimationCurves.Linear"/></para>
/// </param>
/// <returns>A handle to control the interpolation process.</returns>
public InterpolationProcess Interpolate(TimeSpan duration, Vector2 to, BezierCurve? interpolationCurve = null)
{
return base.GetLengthProcess() + Y * Y;
}
InterpolationProcess process = new InterpolationProcess(this, duration, ConvertToVector4(), new Vector4(to), interpolationCurve.GetValueOrDefault(AnimationCurves.Linear));
process.Start();
/// <inheritdoc />
protected override void NormalizationProcess(float length)
{
base.NormalizationProcess(length);
Y *= length;
return process;
}
/// <inheritdoc />
@ -78,6 +86,13 @@ namespace SM.Base.Types
base.Set(x, triggerChanged);
}
/// <inheritdoc />
public override void Set(params float[] parameters)
{
base.Set(parameters);
Y = parameters[1];
}
/// <inheritdoc />
public override void Add(float uniform, bool triggerChanged = true)
{
@ -107,6 +122,25 @@ namespace SM.Base.Types
base.Add(x, triggerChanged);
}
/// <inheritdoc />
protected override float GetLengthProcess()
{
return base.GetLengthProcess() + Y * Y;
}
/// <inheritdoc />
protected override void NormalizationProcess(float length)
{
base.NormalizationProcess(length);
Y *= length;
}
/// <inheritdoc />
protected override Vector4 ConvertToVector4()
{
return new Vector4(X,Y, 0, 0);
}
/// <summary>
/// Converts to <see cref="Vector2" />
/// </summary>

View file

@ -1,6 +1,8 @@
#region usings
using System;
using OpenTK;
using SM.Base.Animation;
#endregion
@ -33,23 +35,26 @@ namespace SM.Base.Types
/// </summary>
public float Z { get; set; }
/// <inheritdoc />
protected override float GetLengthProcess()
/// <summary>
/// Interpolates the motion to the target.
/// </summary>
/// <param name="duration">How long the interpolation should take.</param>
/// <param name="to">The value it should interpolate.</param>
/// <param name="interpolationCurve">The curve how he interpolates. Preset values can be found under <see cref="AnimationCurves"/>. Default: <see cref="AnimationCurves.Linear"/></param>
/// <returns>A handle to control the interpolation process.</returns>
public InterpolationProcess Interpolate(TimeSpan duration, Vector3 to, BezierCurve? interpolationCurve = null)
{
return base.GetLengthProcess() + Z * Z;
InterpolationProcess process = new InterpolationProcess(this, duration, ConvertToVector4(), new Vector4(to, 0), interpolationCurve.GetValueOrDefault(AnimationCurves.Linear));
process.Start();
return process;
}
/// <inheritdoc />
protected override void NormalizationProcess(float length)
{
base.NormalizationProcess(length);
Z *= length;
}
/// <inheritdoc />
public override string ToString()
{
return "{" + X + "; " + Y + "}";
return "{" + X + "; " + Y + "; "+Z+"}";
}
/// <inheritdoc />
@ -76,6 +81,13 @@ namespace SM.Base.Types
Set(vector.X, vector.Y, vector.Z, triggerChanged);
}
/// <inheritdoc />
public override void Set(params float[] parameters)
{
base.Set(parameters);
Z = parameters[2];
}
/// <inheritdoc />
public override void Add(float uniform, bool triggerChanged = true)
{
@ -106,6 +118,24 @@ namespace SM.Base.Types
base.Add(x, y, triggerChanged);
}
/// <inheritdoc />
protected override float GetLengthProcess()
{
return base.GetLengthProcess() + Z * Z;
}
/// <inheritdoc />
protected override void NormalizationProcess(float length)
{
base.NormalizationProcess(length);
Z *= length;
}
/// <inheritdoc />
protected override Vector4 ConvertToVector4()
{
return new Vector4(X, Y, Z, 0);
}
/// <summary>
/// Converts to <see cref="Vector3" />
/// </summary>

View file

@ -0,0 +1,139 @@
using System;
using System.Windows.Forms;
using OpenTK;
using SM.Base.Animation;
namespace SM.Base.Types
{
/// <inheritdoc />
public class CVector4 : CVector3
{
/// <summary>
/// The W-component.
/// </summary>
public float W { get; set; }
/// <inheritdoc />
public CVector4(float uniform) : base(uniform)
{
W = uniform;
}
/// <inheritdoc />
public CVector4(float x, float y, float z, float w) : base(x, y, z)
{
W = w;
}
/// <summary>
/// Interpolates the motion to the target.
/// </summary>
/// <param name="duration">How long the interpolation should take.</param>
/// <param name="to">The value it should interpolate.</param>
/// <param name="interpolationCurve">The curve how he interpolates. Preset values can be found under <see cref="AnimationCurves"/>. Default: <see cref="AnimationCurves.Linear"/></param>
/// <returns>A handle to control the interpolation process.</returns>
public InterpolationProcess Interpolate(TimeSpan duration, Vector4 to, BezierCurve? interpolationCurve = null)
{
InterpolationProcess process = new InterpolationProcess(this, duration, ConvertToVector4(), to, interpolationCurve.GetValueOrDefault(AnimationCurves.Linear));
process.Start();
return process;
}
/// <inheritdoc />
public override void Set(float uniform, bool triggerChanged = true)
{
W = uniform;
base.Set(uniform, triggerChanged);
}
/// <summary>
/// Sets the a own value to each component.
/// </summary>
public void Set(float x, float y, float z, float w, bool triggerChanged = true)
{
W = w;
base.Set(x, y, z, triggerChanged);
}
/// <summary>
/// Sets each component to the <see cref="Vector4" /> counter-part.
/// </summary>
public void Set(Vector4 vector, bool triggerChanged = true)
{
Set(vector.X, vector.Y, vector.Z, vector.W, triggerChanged);
}
/// <inheritdoc />
public override void Set(params float[] parameters)
{
base.Set(parameters);
W = parameters[3];
}
/// <inheritdoc />
public override void Add(float uniform, bool triggerChanged = true)
{
W += uniform;
base.Add(uniform, triggerChanged);
}
/// <summary>
/// Adds a <see cref="Vector4"/> to the CVector.
/// </summary>
/// <param name="vector"></param>
/// <param name="triggerChanged">If false, the event Changed doesn't gets triggered </param>
public void Add(Vector4 vector, bool triggerChanged = true)
{
Add(vector.X, vector.Y, vector.Z, vector.W, triggerChanged);
}
/// <summary>
/// Adds the values to the CVector.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <param name="w"></param>
/// <param name="triggerChanged">If false, the event Changed doesn't gets triggered </param>
public void Add(float x, float y, float z, float w, bool triggerChanged = true)
{
W = w;
base.Add(x, y, z, triggerChanged);
}
/// <inheritdoc />
public override string ToString()
{
return "{" + X + "; " + Y + "; " + Z + "; " + W + "}";
}
/// <inheritdoc />
protected override float GetLengthProcess()
{
return base.GetLengthProcess() + W * W;
}
/// <inheritdoc />
protected override void NormalizationProcess(float length)
{
base.NormalizationProcess(length);
W *= length;
}
/// <inheritdoc />
protected override Vector4 ConvertToVector4()
{
return new Vector4(X, Y, Z, W);
}
/// <summary>
/// Converts a <see cref="CVector4"/> into a <see cref="Vector4"/>.
/// </summary>
public static implicit operator Vector4(CVector4 vector) => new Vector4(vector.X, vector.Y, vector.Z, vector.W);
/// <summary>
/// Converts a <see cref="Vector4"/> into a <see cref="CVector4"/>.
/// </summary>
public static implicit operator CVector4(Vector4 vector) => new CVector4(vector.X, vector.Y, vector.Z, vector.W);
}
}

View file

@ -0,0 +1,83 @@
using System;
using OpenTK;
namespace SM.Base.Types
{
/// <summary>
/// Basis for the CVector classes
/// </summary>
public abstract class CVectorBase
{
/// <summary>
/// This event triggers when a component changed.
/// </summary>
public event Action Changed;
/// <summary>
/// The length/magnitute of the vector.
/// </summary>
public float Length => GetLength();
/// <summary>
/// Gets the square of the vector length (magnitude).
/// </summary>
/// <remarks>
/// This property avoids the costly square root operation required by the Length property. This makes it more suitable
/// for comparisons.
/// </remarks>
public float LengthSquared => GetLength(true);
/// <summary>
/// Get the length of the vector.
/// </summary>
/// <param name="squared">If true, it will return the squared product.</param>
/// <returns></returns>
public float GetLength(bool squared = false)
{
float length = GetLengthProcess();
if (squared) return length;
return (float)Math.Sqrt(length);
}
/// <summary>
/// Normalizes the vector.
/// </summary>
public void Normalize()
{
float length = GetLength();
NormalizationProcess(length);
}
/// <summary>
/// Sets the values of the vector, by providing the values over an array.
/// </summary>
/// <param name="parameters"></param>
public abstract void Set(params float[] parameters);
/// <summary>
/// This triggers the <see cref="Changed"/> event.
/// </summary>
protected void TriggerChanged()
{
Changed?.Invoke();
}
/// <summary>
/// Conversion from <see cref="float" /> to One-dimensional Vector.
/// </summary>
/// <returns></returns>
protected abstract float GetLengthProcess();
/// <summary>
/// Normalizes the vector.
/// </summary>
/// <param name="length"></param>
protected abstract void NormalizationProcess(float length);
/// <summary>
/// Converts the vector to a <see cref="Vector4"/>
/// </summary>
/// <returns></returns>
protected abstract Vector4 ConvertToVector4();
}
}

View file

@ -19,6 +19,7 @@ namespace SM2D.Scene
Transform.Size = new CVector2(1);
}
/// <inheritdoc />
public override void Draw(DrawContext context)
{
this.Sort(Comparitor);