A game about forced loneliness, made by TACStudios
1using System;
2using UnityEngine;
3
4// Extension methods responsible for managing extrapolation time
5namespace UnityEngine.Timeline
6{
7 static class Extrapolation
8 {
9 /// <summary>
10 /// The minimum amount of extrapolation time to apply
11 /// </summary>
12 internal static readonly double kMinExtrapolationTime = TimeUtility.kTimeEpsilon * 1000;
13
14 // Calculates the extrapolation times
15 internal static void CalculateExtrapolationTimes(this TrackAsset asset)
16 {
17 TimelineClip[] clips = asset.clips;
18 if (clips == null || clips.Length == 0)
19 return;
20
21 // extrapolation not supported
22 if (!clips[0].SupportsExtrapolation())
23 return;
24
25 var orderedClips = SortClipsByStartTime(clips);
26 if (orderedClips.Length > 0)
27 {
28 // post extrapolation is the minimum time to the next clip
29 for (int i = 0; i < orderedClips.Length; i++)
30 {
31 double minTime = double.PositiveInfinity;
32 for (int j = 0; j < orderedClips.Length; j++)
33 {
34 if (i == j)
35 continue;
36
37 double deltaTime = orderedClips[j].start - orderedClips[i].end;
38 if (deltaTime >= -TimeUtility.kTimeEpsilon && deltaTime < minTime)
39 minTime = Math.Min(minTime, deltaTime);
40 // check for overlapped clips
41 if (orderedClips[j].start <= orderedClips[i].end && orderedClips[j].end > orderedClips[i].end)
42 minTime = 0;
43 }
44 minTime = minTime <= kMinExtrapolationTime ? 0 : minTime;
45 orderedClips[i].SetPostExtrapolationTime(minTime);
46 }
47
48 // the first clip gets pre-extrapolation, then it's only respected if there is no post extrapolation
49 orderedClips[0].SetPreExtrapolationTime(Math.Max(0, orderedClips[0].start));
50 for (int i = 1; i < orderedClips.Length; i++)
51 {
52 double preTime = 0;
53 int prevClip = -1;
54 for (int j = 0; j < i; j++)
55 {
56 // overlap, no pre-time
57 if (orderedClips[j].end > orderedClips[i].start)
58 {
59 prevClip = -1;
60 preTime = 0;
61 break;
62 }
63
64 double gap = orderedClips[i].start - orderedClips[j].end;
65 if (prevClip == -1 || gap < preTime)
66 {
67 preTime = gap;
68 prevClip = j;
69 }
70 }
71 // check for a post extrapolation time
72 if (prevClip >= 0)
73 {
74 if (orderedClips[prevClip].postExtrapolationMode != TimelineClip.ClipExtrapolation.None)
75 preTime = 0;
76 }
77
78 preTime = preTime <= kMinExtrapolationTime ? 0 : preTime;
79 orderedClips[i].SetPreExtrapolationTime(preTime);
80 }
81 }
82 }
83
84 static TimelineClip[] SortClipsByStartTime(TimelineClip[] clips)
85 {
86 var orderedClips = new TimelineClip[clips.Length];
87 Array.Copy(clips, orderedClips, clips.Length);
88 Array.Sort(orderedClips, (clip1, clip2) => clip1.start.CompareTo(clip2.start));
89 return orderedClips;
90 }
91 }
92}