12using System.Collections.Generic;
19 public static void RemoveRange<T, U>(
this SortedList<T, U> list,
int amount)
23 for (
int i = 0; i < amount && i < list.Count; ++i)
34 public static double Timescale(
38 double catchupNegativeThreshold,
39 double catchupPositiveThreshold)
44 if (drift > catchupPositiveThreshold)
47 return 1 + catchupSpeed;
53 if (drift < catchupNegativeThreshold)
56 return 1 - slowdownSpeed;
65 public static double DynamicAdjustment(
67 double jitterStandardDeviation,
68 double dynamicAdjustmentTolerance)
75 double intervalWithJitter = sendInterval + jitterStandardDeviation;
79 double multiples = intervalWithJitter / sendInterval;
82 double safezone = multiples + dynamicAdjustmentTolerance;
89 public static void Insert<T>(
90 SortedList<double, T> buffer,
92 ref
double localTimeline,
93 ref
double localTimescale,
99 float catchupNegativeThreshold,
100 float catchupPositiveThreshold,
111 if (buffer.Count == 0)
112 localTimeline = snapshot.remoteTime - bufferTime;
122 if (!buffer.ContainsKey(snapshot.remoteTime))
124 buffer.Add(snapshot.remoteTime, snapshot);
127 if (buffer.Count >= 2)
140 double previousLocalTime = buffer.Values[buffer.Count - 2].localTime;
141 double lastestLocalTime = buffer.Values[buffer.Count - 1].localTime;
144 double localDeliveryTime = lastestLocalTime - previousLocalTime;
150 deliveryTimeEma.Add(localDeliveryTime);
160 double latestRemoteTime = snapshot.remoteTime;
161 double timeDiff = latestRemoteTime - localTimeline;
177 driftEma.Add(timeDiff);
180 double drift = driftEma.Value - bufferTime;
183 double absoluteNegativeThreshold = sendInterval * catchupNegativeThreshold;
184 double absolutePositiveThreshold = sendInterval * catchupPositiveThreshold;
191 localTimescale = Timescale(drift, catchupSpeed, slowdownSpeed, absoluteNegativeThreshold, absolutePositiveThreshold);
202 public static void Sample<T>(
203 SortedList<double, T> buffer,
204 double localTimeline,
215 for (
int i = 0; i < buffer.Count - 1; ++i)
218 T first = buffer.Values[i];
219 T second = buffer.Values[i + 1];
220 if (localTimeline >= first.remoteTime &&
221 localTimeline <= second.remoteTime)
235 if (buffer.Values[0].remoteTime > localTimeline)
243 from = to = buffer.Count - 1;
251 public static bool Step<T>(
252 SortedList<double, T> buffer,
254 ref
double localTimeline,
255 double localTimescale,
256 Func<T, T, double, T> Interpolate,
263 if (buffer.Count == 0)
267 localTimeline += deltaTime * localTimescale;
270 Sample(buffer, localTimeline, out
int from, out
int to, out
double t);
273 T fromSnap = buffer.Values[from];
274 T toSnap = buffer.Values[to];
275 computed = Interpolate(fromSnap, toSnap, t);
285 buffer.RemoveRange(from);
static double InverseLerp(double a, double b, double value)
Calculates the linear parameter t that produces the interpolant value within the range [a,...