93 lines
3.7 KiB
C#
93 lines
3.7 KiB
C#
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|