You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.7 KiB
92 lines
3.7 KiB
using System; |
|
using UnityEngine; |
|
|
|
// Extension methods responsible for managing extrapolation time |
|
namespace UnityEngine.Timeline |
|
{ |
|
static class Extrapolation |
|
{ |
|
/// <summary> |
|
/// The minimum amount of extrapolation time to apply |
|
/// </summary> |
|
internal static readonly double kMinExtrapolationTime = TimeUtility.kTimeEpsilon * 1000; |
|
|
|
// Calculates the extrapolation times |
|
internal static void CalculateExtrapolationTimes(this TrackAsset asset) |
|
{ |
|
TimelineClip[] clips = asset.clips; |
|
if (clips == null || clips.Length == 0) |
|
return; |
|
|
|
// extrapolation not supported |
|
if (!clips[0].SupportsExtrapolation()) |
|
return; |
|
|
|
var orderedClips = SortClipsByStartTime(clips); |
|
if (orderedClips.Length > 0) |
|
{ |
|
// post extrapolation is the minimum time to the next clip |
|
for (int i = 0; i < orderedClips.Length; i++) |
|
{ |
|
double minTime = double.PositiveInfinity; |
|
for (int j = 0; j < orderedClips.Length; j++) |
|
{ |
|
if (i == j) |
|
continue; |
|
|
|
double deltaTime = orderedClips[j].start - orderedClips[i].end; |
|
if (deltaTime >= -TimeUtility.kTimeEpsilon && deltaTime < minTime) |
|
minTime = Math.Min(minTime, deltaTime); |
|
// check for overlapped clips |
|
if (orderedClips[j].start <= orderedClips[i].end && orderedClips[j].end > orderedClips[i].end) |
|
minTime = 0; |
|
} |
|
minTime = minTime <= kMinExtrapolationTime ? 0 : minTime; |
|
orderedClips[i].SetPostExtrapolationTime(minTime); |
|
} |
|
|
|
// the first clip gets pre-extrapolation, then it's only respected if there is no post extrapolation |
|
orderedClips[0].SetPreExtrapolationTime(Math.Max(0, orderedClips[0].start)); |
|
for (int i = 1; i < orderedClips.Length; i++) |
|
{ |
|
double preTime = 0; |
|
int prevClip = -1; |
|
for (int j = 0; j < i; j++) |
|
{ |
|
// overlap, no pre-time |
|
if (orderedClips[j].end > orderedClips[i].start) |
|
{ |
|
prevClip = -1; |
|
preTime = 0; |
|
break; |
|
} |
|
|
|
double gap = orderedClips[i].start - orderedClips[j].end; |
|
if (prevClip == -1 || gap < preTime) |
|
{ |
|
preTime = gap; |
|
prevClip = j; |
|
} |
|
} |
|
// check for a post extrapolation time |
|
if (prevClip >= 0) |
|
{ |
|
if (orderedClips[prevClip].postExtrapolationMode != TimelineClip.ClipExtrapolation.None) |
|
preTime = 0; |
|
} |
|
|
|
preTime = preTime <= kMinExtrapolationTime ? 0 : preTime; |
|
orderedClips[i].SetPreExtrapolationTime(preTime); |
|
} |
|
} |
|
} |
|
|
|
static TimelineClip[] SortClipsByStartTime(TimelineClip[] clips) |
|
{ |
|
var orderedClips = new TimelineClip[clips.Length]; |
|
Array.Copy(clips, orderedClips, clips.Length); |
|
Array.Sort(orderedClips, (clip1, clip2) => clip1.start.CompareTo(clip2.start)); |
|
return orderedClips; |
|
} |
|
} |
|
}
|
|
|