diff options
| author | Andrew Lee <alee14498@protonmail.com> | 2020-04-19 17:19:32 -0400 |
|---|---|---|
| committer | Andrew Lee <alee14498@protonmail.com> | 2020-04-19 17:19:32 -0400 |
| commit | c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 (patch) | |
| tree | ee4d51c7c1d633e11f46453ef1edd3c77c4ef9f7 /Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities | |
| download | Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.tar.gz Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.tar.bz2 Project-Sandbox-c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78.zip | |
Inital commit
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities')
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: |
