summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Animation/AnimationClipCurveCache.cs
diff options
context:
space:
mode:
authorAndrew Lee <alee14498@protonmail.com>2020-04-19 17:19:32 -0400
committerAndrew Lee <alee14498@protonmail.com>2020-04-19 17:19:32 -0400
commitc55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 (patch)
treeee4d51c7c1d633e11f46453ef1edd3c77c4ef9f7 /Library/PackageCache/com.unity.timeline@1.2.13/Editor/Animation/AnimationClipCurveCache.cs
downloadProject-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/Editor/Animation/AnimationClipCurveCache.cs')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Animation/AnimationClipCurveCache.cs436
1 files changed, 436 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Animation/AnimationClipCurveCache.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Animation/AnimationClipCurveCache.cs
new file mode 100644
index 0000000..8570a73
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Animation/AnimationClipCurveCache.cs
@@ -0,0 +1,436 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEditor;
+using UnityEditorInternal;
+
+namespace UnityEditor.Timeline
+{
+ struct CurveBindingPair
+ {
+ public EditorCurveBinding binding;
+ public AnimationCurve curve;
+ public ObjectReferenceKeyframe[] objectCurve;
+ }
+
+ class CurveBindingGroup
+ {
+ public CurveBindingPair[] curveBindingPairs { get; set; }
+ public Vector2 timeRange { get; set; }
+ public Vector2 valueRange { get; set; }
+
+ public bool isFloatCurve
+ {
+ get
+ {
+ return curveBindingPairs != null && curveBindingPairs.Length > 0 &&
+ curveBindingPairs[0].curve != null;
+ }
+ }
+
+ public bool isObjectCurve
+ {
+ get
+ {
+ return curveBindingPairs != null && curveBindingPairs.Length > 0 &&
+ curveBindingPairs[0].objectCurve != null;
+ }
+ }
+
+ public int count
+ {
+ get
+ {
+ if (curveBindingPairs == null)
+ return 0;
+ return curveBindingPairs.Length;
+ }
+ }
+ }
+
+ class AnimationClipCurveInfo
+ {
+ bool m_CurveDirty = true;
+ bool m_KeysDirty = true;
+
+ public bool dirty
+ {
+ get { return m_CurveDirty; }
+ set
+ {
+ m_CurveDirty = value;
+ if (m_CurveDirty)
+ {
+ m_KeysDirty = true;
+ if (m_groupings != null)
+ m_groupings.Clear();
+ }
+ }
+ }
+
+ public AnimationCurve[] curves;
+ public EditorCurveBinding[] bindings;
+
+ public EditorCurveBinding[] objectBindings;
+ public List<ObjectReferenceKeyframe[]> objectCurves;
+
+ Dictionary<string, CurveBindingGroup> m_groupings;
+
+ // to tell whether the cache has changed
+ public int version { get; private set; }
+
+ float[] m_KeyTimes;
+
+ Dictionary<EditorCurveBinding, float[]> m_individualBindinsKey;
+
+ public float[] keyTimes
+ {
+ get
+ {
+ if (m_KeysDirty || m_KeyTimes == null)
+ {
+ RebuildKeyCache();
+ }
+ return m_KeyTimes;
+ }
+ }
+
+ public float[] GetCurveTimes(EditorCurveBinding curve)
+ {
+ return GetCurveTimes(new[] { curve });
+ }
+
+ public float[] GetCurveTimes(EditorCurveBinding[] curves)
+ {
+ if (m_KeysDirty || m_KeyTimes == null)
+ {
+ RebuildKeyCache();
+ }
+
+ var keyTimes = new List<float>();
+ for (int i = 0; i < curves.Length; i++)
+ {
+ var c = curves[i];
+ if (m_individualBindinsKey.ContainsKey(c))
+ {
+ keyTimes.AddRange(m_individualBindinsKey[c]);
+ }
+ }
+ return keyTimes.ToArray();
+ }
+
+ void RebuildKeyCache()
+ {
+ m_individualBindinsKey = new Dictionary<EditorCurveBinding, float[]>();
+
+ List<float> keys = curves.SelectMany(y => y.keys).Select(z => z.time).ToList();
+ for (int i = 0; i < objectCurves.Count; i++)
+ {
+ var kf = objectCurves[i];
+ keys.AddRange(kf.Select(x => x.time));
+ }
+
+ for (int b = 0; b < bindings.Count(); b++)
+ {
+ m_individualBindinsKey.Add(bindings[b], curves[b].keys.Select(k => k.time).Distinct().ToArray());
+ }
+
+ m_KeyTimes = keys.OrderBy(x => x).Distinct().ToArray();
+ m_KeysDirty = false;
+ }
+
+ public void Update(AnimationClip clip)
+ {
+ List<EditorCurveBinding> postfilter = new List<EditorCurveBinding>();
+ var clipBindings = AnimationUtility.GetCurveBindings(clip);
+ for (int i = 0; i < clipBindings.Length; i++)
+ {
+ var bind = clipBindings[i];
+ if (!bind.propertyName.Contains("LocalRotation.w"))
+ postfilter.Add(RotationCurveInterpolation.RemapAnimationBindingForRotationCurves(bind, clip));
+ }
+ bindings = postfilter.ToArray();
+
+ curves = new AnimationCurve[bindings.Length];
+ for (int i = 0; i < bindings.Length; i++)
+ {
+ curves[i] = AnimationUtility.GetEditorCurve(clip, bindings[i]);
+ }
+
+ objectBindings = AnimationUtility.GetObjectReferenceCurveBindings(clip);
+ objectCurves = new List<ObjectReferenceKeyframe[]>(objectBindings.Length);
+ for (int i = 0; i < objectBindings.Length; i++)
+ {
+ objectCurves.Add(AnimationUtility.GetObjectReferenceCurve(clip, objectBindings[i]));
+ }
+
+ m_CurveDirty = false;
+ m_KeysDirty = true;
+
+ version = version + 1;
+ }
+
+ public bool GetBindingForCurve(AnimationCurve curve, ref EditorCurveBinding binding)
+ {
+ for (int i = 0; i < curves.Length; i++)
+ {
+ if (curve == curves[i])
+ {
+ binding = bindings[i];
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public AnimationCurve GetCurveForBinding(EditorCurveBinding binding)
+ {
+ for (int i = 0; i < curves.Length; i++)
+ {
+ if (binding.Equals(bindings[i]))
+ {
+ return curves[i];
+ }
+ }
+ return null;
+ }
+
+ public ObjectReferenceKeyframe[] GetObjectCurveForBinding(EditorCurveBinding binding)
+ {
+ if (objectCurves == null)
+ return null;
+
+ for (int i = 0; i < objectCurves.Count; i++)
+ {
+ if (binding.Equals(objectBindings[i]))
+ {
+ return objectCurves[i];
+ }
+ }
+ return null;
+ }
+
+ // given a groupID, get the list of curve bindings
+ public CurveBindingGroup GetGroupBinding(string groupID)
+ {
+ if (m_groupings == null)
+ m_groupings = new Dictionary<string, CurveBindingGroup>();
+
+ CurveBindingGroup result = null;
+ if (!m_groupings.TryGetValue(groupID, out result))
+ {
+ result = new CurveBindingGroup();
+ result.timeRange = new Vector2(float.MaxValue, float.MinValue);
+ result.valueRange = new Vector2(float.MaxValue, float.MinValue);
+ List<CurveBindingPair> found = new List<CurveBindingPair>();
+ for (int i = 0; i < bindings.Length; i++)
+ {
+ if (bindings[i].GetGroupID() == groupID)
+ {
+ CurveBindingPair pair = new CurveBindingPair();
+ pair.binding = bindings[i];
+ pair.curve = curves[i];
+ found.Add(pair);
+
+ for (int k = 0; k < curves[i].keys.Length; k++)
+ {
+ var key = curves[i].keys[k];
+ result.timeRange = new Vector2(Mathf.Min(key.time, result.timeRange.x), Mathf.Max(key.time, result.timeRange.y));
+ result.valueRange = new Vector2(Mathf.Min(key.value, result.valueRange.x), Mathf.Max(key.value, result.valueRange.y));
+ }
+ }
+ }
+ for (int i = 0; i < objectBindings.Length; i++)
+ {
+ if (objectBindings[i].GetGroupID() == groupID)
+ {
+ CurveBindingPair pair = new CurveBindingPair();
+ pair.binding = objectBindings[i];
+ pair.objectCurve = objectCurves[i];
+ found.Add(pair);
+
+ for (int k = 0; k < objectCurves[i].Length; k++)
+ {
+ var key = objectCurves[i][k];
+ result.timeRange = new Vector2(Mathf.Min(key.time, result.timeRange.x), Mathf.Max(key.time, result.timeRange.y));
+ }
+ }
+ }
+
+ result.curveBindingPairs = found.OrderBy(x => AnimationWindowUtility.GetComponentIndex(x.binding.propertyName)).ToArray();
+
+ m_groupings.Add(groupID, result);
+ }
+ return result;
+ }
+ }
+
+ // Cache for storing the animation clip data
+ class AnimationClipCurveCache
+ {
+ static AnimationClipCurveCache s_Instance;
+ Dictionary<AnimationClip, AnimationClipCurveInfo> m_ClipCache = new Dictionary<AnimationClip, AnimationClipCurveInfo>();
+ bool m_IsEnabled;
+
+
+ public static AnimationClipCurveCache Instance
+ {
+ get
+ {
+ if (s_Instance == null)
+ {
+ s_Instance = new AnimationClipCurveCache();
+ }
+
+ return s_Instance;
+ }
+ }
+
+ public void OnEnable()
+ {
+ if (!m_IsEnabled)
+ {
+ AnimationUtility.onCurveWasModified += OnCurveWasModified;
+ m_IsEnabled = true;
+ }
+ }
+
+ public void OnDisable()
+ {
+ if (m_IsEnabled)
+ {
+ AnimationUtility.onCurveWasModified -= OnCurveWasModified;
+ m_IsEnabled = false;
+ }
+ }
+
+ // callback when a curve is edited. Force the cache to update next time it's accessed
+ void OnCurveWasModified(AnimationClip clip, EditorCurveBinding binding, AnimationUtility.CurveModifiedType modification)
+ {
+ if (modification == AnimationUtility.CurveModifiedType.CurveDeleted)
+ {
+ m_ClipCache.Remove(clip);
+ }
+ else
+ {
+ AnimationClipCurveInfo data;
+ if (m_ClipCache.TryGetValue(clip, out data))
+ {
+ data.dirty = true;
+ }
+ }
+ }
+
+ public AnimationClipCurveInfo GetCurveInfo(AnimationClip clip)
+ {
+ AnimationClipCurveInfo data;
+ if (clip == null)
+ return null;
+ if (!m_ClipCache.TryGetValue(clip, out data))
+ {
+ data = new AnimationClipCurveInfo();
+ data.dirty = true;
+ m_ClipCache[clip] = data;
+ }
+ if (data.dirty)
+ {
+ data.Update(clip);
+ }
+ return data;
+ }
+
+ public void ClearCachedProxyClips()
+ {
+ var toRemove = new List<AnimationClip>();
+ foreach (var entry in m_ClipCache)
+ {
+ var clip = entry.Key;
+ if (clip != null && (clip.hideFlags & HideFlags.HideAndDontSave) == HideFlags.HideAndDontSave)
+ toRemove.Add(clip);
+ }
+
+ foreach (var clip in toRemove)
+ {
+ m_ClipCache.Remove(clip);
+ Object.DestroyImmediate(clip, true);
+ }
+ }
+
+
+ public void Clear()
+ {
+ ClearCachedProxyClips();
+ m_ClipCache.Clear();
+ }
+
+ }
+
+ static class EditorCurveBindingExtension
+ {
+ // identifier to generate an id thats the same for all curves in the same group
+ public static string GetGroupID(this EditorCurveBinding binding)
+ {
+ return binding.type + AnimationWindowUtility.GetPropertyGroupName(binding.propertyName);
+ }
+ }
+
+
+ static class CurveBindingGroupExtensions
+ {
+ // Extentions to determine curve types
+ public static bool IsEnableGroup(this CurveBindingGroup curves)
+ {
+ return curves.isFloatCurve && curves.count == 1 && curves.curveBindingPairs[0].binding.propertyName == "m_Enabled";
+ }
+
+ public static bool IsVectorGroup(this CurveBindingGroup curves)
+ {
+ if (!curves.isFloatCurve)
+ return false;
+ if (curves.count <= 1 || curves.count > 4)
+ return false;
+ char l = curves.curveBindingPairs[0].binding.propertyName.Last();
+ return l == 'x' || l == 'y' || l == 'z' || l == 'w';
+ }
+
+ public static bool IsColorGroup(this CurveBindingGroup curves)
+ {
+ if (!curves.isFloatCurve)
+ return false;
+ if (curves.count != 3 && curves.count != 4)
+ return false;
+ char l = curves.curveBindingPairs[0].binding.propertyName.Last();
+ return l == 'r' || l == 'g' || l == 'b' || l == 'a';
+ }
+
+ public static string GetDescription(this CurveBindingGroup group, float t)
+ {
+ string result = string.Empty;
+ if (group.isFloatCurve)
+ {
+ if (group.count > 1)
+ {
+ result += "(" + group.curveBindingPairs[0].curve.Evaluate(t).ToString("0.##");
+ for (int j = 1; j < group.curveBindingPairs.Length; j++)
+ {
+ result += "," + group.curveBindingPairs[j].curve.Evaluate(t).ToString("0.##");
+ }
+ result += ")";
+ }
+ else
+ {
+ result = group.curveBindingPairs[0].curve.Evaluate(t).ToString("0.##");
+ }
+ }
+ else if (group.isObjectCurve)
+ {
+ Object obj = null;
+ if (group.curveBindingPairs[0].objectCurve.Length > 0)
+ obj = CurveEditUtility.Evaluate(group.curveBindingPairs[0].objectCurve, t);
+ result = (obj == null ? "None" : obj.name);
+ }
+
+ return result;
+ }
+ }
+}