// Copyright (C) 2023 Nicholas Maltbie
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
// associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using UnityEngine;
namespace nickmaltbie.OpenKCC.Utils
{
///
/// Smoothed window of some value.
/// Also, unity cannot detect code coverage stats for generic classes. Going
/// to ignore metrics for this class.
///
[ExcludeFromCodeCoverage]
public class SmoothedWindow
{
///
/// Gets the sample values.
///
protected E[] Samples { get; private set; }
///
/// Gets the current selected index.
///
protected int CurrentIdx { get; private set; }
///
/// Get values for debugging.
///
internal IEnumerable Values =>
Enumerable.Range(0, Count).Select(index => Samples[(CurrentIdx + index) % Count]);
///
/// Count of
///
///
public int Count { get; protected set; }
///
/// Create a smoothed window.
///
/// Size of smoothing window.
public SmoothedWindow(int size)
{
Samples = new E[size];
}
///
/// Adds a sample to the smoothing window at the next
/// available space. Will overwrite data if any data
/// is there.
///
/// Value to add.
/// Previous value removed.
public virtual E AddSample(E value)
{
E previous = Samples[CurrentIdx];
Samples[CurrentIdx] = value;
Count = Mathf.Max(Count, ++CurrentIdx);
CurrentIdx %= Samples.Length;
return previous;
}
}
///
/// Smoothed window for a Vector3 value.
///
public class SmoothedVector : SmoothedWindow
{
///
/// Running sum of the values stored in samples.
///
protected Vector3 sum = Vector3.zero;
///
/// Create a smoothed vector with a given number of samples..
///
/// Size of smoothing window.
public SmoothedVector(int size) : base(size) { }
///
/// Returns the average of all samples in the window.
///
public Vector3 Average()
{
if (Count == 0)
{
return Vector3.zero;
}
return sum / Count;
}
///
public override Vector3 AddSample(Vector3 value)
{
Vector3 previous = base.AddSample(value);
sum += value;
sum -= previous;
return previous;
}
}
}