Extrapolation.cs 3.7 KB

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