summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities
diff options
context:
space:
mode:
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs266
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs133
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs92
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs51
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs102
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs17
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs54
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs212
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs131
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs90
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs30
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta11
22 files changed, 1299 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs
new file mode 100644
index 0000000..b8ab669
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs
@@ -0,0 +1,266 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using UnityEditor;
+
+
+namespace UnityEngine.Timeline
+{
+ static class AnimationPreviewUtilities
+ {
+ private const string k_PosX = "m_LocalPosition.x";
+ private const string k_PosY = "m_LocalPosition.y";
+ private const string k_PosZ = "m_LocalPosition.z";
+ private const string k_RotX = "m_LocalRotation.x";
+ private const string k_RotY = "m_LocalRotation.y";
+ private const string k_RotZ = "m_LocalRotation.z";
+ private const string k_RotW = "m_LocalRotation.w";
+ private const string k_ScaleX = "m_LocalScale.x";
+ private const string k_ScaleY = "m_LocalScale.y";
+ private const string k_ScaleZ = "m_LocalScale.z";
+ private const string k_EulerAnglesRaw = "localEulerAnglesRaw";
+ private const string k_EulerHint = "m_LocalEulerAnglesHint";
+ private const string k_Pos = "m_LocalPosition";
+ private const string k_Rot = "m_LocalRotation";
+ private const string k_MotionT = "MotionT";
+ private const string k_MotionQ = "MotionQ";
+ private const string k_RootT = "RootT";
+ private const string k_RootQ = "RootQ";
+
+
+ internal class EditorCurveBindingComparer : IEqualityComparer<EditorCurveBinding>
+ {
+ public bool Equals(EditorCurveBinding x, EditorCurveBinding y) { return x.path.Equals(y.path) && x.type == y.type && x.propertyName == y.propertyName; }
+ public int GetHashCode(EditorCurveBinding obj)
+ {
+ return obj.propertyName.GetHashCode() ^ obj.path.GetHashCode();
+ }
+
+ public static readonly EditorCurveBindingComparer Instance = new EditorCurveBindingComparer();
+ }
+
+ // a dictionary is faster than a hashset, because the capacity can be pre-set
+ private static readonly Dictionary<EditorCurveBinding, int> s_CurveSet = new Dictionary<EditorCurveBinding, int>(10000, EditorCurveBindingComparer.Instance);
+ private static readonly AnimatorBindingCache s_BindingCache = new AnimatorBindingCache();
+
+ public static void ClearCaches()
+ {
+ s_BindingCache.Clear();
+ s_CurveSet.Clear();
+ }
+
+ public static EditorCurveBinding[] GetBindings(GameObject animatorRoot, IEnumerable<AnimationClip> clips)
+ {
+ s_CurveSet.Clear();
+ foreach (var clip in clips)
+ {
+ AddBindings(s_BindingCache.GetCurveBindings(clip));
+ }
+
+ // if we have a transform binding, bind the entire skeleton
+ if (NeedsSkeletonBindings(s_CurveSet.Keys))
+ AddBindings(s_BindingCache.GetAnimatorBindings(animatorRoot));
+
+ var bindings = new EditorCurveBinding[s_CurveSet.Keys.Count];
+ s_CurveSet.Keys.CopyTo(bindings, 0);
+ return bindings;
+ }
+
+ public static void PreviewFromCurves(GameObject animatorRoot, IEnumerable<EditorCurveBinding> keys)
+ {
+ if (!AnimationMode.InAnimationMode())
+ return;
+
+ var avatarRoot = GetAvatarRoot(animatorRoot);
+ foreach (var binding in keys)
+ {
+ if (IsAvatarBinding(binding) || IsEuler(binding))
+ continue;
+
+ bool isTransform = typeof(Transform).IsAssignableFrom(binding.type);
+ if (isTransform && binding.propertyName == AnimatorBindingCache.TRPlaceHolder)
+ AddTRBinding(animatorRoot, binding);
+ else if (isTransform && binding.propertyName == AnimatorBindingCache.ScalePlaceholder)
+ AddScaleBinding(animatorRoot, binding);
+ else
+ AnimationMode.AddEditorCurveBinding(avatarRoot, binding);
+ }
+ }
+
+ public static AnimationClip CreateDefaultClip(GameObject animatorRoot, IEnumerable<EditorCurveBinding> keys)
+ {
+ AnimationClip animClip = new AnimationClip() { name = "DefaultPose" };
+ var keyFrames = new[] {new Keyframe(0, 0)};
+ var curve = new AnimationCurve(keyFrames);
+ bool rootMotion = false;
+ var avatarRoot = GetAvatarRoot(animatorRoot);
+
+ foreach (var binding in keys)
+ {
+ if (IsRootMotion(binding))
+ {
+ rootMotion = true;
+ continue;
+ }
+
+ if (typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName == AnimatorBindingCache.TRPlaceHolder)
+ {
+ if (string.IsNullOrEmpty(binding.path))
+ rootMotion = true;
+ else
+ {
+ var transform = animatorRoot.transform.Find(binding.path);
+ if (transform != null)
+ {
+ var pos = transform.localPosition;
+ var rot = transform.localRotation;
+ animClip.SetCurve(binding.path, typeof(Transform), k_PosX, SetZeroKey(curve, keyFrames, pos.x));
+ animClip.SetCurve(binding.path, typeof(Transform), k_PosY, SetZeroKey(curve, keyFrames, pos.y));
+ animClip.SetCurve(binding.path, typeof(Transform), k_PosZ, SetZeroKey(curve, keyFrames, pos.z));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotX, SetZeroKey(curve, keyFrames, rot.x));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotY, SetZeroKey(curve, keyFrames, rot.y));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotZ, SetZeroKey(curve, keyFrames, rot.z));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotW, SetZeroKey(curve, keyFrames, rot.w));
+ }
+ }
+
+ continue;
+ }
+
+ if (typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName == AnimatorBindingCache.ScalePlaceholder)
+ {
+ var transform = animatorRoot.transform.Find(binding.path);
+ if (transform != null)
+ {
+ var scale = transform.localScale;
+ animClip.SetCurve(binding.path, typeof(Transform), k_ScaleX, SetZeroKey(curve, keyFrames, scale.x));
+ animClip.SetCurve(binding.path, typeof(Transform), k_ScaleY, SetZeroKey(curve, keyFrames, scale.y));
+ animClip.SetCurve(binding.path, typeof(Transform), k_ScaleZ, SetZeroKey(curve, keyFrames, scale.z));
+ }
+
+ continue;
+ }
+
+ // Not setting curves through AnimationUtility.SetEditorCurve to avoid reentrant
+ // onCurveWasModified calls in timeline. This means we don't get sprite curves
+ // in the default clip right now.
+ if (IsAvatarBinding(binding) || IsEulerHint(binding) || binding.isPPtrCurve)
+ continue;
+
+ float floatValue;
+ AnimationUtility.GetFloatValue(avatarRoot, binding, out floatValue);
+ animClip.SetCurve(binding.path, binding.type, binding.propertyName, SetZeroKey(curve, keyFrames, floatValue));
+ }
+
+ // add root motion explicitly.
+ if (rootMotion)
+ {
+ var pos = Vector3.zero; // the appropriate root motion offsets are applied by timeline
+ var rot = Quaternion.identity;
+ animClip.SetCurve(string.Empty, typeof(Transform), k_PosX, SetZeroKey(curve, keyFrames, pos.x));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_PosY, SetZeroKey(curve, keyFrames, pos.y));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_PosZ, SetZeroKey(curve, keyFrames, pos.z));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotX, SetZeroKey(curve, keyFrames, rot.x));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotY, SetZeroKey(curve, keyFrames, rot.y));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotZ, SetZeroKey(curve, keyFrames, rot.z));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotW, SetZeroKey(curve, keyFrames, rot.w));
+ }
+
+ return animClip;
+ }
+
+ public static bool IsRootMotion(EditorCurveBinding binding)
+ {
+ // Root Transform TR.
+ if (typeof(Transform).IsAssignableFrom(binding.type) && string.IsNullOrEmpty(binding.path))
+ {
+ return binding.propertyName.StartsWith(k_Pos) || binding.propertyName.StartsWith(k_Rot);
+ }
+
+ // MotionCurves/RootCurves.
+ if (binding.type == typeof(Animator))
+ {
+ return binding.propertyName.StartsWith(k_MotionT) || binding.propertyName.StartsWith(k_MotionQ) ||
+ binding.propertyName.StartsWith(k_RootT) || binding.propertyName.StartsWith(k_RootQ);
+ }
+
+ return false;
+ }
+
+ private static bool NeedsSkeletonBindings(IEnumerable<EditorCurveBinding> bindings)
+ {
+ foreach (var b in bindings)
+ {
+ if (IsSkeletalBinding(b))
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void AddBindings(IEnumerable<EditorCurveBinding> bindings)
+ {
+ foreach (var b in bindings)
+ {
+ if (!s_CurveSet.ContainsKey(b))
+ s_CurveSet[b] = 1;
+ }
+ }
+
+ private static void AddTRBinding(GameObject root, EditorCurveBinding binding)
+ {
+ // This is faster than AnimationMode.AddTransformTR
+ binding.propertyName = k_PosX; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_PosY; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_PosZ; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotX; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotY; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotZ; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotW; AnimationMode.AddEditorCurveBinding(root, binding);
+ }
+
+ private static void AddScaleBinding(GameObject root, EditorCurveBinding binding)
+ {
+ // AnimationMode.AddTransformTRS is slow
+ binding.propertyName = k_ScaleX; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_ScaleY; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_ScaleZ; AnimationMode.AddEditorCurveBinding(root, binding);
+ }
+
+ private static bool IsEuler(EditorCurveBinding binding)
+ {
+ return typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName.StartsWith(k_EulerAnglesRaw);
+ }
+
+ private static bool IsAvatarBinding(EditorCurveBinding binding)
+ {
+ return typeof(Animator).IsAssignableFrom(binding.type) && string.IsNullOrEmpty(binding.path);
+ }
+
+ private static bool IsSkeletalBinding(EditorCurveBinding binding)
+ {
+ // skin mesh incorporates blend shapes
+ return typeof(Transform).IsAssignableFrom(binding.type) || typeof(SkinnedMeshRenderer).IsAssignableFrom(binding.type);
+ }
+
+ private static AnimationCurve SetZeroKey(AnimationCurve curve, Keyframe[] keys, float val)
+ {
+ keys[0].value = val;
+ curve.keys = keys;
+ return curve;
+ }
+
+ private static bool IsEulerHint(EditorCurveBinding binding)
+ {
+ return typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName.StartsWith(k_EulerHint);
+ }
+
+ private static GameObject GetAvatarRoot(GameObject animatorRoot)
+ {
+ var animator = animatorRoot.GetComponent<Animator>();
+ if (animator != null && animator.avatarRoot != animatorRoot.transform)
+ return animator.avatarRoot.gameObject;
+ return animatorRoot;
+ }
+ }
+}
+#endif
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta
new file mode 100644
index 0000000..82e3768
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 01da6c5b7c781174d818662ce6f39b8b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs
new file mode 100644
index 0000000..53198ea
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs
@@ -0,0 +1,133 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using UnityEditor;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Animator to Editor Curve Binding cache. Used to prevent frequent calls to GetAnimatorBindings which can be costly
+ /// </summary>
+ class AnimatorBindingCache
+ {
+ public const string TRPlaceHolder = "TransformTR";
+ public const string ScalePlaceholder = "TransformScale";
+
+ struct AnimatorEntry
+ {
+ public int animatorID;
+ public bool applyRootMotion;
+ public bool humanoid;
+ }
+
+ class AnimatorEntryComparer : IEqualityComparer<AnimatorEntry>
+ {
+ public bool Equals(AnimatorEntry x, AnimatorEntry y) { return x.animatorID == y.animatorID && x.applyRootMotion == y.applyRootMotion && x.humanoid == y.humanoid; }
+ public int GetHashCode(AnimatorEntry obj) { return HashUtility.CombineHash(obj.animatorID, obj.applyRootMotion.GetHashCode(), obj.humanoid.GetHashCode()); }
+ public static readonly AnimatorEntryComparer Instance = new AnimatorEntryComparer();
+ }
+
+ readonly Dictionary<AnimatorEntry, EditorCurveBinding[]> m_AnimatorCache = new Dictionary<AnimatorEntry, EditorCurveBinding[]>(AnimatorEntryComparer.Instance);
+ readonly Dictionary<AnimationClip, EditorCurveBinding[]> m_ClipCache = new Dictionary<AnimationClip, EditorCurveBinding[]>();
+
+ private static readonly EditorCurveBinding[] kEmptyArray = new EditorCurveBinding[0];
+ private static readonly List<EditorCurveBinding> s_BindingScratchPad = new List<EditorCurveBinding>(1000);
+
+ public AnimatorBindingCache()
+ {
+ AnimationUtility.onCurveWasModified += OnCurveWasModified;
+ }
+
+ public EditorCurveBinding[] GetAnimatorBindings(GameObject gameObject)
+ {
+ if (gameObject == null)
+ return kEmptyArray;
+
+ Animator animator = gameObject.GetComponent<Animator>();
+ if (animator == null)
+ return kEmptyArray;
+
+ AnimatorEntry entry = new AnimatorEntry()
+ {
+ animatorID = animator.GetInstanceID(),
+ applyRootMotion = animator.applyRootMotion,
+ humanoid = animator.isHuman
+ };
+
+ EditorCurveBinding[] result = null;
+ if (m_AnimatorCache.TryGetValue(entry, out result))
+ return result;
+
+ s_BindingScratchPad.Clear();
+
+ // Replacement for AnimationMode.GetAnimatorBinding - this is faster and allocates kB instead of MB
+ var transforms = animator.GetComponentsInChildren<Transform>();
+ foreach (var t in transforms)
+ {
+ if (animator.IsBoneTransform(t))
+ s_BindingScratchPad.Add(EditorCurveBinding.FloatCurve(AnimationUtility.CalculateTransformPath(t, animator.transform), typeof(Transform), TRPlaceHolder));
+ }
+
+ var streamBindings = AnimationUtility.GetAnimationStreamBindings(animator.gameObject);
+ UpdateTransformBindings(streamBindings);
+ s_BindingScratchPad.AddRange(streamBindings);
+
+ result = new EditorCurveBinding[s_BindingScratchPad.Count];
+ s_BindingScratchPad.CopyTo(result);
+ m_AnimatorCache[entry] = result;
+ return result;
+ }
+
+ public EditorCurveBinding[] GetCurveBindings(AnimationClip clip)
+ {
+ if (clip == null)
+ return kEmptyArray;
+
+ EditorCurveBinding[] result;
+ if (!m_ClipCache.TryGetValue(clip, out result))
+ {
+ result = AnimationMode.GetCurveBindings(clip);
+ UpdateTransformBindings(result);
+ m_ClipCache[clip] = result;
+ }
+
+ return result;
+ }
+
+ private static void UpdateTransformBindings(EditorCurveBinding[] bindings)
+ {
+ for (int i = 0; i < bindings.Length; i++)
+ {
+ var binding = bindings[i];
+ if (AnimationPreviewUtilities.IsRootMotion(binding))
+ {
+ binding.type = typeof(Transform);
+ binding.propertyName = TRPlaceHolder;
+ }
+ else if (typeof(Transform).IsAssignableFrom(binding.type) && (binding.propertyName.StartsWith("m_LocalRotation.") || binding.propertyName.StartsWith("m_LocalPosition.")))
+ {
+ binding.propertyName = TRPlaceHolder;
+ }
+ else if (typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName.StartsWith("m_LocalScale."))
+ {
+ binding.propertyName = ScalePlaceholder;
+ }
+ bindings[i] = binding;
+ }
+ }
+
+ public void Clear()
+ {
+ m_AnimatorCache.Clear();
+ m_ClipCache.Clear();
+ }
+
+ void OnCurveWasModified(AnimationClip clip, EditorCurveBinding binding, AnimationUtility.CurveModifiedType modification)
+ {
+ m_ClipCache.Remove(clip);
+ }
+ }
+}
+#endif
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta
new file mode 100644
index 0000000..dc6dc1d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d0080567f62c3f94cb75b2927a349e22
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs
new file mode 100644
index 0000000..34408c9
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs
@@ -0,0 +1,92 @@
+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;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta
new file mode 100644
index 0000000..69c90cf
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 32535dd294c621e4297fba34b15b1c52
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs
new file mode 100644
index 0000000..81fa940
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs
@@ -0,0 +1,51 @@
+namespace UnityEngine.Timeline
+{
+ static class HashUtility
+ {
+ // Note. We could have used "params int[] hashes" but we want to avoid allocating.
+
+ public static int CombineHash(this int h1, int h2)
+ {
+ return h1 ^ (int)(h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); // Similar to c++ boost::hash_combine
+ }
+
+ public static int CombineHash(int h1, int h2, int h3)
+ {
+ return CombineHash(h1, h2).CombineHash(h3);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4)
+ {
+ return CombineHash(h1, h2, h3).CombineHash(h4);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4, int h5)
+ {
+ return CombineHash(h1, h2, h3, h4).CombineHash(h5);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4, int h5, int h6)
+ {
+ return CombineHash(h1, h2, h3, h4, h5).CombineHash(h6);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
+ {
+ return CombineHash(h1, h2, h3, h4, h5, h6).CombineHash(h7);
+ }
+
+ public static int CombineHash(int[] hashes)
+ {
+ if (hashes == null || hashes.Length == 0)
+ return 0;
+
+ var h = hashes[0];
+ for (int i = 1; i < hashes.Length; ++i)
+ {
+ h = CombineHash(h, hashes[i]);
+ }
+
+ return h;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta
new file mode 100644
index 0000000..fec5c19
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d0ca7b2e84542bf4ab9987087e8d79ad
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs
new file mode 100644
index 0000000..08f991a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs
@@ -0,0 +1,102 @@
+using System.Collections.Generic;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Interface used to inform the Timeline Editor about potential property modifications that may occur while previewing.
+ /// </summary>
+ public interface IPropertyCollector
+ {
+ /// <summary>
+ /// Sets the active game object for subsequent property modifications.
+ /// </summary>
+ /// <param name="gameObject">The GameObject to push.</param>
+ void PushActiveGameObject(GameObject gameObject);
+
+ /// <summary>
+ /// Removes the active GameObject from the modification stack, restoring the previous value.
+ /// </summary>
+ void PopActiveGameObject();
+
+ /// <summary>
+ /// Add properties modified by an animation clip.
+ /// </summary>
+ /// <param name="clip">The animation clip that contains the properties</param>
+ void AddFromClip(AnimationClip clip);
+
+ /// <summary>
+ /// Add property modifications specified by a list of animation clips.
+ /// </summary>
+ /// <param name="clips">The list of animation clips used to determine which property modifications to apply.</param>
+ void AddFromClips(IEnumerable<AnimationClip> clips);
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <typeparam name="T">The type of the component the property exists on</typeparam>
+ /// <remarks>
+ /// This method uses the most recent gameObject from PushActiveGameObject
+ /// </remarks>
+ void AddFromName<T>(string name) where T : Component;
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <remarks>
+ /// This method uses the most recent gameObject from PushActiveGameObject
+ /// </remarks>
+ void AddFromName(string name);
+
+ /// <summary>
+ /// Add property modifications modified by an animation clip.
+ /// </summary>
+ /// <param name="obj">The GameObject where the properties exist</param>
+ /// <param name="clip">The animation clip that contains the properties</param>
+ void AddFromClip(GameObject obj, AnimationClip clip);
+
+ /// <summary>
+ /// Add property modifications specified by a list of animation clips.
+ /// </summary>
+ /// <param name="obj">The gameObject that will be animated</param>
+ /// <param name="clips">The list of animation clips used to determine which property modifications to apply.</param>
+ void AddFromClips(GameObject obj, IEnumerable<AnimationClip> clips);
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <param name="obj">The gameObject where the properties exist</param>
+ /// <typeparam name="T">The type of the component the property exists on</typeparam>>
+ void AddFromName<T>(GameObject obj, string name) where T : Component;
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="obj">The gameObject where the properties exist</param>
+ /// <param name="name">The name of the serialized property</param>
+ void AddFromName(GameObject obj, string name);
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <param name="component">The component where the properties exist</param>
+ void AddFromName(Component component, string name);
+
+ /// <summary>
+ /// Set all serializable properties on a component to be under preview control.
+ /// </summary>
+ /// <param name="obj">The gameObject where the properties exist</param>
+ /// <param name="component">The component to set in preview mode</param>
+ void AddFromComponent(GameObject obj, Component component);
+
+ /// <summary>
+ /// Add property modifications modified by an animation clip.
+ /// </summary>
+ /// <param name="obj">The Object where the properties exist</param>
+ /// <param name="clip">The animation clip that contains the properties</param>
+ void AddObjectProperties(Object obj, AnimationClip clip);
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta
new file mode 100644
index 0000000..05ecf1d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 66b2b8fd1d9b4bc4c96b07335ad822f3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs
new file mode 100644
index 0000000..b779f15
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs
@@ -0,0 +1,17 @@
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Implement this interface in a PlayableAsset to specify which properties will be modified when Timeline is in preview mode.
+ /// </summary>
+ public interface IPropertyPreview
+ {
+ /// <summary>
+ /// Called by the Timeline Editor to gather properties requiring preview.
+ /// </summary>
+ /// <param name="director">The PlayableDirector invoking the preview</param>
+ /// <param name="driver">PropertyCollector used to gather previewable properties</param>
+ void GatherProperties(PlayableDirector director, IPropertyCollector driver);
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta
new file mode 100644
index 0000000..31806d8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b5f0881228e5827438f74e9b7b33c2dc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs
new file mode 100644
index 0000000..41aabce
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ static class NotificationUtilities
+ {
+ public static ScriptPlayable<TimeNotificationBehaviour> CreateNotificationsPlayable(PlayableGraph graph, IEnumerable<IMarker> markers, GameObject go)
+ {
+ var notificationPlayable = ScriptPlayable<TimeNotificationBehaviour>.Null;
+ var director = go.GetComponent<PlayableDirector>();
+ foreach (var e in markers)
+ {
+ var notif = e as INotification;
+ if (notif == null)
+ continue;
+
+ if (notificationPlayable.Equals(ScriptPlayable<TimeNotificationBehaviour>.Null))
+ {
+ notificationPlayable = TimeNotificationBehaviour.Create(graph,
+ director.playableAsset.duration, director.extrapolationMode);
+ }
+
+ var time = (DiscreteTime)e.time;
+ var tlDuration = (DiscreteTime)director.playableAsset.duration;
+ if (time >= tlDuration && time <= tlDuration.OneTickAfter() && tlDuration != 0)
+ {
+ time = tlDuration.OneTickBefore();
+ }
+
+ var notificationOptionProvider = e as INotificationOptionProvider;
+ if (notificationOptionProvider != null)
+ {
+ notificationPlayable.GetBehaviour().AddNotification((double)time, notif, notificationOptionProvider.flags);
+ }
+ else
+ {
+ notificationPlayable.GetBehaviour().AddNotification((double)time, notif);
+ }
+ }
+
+ return notificationPlayable;
+ }
+
+ public static bool TrackTypeSupportsNotifications(Type type)
+ {
+ var binding = (TrackBindingTypeAttribute)Attribute.GetCustomAttribute(type, typeof(TrackBindingTypeAttribute));
+ return binding != null &&
+ (typeof(Component).IsAssignableFrom(binding.type) ||
+ typeof(GameObject).IsAssignableFrom(binding.type));
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta
new file mode 100644
index 0000000..6e5c8c3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b90311a8f07b00f4bbeb2fff3b128d25
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs
new file mode 100644
index 0000000..549de4c
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Text.RegularExpressions;
+
+namespace UnityEngine.Timeline
+{
+ // Sequence specific utilities for time manipulation
+ static class TimeUtility
+ {
+ // chosen because it will cause no rounding errors between time/frames for frames values up to at least 10 million
+ public static readonly double kTimeEpsilon = 1e-14;
+ public static readonly double kFrameRateEpsilon = 1e-6;
+ public static readonly double k_MaxTimelineDurationInSeconds = 9e6; //104 days of running time
+
+ static void ValidateFrameRate(double frameRate)
+ {
+ if (frameRate <= kTimeEpsilon)
+ throw new ArgumentException("frame rate cannot be 0 or negative");
+ }
+
+ public static int ToFrames(double time, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ time = Math.Min(Math.Max(time, -k_MaxTimelineDurationInSeconds), k_MaxTimelineDurationInSeconds);
+ // this matches OnFrameBoundary
+ double tolerance = GetEpsilon(time, frameRate) / 2.0;
+ if (time < 0)
+ {
+ return (int)Math.Ceiling(time * frameRate - tolerance);
+ }
+ return (int)Math.Floor(time * frameRate + tolerance);
+ }
+
+ public static double ToExactFrames(double time, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ return time * frameRate;
+ }
+
+ public static double FromFrames(int frames, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ return (frames / frameRate);
+ }
+
+ public static double FromFrames(double frames, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ return frames / frameRate;
+ }
+
+ public static bool OnFrameBoundary(double time, double frameRate)
+ {
+ return OnFrameBoundary(time, frameRate, GetEpsilon(time, frameRate));
+ }
+
+ public static double GetEpsilon(double time, double frameRate)
+ {
+ return Math.Max(Math.Abs(time), 1) * frameRate * kTimeEpsilon;
+ }
+
+ public static bool OnFrameBoundary(double time, double frameRate, double epsilon)
+ {
+ ValidateFrameRate(frameRate);
+
+ double exact = ToExactFrames(time, frameRate);
+ double rounded = Math.Round(exact);
+
+ return Math.Abs(exact - rounded) < epsilon;
+ }
+
+ public static double RoundToFrame(double time, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+
+ var frameBefore = (int)Math.Floor(time * frameRate) / frameRate;
+ var frameAfter = (int)Math.Ceiling(time * frameRate) / frameRate;
+
+ return Math.Abs(time - frameBefore) < Math.Abs(time - frameAfter) ? frameBefore : frameAfter;
+ }
+
+ public static string TimeAsFrames(double timeValue, double frameRate, string format = "F2")
+ {
+ if (OnFrameBoundary(timeValue, frameRate)) // make integral values when on time borders
+ return ToFrames(timeValue, frameRate).ToString();
+ return ToExactFrames(timeValue, frameRate).ToString(format);
+ }
+
+ public static string TimeAsTimeCode(double timeValue, double frameRate, string format = "F2")
+ {
+ ValidateFrameRate(frameRate);
+
+ int intTime = (int)Math.Abs(timeValue);
+
+ int hours = intTime / 3600;
+ int minutes = (intTime % 3600) / 60;
+ int seconds = intTime % 60;
+
+ string result;
+ string sign = timeValue < 0 ? "-" : string.Empty;
+ if (hours > 0)
+ result = hours + ":" + minutes.ToString("D2") + ":" + seconds.ToString("D2");
+ else if (minutes > 0)
+ result = minutes + ":" + seconds.ToString("D2");
+ else
+ result = seconds.ToString();
+
+ int frameDigits = (int)Math.Floor(Math.Log10(frameRate) + 1);
+
+ // Add partial digits on the frame if needed.
+ // we are testing the original value (not the truncated), because the truncation can cause rounding errors leading
+ // to invalid strings for items on frame boundaries
+ string frames = (ToFrames(timeValue, frameRate) - ToFrames(intTime, frameRate)).ToString().PadLeft(frameDigits, '0');
+ if (!OnFrameBoundary(timeValue, frameRate))
+ {
+ string decimals = ToExactFrames(timeValue, frameRate).ToString(format);
+ int decPlace = decimals.IndexOf('.');
+ if (decPlace >= 0)
+ frames += " [" + decimals.Substring(decPlace) + "]";
+ }
+
+ return sign + result + ":" + frames;
+ }
+
+ // Given a time code string, return the time in seconds
+ // 1.5 -> 1.5 seconds
+ // 1:1.5 -> 1 minute, 1.5 seconds
+ // 1:1[.5] -> 1 second, 1.5 frames
+ // 2:3:4 -> 2 minutes, 3 seconds, 4 frames
+ // 1[.6] -> 1.6 frames
+ public static double ParseTimeCode(string timeCode, double frameRate, double defaultValue)
+ {
+ timeCode = RemoveChar(timeCode, c => char.IsWhiteSpace(c));
+ string[] sections = timeCode.Split(':');
+ if (sections.Length == 0 || sections.Length > 4)
+ return defaultValue;
+
+ int hours = 0;
+ int minutes = 0;
+ double seconds = 0;
+ double frames = 0;
+
+ try
+ {
+ // depending on the format of the last numbers
+ // seconds format
+ string lastSection = sections[sections.Length - 1];
+ if (Regex.Match(lastSection, @"^\d+\.\d+$").Success)
+ {
+ seconds = double.Parse(lastSection);
+ if (sections.Length > 3) return defaultValue;
+ if (sections.Length > 1) minutes = int.Parse(sections[sections.Length - 2]);
+ if (sections.Length > 2) hours = int.Parse(sections[sections.Length - 3]);
+ }
+ // frame formats
+ else
+ {
+ if (Regex.Match(lastSection, @"^\d+\[\.\d+\]$").Success)
+ {
+ string stripped = RemoveChar(lastSection, c => c == '[' || c == ']');
+ frames = double.Parse(stripped);
+ }
+ else if (Regex.Match(lastSection, @"^\d*$").Success)
+ {
+ frames = int.Parse(lastSection);
+ }
+ else
+ {
+ return defaultValue;
+ }
+
+ if (sections.Length > 1) seconds = int.Parse(sections[sections.Length - 2]);
+ if (sections.Length > 2) minutes = int.Parse(sections[sections.Length - 3]);
+ if (sections.Length > 3) hours = int.Parse(sections[sections.Length - 4]);
+ }
+ }
+ catch (FormatException)
+ {
+ return defaultValue;
+ }
+
+ return frames / frameRate + seconds + minutes * 60 + hours * 3600;
+ }
+
+ // fixes rounding errors from using single precision for length
+ public static double GetAnimationClipLength(AnimationClip clip)
+ {
+ if (clip == null || clip.empty)
+ return 0;
+
+ double length = clip.length;
+ if (clip.frameRate > 0)
+ {
+ double frames = Mathf.Round(clip.length * clip.frameRate);
+ length = frames / clip.frameRate;
+ }
+ return length;
+ }
+
+ static string RemoveChar(string str, Func<char, bool> charToRemoveFunc)
+ {
+ var len = str.Length;
+ var src = str.ToCharArray();
+ var dstIdx = 0;
+ for (var i = 0; i < len; i++)
+ {
+ if (!charToRemoveFunc(src[i]))
+ src[dstIdx++] = src[i];
+ }
+ return new string(src, 0, dstIdx);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta
new file mode 100644
index 0000000..ff1d820
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f779e779d62b5ca49b658236c337845d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs
new file mode 100644
index 0000000..0870e40
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace UnityEngine.Timeline
+{
+ static class TimelineCreateUtilities
+ {
+ // based off of ObjectNames.GetUniqueName, but can exist in runtime
+ public static string GenerateUniqueActorName(List<ScriptableObject> tracks, string name)
+ {
+ if (!tracks.Exists(x => ((object)x) != null && x.name == name))
+ return name;
+
+ int numberInParentheses = 0;
+ string baseName = name;
+
+ if (!string.IsNullOrEmpty(name) && name[name.Length - 1] == ')')
+ {
+ int index = name.LastIndexOf('(');
+ if (index > 0)
+ {
+ string numberString = name.Substring(index + 1, name.Length - index - 2);
+ if (int.TryParse(numberString, out numberInParentheses))
+ {
+ numberInParentheses++;
+ baseName = name.Substring(0, index);
+ }
+ }
+ }
+
+ baseName = baseName.TrimEnd();
+
+ for (int i = numberInParentheses; i < numberInParentheses + 5000; i++)
+ {
+ if (i > 0)
+ {
+ string result = string.Format("{0} ({1})", baseName, i);
+ if (!tracks.Exists(x => ((object)x) != null && x.name == result))
+ return result;
+ }
+ }
+
+ // Fallback
+ return name;
+ }
+
+ public static void SaveAssetIntoObject(Object childAsset, Object masterAsset)
+ {
+ if (childAsset == null || masterAsset == null)
+ return;
+
+ if ((masterAsset.hideFlags & HideFlags.DontSave) != 0)
+ {
+ childAsset.hideFlags |= HideFlags.DontSave;
+ }
+ else
+ {
+ childAsset.hideFlags |= HideFlags.HideInHierarchy;
+#if UNITY_EDITOR
+ if (!AssetDatabase.Contains(childAsset) && AssetDatabase.Contains(masterAsset))
+ AssetDatabase.AddObjectToAsset(childAsset, masterAsset);
+#endif
+ }
+ }
+
+ public static AnimationClip CreateAnimationClipForTrack(string name, TrackAsset track, bool isLegacy)
+ {
+ var timelineAsset = track != null ? track.timelineAsset : null;
+ var trackFlags = track != null ? track.hideFlags : HideFlags.None;
+
+ var curves = new AnimationClip
+ {
+ legacy = isLegacy,
+
+ name = name,
+
+ frameRate = timelineAsset == null
+ ? TimelineAsset.EditorSettings.kDefaultFps
+ : timelineAsset.editorSettings.fps
+ };
+
+ SaveAssetIntoObject(curves, timelineAsset);
+ curves.hideFlags = trackFlags & ~HideFlags.HideInHierarchy; // Never hide in hierarchy
+
+ TimelineUndo.RegisterCreatedObjectUndo(curves, "Create Curves");
+
+ return curves;
+ }
+
+ public static bool ValidateParentTrack(TrackAsset parent, Type childType)
+ {
+ if (childType == null || !typeof(TrackAsset).IsAssignableFrom(childType))
+ return false;
+
+ // no parent is valid for any type
+ if (parent == null)
+ return true;
+
+ // A track supports layers if it implements ILayerable. Only supported for parents that are
+ // the same exact type as the child class, and 1 level of nesting only
+ if (parent is ILayerable && !parent.isSubTrack && parent.GetType() == childType)
+ return true;
+
+ var attr = Attribute.GetCustomAttribute(parent.GetType(), typeof(SupportsChildTracksAttribute)) as SupportsChildTracksAttribute;
+ if (attr == null)
+ return false;
+
+ // group track case, accepts all
+ if (attr.childType == null)
+ return true;
+
+ // specific case. Specifies nesting level
+ if (childType == attr.childType)
+ {
+ int nestCount = 0;
+ var p = parent;
+ while (p != null && p.isSubTrack)
+ {
+ nestCount++;
+ p = p.parent as TrackAsset;
+ }
+
+ return nestCount < attr.levels;
+ }
+ return false;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta
new file mode 100644
index 0000000..f81aa91
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 40cb137d0e9816e48a4141ed13afedad
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs
new file mode 100644
index 0000000..b6392f0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using UnityEngine.Playables;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace UnityEngine.Timeline
+{
+ static class TimelineUndo
+ {
+ public static void PushDestroyUndo(TimelineAsset timeline, Object thingToDirty, Object objectToDestroy, string operation)
+ {
+#if UNITY_EDITOR
+ if (objectToDestroy == null || !DisableUndoGuard.enableUndo)
+ return;
+
+ if (thingToDirty != null)
+ EditorUtility.SetDirty(thingToDirty);
+
+ if (timeline != null)
+ EditorUtility.SetDirty(timeline);
+
+ Undo.DestroyObjectImmediate(objectToDestroy);
+#else
+ if (objectToDestroy != null)
+ Object.Destroy(objectToDestroy);
+#endif
+ }
+
+ [Conditional("UNITY_EDITOR")]
+ public static void PushUndo(Object thingToDirty, string operation)
+ {
+#if UNITY_EDITOR
+ if (thingToDirty != null && DisableUndoGuard.enableUndo)
+ {
+ var track = thingToDirty as TrackAsset;
+ if (track != null)
+ track.MarkDirty();
+
+ EditorUtility.SetDirty(thingToDirty);
+ Undo.RegisterCompleteObjectUndo(thingToDirty, "Timeline " + operation);
+ }
+#endif
+ }
+
+ [Conditional("UNITY_EDITOR")]
+ public static void RegisterCreatedObjectUndo(Object thingCreated, string operation)
+ {
+#if UNITY_EDITOR
+ if (DisableUndoGuard.enableUndo)
+ {
+ Undo.RegisterCreatedObjectUndo(thingCreated, "Timeline " + operation);
+ }
+#endif
+ }
+
+#if UNITY_EDITOR
+ public struct DisableUndoGuard : IDisposable
+ {
+ internal static bool enableUndo = true;
+ static readonly Stack<bool> m_UndoStateStack = new Stack<bool>();
+ bool m_Disposed;
+ public DisableUndoGuard(bool disable)
+ {
+ m_Disposed = false;
+ m_UndoStateStack.Push(enableUndo);
+ enableUndo = !disable;
+ }
+
+ public void Dispose()
+ {
+ if (!m_Disposed)
+ {
+ if (m_UndoStateStack.Count == 0)
+ {
+ Debug.LogError("UnMatched DisableUndoGuard calls");
+ enableUndo = true;
+ return;
+ }
+ enableUndo = m_UndoStateStack.Pop();
+ m_Disposed = true;
+ }
+ }
+ }
+#endif
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta
new file mode 100644
index 0000000..c62c751
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1f2a7e0d1b6bbba408a41e206945c23c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs
new file mode 100644
index 0000000..22db909
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs
@@ -0,0 +1,30 @@
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ static class WeightUtility
+ {
+ // Given a mixer, normalizes the mixer if required
+ // returns the output weight that should be applied to the mixer as input
+ public static float NormalizeMixer(Playable mixer)
+ {
+ if (!mixer.IsValid())
+ return 0;
+ int count = mixer.GetInputCount();
+ float weight = 0.0f;
+ for (int c = 0; c < count; c++)
+ {
+ weight += mixer.GetInputWeight(c);
+ }
+
+ if (weight > Mathf.Epsilon && weight < 1)
+ {
+ for (int c = 0; c < count; c++)
+ {
+ mixer.SetInputWeight(c, mixer.GetInputWeight(c) / weight);
+ }
+ }
+ return Mathf.Clamp01(weight);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta
new file mode 100644
index 0000000..bf2c55d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e7a505b341283e14696e86433a5b1ae9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: