123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using Valve.VR.InteractionSystem;
- namespace SicknessReduction.Visual.Vignetting
- {
- public interface IRestrectionSuggestor
- {
- float Suggestion { get; }
- }
- public abstract class RestrictionSuggestor : IRestrectionSuggestor
- {
- protected readonly float threshold;
- protected readonly float minRestriction;
- protected readonly float maxRestriction;
- protected readonly float maxValue;
- protected RestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
- float maxValue)
- {
- this.threshold = threshold;
- this.minRestriction = minRestriction;
- this.maxRestriction = maxRestriction;
- this.maxValue = maxValue;
- }
- protected float LerpedSuggestion(float value) => Mathf.Lerp(minRestriction, maxRestriction,
- (value - threshold) / (maxValue - threshold));
- public abstract float Suggestion { get; }
- }
- public class ValueBasedRestrictionSuggestor : RestrictionSuggestor
- {
- public override float Suggestion
- {
- get
- {
- var abs = Mathf.Abs(Value);
- return abs < threshold
- ? 0f
- : LerpedSuggestion(abs);
- }
- }
- public float Value { set; get; } = 0f;
- public ValueBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
- float maxValue) : base(threshold, minRestriction, maxRestriction, maxValue)
- {
- }
- }
- public class ValueAndTimeBasedRestrictionSuggestor : RestrictionSuggestor
- {
- private readonly float tolerance;
- private readonly float timespan;
- private readonly Dictionary<float, float> values = new Dictionary<float, float>();
- private float value;
- public ValueAndTimeBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction, float maxValue, float tolerance, float timespan) : base(threshold, minRestriction, maxRestriction, maxValue)
- {
- this.tolerance = tolerance;
- this.timespan = timespan;
- }
- public override float Suggestion
- {
- get
- {
- var abs = Mathf.Abs(value);
- var stable = !values.Values.Any(v => Mathf.Abs(v - value) > tolerance);
- return abs < threshold || stable
- ? 0f
- : LerpedSuggestion(abs);
- }
- }
- public void UpdateValue(float v)
- {
- value = v;
- var t = Time.time;
- values[t] = v;
- var keys = values.Keys.Where(k => t - k > timespan).ToList();
- keys.ForEach(k => values.Remove(k));
- }
- }
- public abstract class QueueBasedRestrictionSuggestor<T> : RestrictionSuggestor
- {
- protected Queue<Tuple<float, T>> values;
- protected int bufferSize;
- public QueueBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
- float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue)
- {
- this.bufferSize = bufferSize;
- values = new Queue<Tuple<float, T>>(bufferSize);
- }
- public void AddValue(T value)
- {
- if (values.Count >= bufferSize)
- {
- values.Dequeue();
- }
- values.Enqueue(new Tuple<float, T>(Time.time, value));
- }
- }
- public class QueueBasedRestrictionSuggestorFloat : QueueBasedRestrictionSuggestor<float>
- {
- public QueueBasedRestrictionSuggestorFloat(float threshold, float minRestriction, float maxRestriction,
- float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue, bufferSize)
- {
- }
- public override float Suggestion
- {
- get
- {
- var perSecond = new float[values.Count];
- var index = 0;
- var previousValue = values.FirstOrDefault();
- foreach (var value in values)
- {
- // ReSharper disable once PossibleNullReferenceException
- var timeDif = value.Item1 - previousValue.Item1;
- perSecond[index] = timeDif == 0
- ? 0f
- : Mathf.Abs(value.Item2 - previousValue.Item2) /
- timeDif;
- previousValue = value;
- index++;
- }
- var avg = perSecond.Length == 0 ? 0f : perSecond.Average();
- return avg < threshold
- ? 0f
- : LerpedSuggestion(avg);
- }
- }
- }
- public class QueueBasedRestrictionSuggestorVector3 : QueueBasedRestrictionSuggestor<Vector3>
- {
- public QueueBasedRestrictionSuggestorVector3(float threshold, float minRestriction, float maxRestriction,
- float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue, bufferSize)
- {
- }
- public override float Suggestion
- {
- get
- {
- var perSecond = new Vector3[values.Count];
- var index = 0;
- var previousValue = values.FirstOrDefault();
- foreach (var value in values)
- {
- // ReSharper disable once PossibleNullReferenceException
- var timeDif = value.Item1 - previousValue.Item1;
- perSecond[index] = timeDif == 0
- ? Vector3.zero
- : Helpers.Vector3Abs(value.Item2 - previousValue.Item2) /
- timeDif;
- previousValue = value;
- index++;
- }
- var avg = perSecond.Aggregate(Vector3.zero, (agg, v) => agg + v) / perSecond.Length;
- var max = Helpers.GetMaxComponent(avg);
- return max < threshold
- ? 0f
- : LerpedSuggestion(max);
- }
- }
- }
- }
|