RestrictionSuggestor.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. namespace SicknessReduction.Visual.Vignetting
  6. {
  7. public interface IRestrectionSuggestor
  8. {
  9. float Suggestion { get; }
  10. }
  11. public abstract class RestrictionSuggestor : IRestrectionSuggestor
  12. {
  13. protected readonly float maxRestriction;
  14. protected readonly float maxValue;
  15. protected readonly float minRestriction;
  16. protected readonly float threshold;
  17. protected RestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
  18. float maxValue)
  19. {
  20. this.threshold = threshold;
  21. this.minRestriction = minRestriction;
  22. this.maxRestriction = maxRestriction;
  23. this.maxValue = maxValue;
  24. }
  25. public abstract float Suggestion { get; }
  26. protected float LerpedSuggestion(float value)
  27. {
  28. return Mathf.Lerp(minRestriction, maxRestriction,
  29. (value - threshold) / (maxValue - threshold));
  30. }
  31. }
  32. public class ValueBasedRestrictionSuggestor : RestrictionSuggestor
  33. {
  34. public ValueBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
  35. float maxValue) : base(threshold, minRestriction, maxRestriction, maxValue)
  36. {
  37. }
  38. public override float Suggestion
  39. {
  40. get
  41. {
  42. var abs = Mathf.Abs(Value);
  43. return abs < threshold
  44. ? 0f
  45. : LerpedSuggestion(abs);
  46. }
  47. }
  48. public float Value { set; get; } = 0f;
  49. }
  50. public class ValueAndTimeBasedRestrictionSuggestor : RestrictionSuggestor
  51. {
  52. private readonly float timespan;
  53. private readonly float tolerance;
  54. private readonly Dictionary<float, float> values = new Dictionary<float, float>();
  55. private float value;
  56. public ValueAndTimeBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
  57. float maxValue, float tolerance, float timespan) : base(threshold, minRestriction, maxRestriction, maxValue)
  58. {
  59. this.tolerance = tolerance;
  60. this.timespan = timespan;
  61. }
  62. public override float Suggestion
  63. {
  64. get
  65. {
  66. var abs = Mathf.Abs(value);
  67. var stable = !values.Values.Any(v => Mathf.Abs(v - value) > tolerance);
  68. return abs < threshold || stable
  69. ? 0f
  70. : LerpedSuggestion(abs);
  71. }
  72. }
  73. public void UpdateValue(float v)
  74. {
  75. value = v;
  76. var t = Time.time;
  77. values[t] = v;
  78. var keys = values.Keys.Where(k => t - k > timespan).ToList();
  79. keys.ForEach(k => values.Remove(k));
  80. }
  81. }
  82. public abstract class QueueBasedRestrictionSuggestor<T> : RestrictionSuggestor
  83. {
  84. protected int bufferSize;
  85. protected Queue<Tuple<float, T>> values;
  86. public QueueBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
  87. float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue)
  88. {
  89. this.bufferSize = bufferSize;
  90. values = new Queue<Tuple<float, T>>(bufferSize);
  91. }
  92. public void AddValue(T value)
  93. {
  94. if (values.Count >= bufferSize) values.Dequeue();
  95. values.Enqueue(new Tuple<float, T>(Time.time, value));
  96. }
  97. }
  98. public class QueueBasedRestrictionSuggestorFloat : QueueBasedRestrictionSuggestor<float>
  99. {
  100. public QueueBasedRestrictionSuggestorFloat(float threshold, float minRestriction, float maxRestriction,
  101. float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue, bufferSize)
  102. {
  103. }
  104. public override float Suggestion
  105. {
  106. get
  107. {
  108. var perSecond = new float[values.Count];
  109. var index = 0;
  110. var previousValue = values.FirstOrDefault();
  111. foreach (var value in values)
  112. {
  113. // ReSharper disable once PossibleNullReferenceException
  114. var timeDif = value.Item1 - previousValue.Item1;
  115. perSecond[index] = timeDif == 0
  116. ? 0f
  117. : Mathf.Abs(value.Item2 - previousValue.Item2) /
  118. timeDif;
  119. previousValue = value;
  120. index++;
  121. }
  122. var avg = perSecond.Length == 0 ? 0f : perSecond.Average();
  123. return avg < threshold
  124. ? 0f
  125. : LerpedSuggestion(avg);
  126. }
  127. }
  128. }
  129. public class QueueBasedRestrictionSuggestorVector3 : QueueBasedRestrictionSuggestor<Vector3>
  130. {
  131. public QueueBasedRestrictionSuggestorVector3(float threshold, float minRestriction, float maxRestriction,
  132. float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue, bufferSize)
  133. {
  134. }
  135. public override float Suggestion
  136. {
  137. get
  138. {
  139. var perSecond = new Vector3[values.Count];
  140. var index = 0;
  141. var previousValue = values.FirstOrDefault();
  142. foreach (var value in values)
  143. {
  144. // ReSharper disable once PossibleNullReferenceException
  145. var timeDif = value.Item1 - previousValue.Item1;
  146. perSecond[index] = timeDif == 0
  147. ? Vector3.zero
  148. : Helpers.Vector3Abs(value.Item2 - previousValue.Item2) /
  149. timeDif;
  150. previousValue = value;
  151. index++;
  152. }
  153. var avg = perSecond.Aggregate(Vector3.zero, (agg, v) => agg + v) / perSecond.Length;
  154. var max = Helpers.GetMaxComponent(avg);
  155. return max < threshold
  156. ? 0f
  157. : LerpedSuggestion(max);
  158. }
  159. }
  160. }
  161. }