RestrictionSuggestor.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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 threshold;
  14. protected readonly float minRestriction;
  15. protected readonly float maxRestriction;
  16. protected readonly float maxValue;
  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. protected float LerpedSuggestion(float value) => Mathf.Lerp(minRestriction, maxRestriction,
  26. (value - threshold) / (maxValue - threshold));
  27. public abstract float Suggestion { get; }
  28. }
  29. public class ValueBasedRestrictionSuggestor : RestrictionSuggestor
  30. {
  31. public override float Suggestion
  32. {
  33. get
  34. {
  35. var abs = Mathf.Abs(Value);
  36. return abs < threshold
  37. ? 0f
  38. : LerpedSuggestion(abs);
  39. }
  40. }
  41. public float Value { set; get; } = 0f;
  42. public ValueBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
  43. float maxValue) : base(threshold, minRestriction, maxRestriction, maxValue)
  44. {
  45. }
  46. }
  47. public abstract class QueueBasedRestrictionSuggestor<T> : RestrictionSuggestor
  48. {
  49. protected Queue<Tuple<float, T>> values;
  50. protected int bufferSize;
  51. public QueueBasedRestrictionSuggestor(float threshold, float minRestriction, float maxRestriction,
  52. float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue)
  53. {
  54. this.bufferSize = bufferSize;
  55. values = new Queue<Tuple<float, T>>(bufferSize);
  56. }
  57. public void AddValue(T value)
  58. {
  59. if (values.Count >= bufferSize)
  60. {
  61. values.Dequeue();
  62. }
  63. values.Enqueue(new Tuple<float, T>(Time.time, value));
  64. }
  65. }
  66. public class QueueBasedRestrictionSuggestorFloat : QueueBasedRestrictionSuggestor<float>
  67. {
  68. public QueueBasedRestrictionSuggestorFloat(float threshold, float minRestriction, float maxRestriction,
  69. float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue, bufferSize)
  70. {
  71. }
  72. public override float Suggestion
  73. {
  74. get
  75. {
  76. var perSecond = new float[values.Count];
  77. var index = 0;
  78. var previousValue = values.FirstOrDefault();
  79. foreach (var value in values)
  80. {
  81. // ReSharper disable once PossibleNullReferenceException
  82. var timeDif = value.Item1 - previousValue.Item1;
  83. perSecond[index] = timeDif == 0
  84. ? 0f
  85. : Mathf.Abs(value.Item2 - previousValue.Item2) /
  86. timeDif;
  87. previousValue = value;
  88. index++;
  89. }
  90. var avg = perSecond.Length == 0 ? 0f : perSecond.Average();
  91. return avg < threshold
  92. ? 0f
  93. : LerpedSuggestion(avg);
  94. }
  95. }
  96. }
  97. public class QueueBasedRestrictionSuggestorVector3 : QueueBasedRestrictionSuggestor<Vector3>
  98. {
  99. public QueueBasedRestrictionSuggestorVector3(float threshold, float minRestriction, float maxRestriction,
  100. float maxValue, int bufferSize = 10) : base(threshold, minRestriction, maxRestriction, maxValue, bufferSize)
  101. {
  102. }
  103. public override float Suggestion
  104. {
  105. get
  106. {
  107. var perSecond = new Vector3[values.Count];
  108. var index = 0;
  109. var previousValue = values.FirstOrDefault();
  110. foreach (var value in values)
  111. {
  112. // ReSharper disable once PossibleNullReferenceException
  113. var timeDif = value.Item1 - previousValue.Item1;
  114. perSecond[index] = timeDif == 0
  115. ? Vector3.zero
  116. : Helpers.Vector3Abs(value.Item2 - previousValue.Item2) /
  117. timeDif;
  118. previousValue = value;
  119. index++;
  120. }
  121. var avg = perSecond.Aggregate(Vector3.zero, (agg, v) => agg + v) / perSecond.Length;
  122. var max = Helpers.GetMaxComponent(avg);
  123. return max < threshold
  124. ? 0f
  125. : LerpedSuggestion(max);
  126. }
  127. }
  128. }
  129. }