You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.0 KiB
C#
135 lines
4.0 KiB
C#
using System;
|
|
|
|
namespace Fusion.Addons.SimpleKCC
|
|
{
|
|
internal abstract class SmoothValue<T>
|
|
{
|
|
private SmoothItem<T>[] _items;
|
|
|
|
private int _index;
|
|
|
|
public SmoothItem<T>[] Items => _items;
|
|
|
|
public SmoothValue(int capacity)
|
|
{
|
|
_items = new SmoothItem<T>[capacity];
|
|
for (int i = 0; i < capacity; i++)
|
|
{
|
|
_items[i] = new SmoothItem<T>();
|
|
}
|
|
}
|
|
|
|
public void AddValue(int frame, double size, T value)
|
|
{
|
|
if (size <= 0.0)
|
|
{
|
|
throw new ArgumentException("size");
|
|
}
|
|
|
|
SmoothItem<T> smoothItem = _items[_index];
|
|
if (smoothItem.Frame == frame)
|
|
{
|
|
smoothItem.Size = size;
|
|
smoothItem.Value = value;
|
|
return;
|
|
}
|
|
|
|
_index = (_index + 1) % _items.Length;
|
|
smoothItem = _items[_index];
|
|
smoothItem.Frame = frame;
|
|
smoothItem.Size = size;
|
|
smoothItem.Value = value;
|
|
}
|
|
|
|
public void ClearValues()
|
|
{
|
|
int i = 0;
|
|
for (int num = _items.Length; i < num; i++)
|
|
{
|
|
SmoothItem<T> obj = _items[i];
|
|
obj.Frame = 0;
|
|
obj.Size = 0.0;
|
|
obj.Value = GetDefaultValue();
|
|
}
|
|
|
|
_index = 0;
|
|
}
|
|
|
|
public T CalculateSmoothValue(double window, double size)
|
|
{
|
|
int frames;
|
|
return CalculateSmoothValue(window, size, out frames);
|
|
}
|
|
|
|
public T CalculateSmoothValue(double window, double size, out int frames)
|
|
{
|
|
frames = 0;
|
|
if (window <= 0.0)
|
|
{
|
|
SmoothItem<T> smoothItem = _items[_index];
|
|
if (smoothItem.Frame == 0)
|
|
{
|
|
return default(T);
|
|
}
|
|
|
|
frames = 1;
|
|
return smoothItem.Value;
|
|
}
|
|
|
|
double num = window;
|
|
T accumulatedValue = GetDefaultValue();
|
|
for (int num2 = _index; num2 >= 0; num2--)
|
|
{
|
|
SmoothItem<T> smoothItem = _items[num2];
|
|
if (smoothItem.Frame != 0)
|
|
{
|
|
if (num <= smoothItem.Size)
|
|
{
|
|
double scale = num / smoothItem.Size;
|
|
accumulatedValue = AccumulateValue(accumulatedValue, smoothItem.Value, scale);
|
|
frames++;
|
|
return GetSmoothValue(accumulatedValue, size / window);
|
|
}
|
|
|
|
num -= smoothItem.Size;
|
|
accumulatedValue = AccumulateValue(accumulatedValue, smoothItem.Value, 1.0);
|
|
frames++;
|
|
}
|
|
}
|
|
|
|
for (int num3 = _items.Length - 1; num3 > _index; num3--)
|
|
{
|
|
SmoothItem<T> smoothItem = _items[num3];
|
|
if (smoothItem.Frame != 0)
|
|
{
|
|
if (num < smoothItem.Size)
|
|
{
|
|
double scale2 = num / smoothItem.Size;
|
|
accumulatedValue = AccumulateValue(accumulatedValue, smoothItem.Value, scale2);
|
|
frames++;
|
|
return GetSmoothValue(accumulatedValue, size / window);
|
|
}
|
|
|
|
num -= smoothItem.Size;
|
|
accumulatedValue = AccumulateValue(accumulatedValue, smoothItem.Value, 1.0);
|
|
frames++;
|
|
}
|
|
}
|
|
|
|
if (num >= window)
|
|
{
|
|
return default(T);
|
|
}
|
|
|
|
double num4 = window - num;
|
|
return GetSmoothValue(accumulatedValue, size / num4);
|
|
}
|
|
|
|
protected abstract T GetDefaultValue();
|
|
|
|
protected abstract T AccumulateValue(T accumulatedValue, T value, double scale);
|
|
|
|
protected abstract T GetSmoothValue(T accumulatedValue, double scale);
|
|
}
|
|
}
|