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;
 | |
|         }
 | |
|     }
 | |
| }
 |