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/Editor/Utilities/KeyTraverser.cs | |
| 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/Editor/Utilities/KeyTraverser.cs')
| -rw-r--r-- | Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs new file mode 100644 index 0000000..2f64868 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Timeline; + +namespace UnityEditor.Timeline.Utilities +{ + class KeyTraverser + { + float[] m_KeyCache; + int m_DirtyStamp = -1; + int m_LastHash = -1; + readonly TimelineAsset m_Asset; + readonly float m_Epsilon; + int m_LastIndex = -1; + + public int lastIndex + { + get { return m_LastIndex; } + } + + public static IEnumerable<float> GetClipKeyTimes(TimelineClip clip) + { + if (clip == null || clip.animationClip == null || clip.animationClip.empty) + return new float[0]; + + return AnimationClipCurveCache.Instance.GetCurveInfo(clip.animationClip).keyTimes. + Select(k => (float)clip.FromLocalTimeUnbound(k)). // convert to sequence time + Where(k => k >= clip.start && k <= clip.end); // remove non visible keys + } + + public static IEnumerable<float> GetTrackKeyTimes(AnimationTrack track) + { + if (track != null) + { + if (track.inClipMode) + return track.clips.Where(c => c.recordable). + SelectMany(x => GetClipKeyTimes(x)); + if (track.infiniteClip != null && !track.infiniteClip.empty) + return AnimationClipCurveCache.Instance.GetCurveInfo(track.infiniteClip).keyTimes; + } + return new float[0]; + } + + static int CalcAnimClipHash(TrackAsset asset) + { + int hash = 0; + if (asset != null) + { + AnimationTrack animTrack = asset as AnimationTrack; + if (animTrack != null) + { + for (var i = 0; i != animTrack.clips.Length; ++i) + { + hash ^= (animTrack.clips[i]).Hash(); + } + } + foreach (var subTrack in asset.GetChildTracks()) + { + if (subTrack != null) + hash ^= CalcAnimClipHash(subTrack); + } + } + return hash; + } + + internal static int CalcAnimClipHash(TimelineAsset asset) + { + int hash = 0; + foreach (var t in asset.GetRootTracks()) + { + if (t != null) + hash ^= CalcAnimClipHash(t); + } + return hash; + } + + void RebuildKeyCache() + { + m_KeyCache = m_Asset.flattenedTracks.Where(x => (x as AnimationTrack) != null) + .Cast<AnimationTrack>() + .SelectMany(t => GetTrackKeyTimes(t)). + OrderBy(x => x).ToArray(); + + if (m_KeyCache.Length > 0) + { + float[] unique = new float[m_KeyCache.Length]; + unique[0] = m_KeyCache[0]; + int index = 0; + for (int i = 1; i < m_KeyCache.Length; i++) + { + if (m_KeyCache[i] - unique[index] > m_Epsilon) + { + index++; + unique[index] = m_KeyCache[i]; + } + } + m_KeyCache = unique; + Array.Resize(ref m_KeyCache, index + 1); + } + } + + public KeyTraverser(TimelineAsset timeline, float epsilon) + { + m_Asset = timeline; + m_Epsilon = epsilon; + } + + void CheckCache(int dirtyStamp) + { + int hash = CalcAnimClipHash(m_Asset); + if (dirtyStamp != m_DirtyStamp || hash != m_LastHash) + { + RebuildKeyCache(); + m_DirtyStamp = dirtyStamp; + m_LastHash = hash; + } + } + + public float GetNextKey(float key, int dirtyStamp) + { + CheckCache(dirtyStamp); + if (m_KeyCache.Length > 0) + { + if (key < m_KeyCache.Last() - m_Epsilon) + { + if (key > m_KeyCache[0] - m_Epsilon) + { + float t = key + m_Epsilon; + // binary search + int max = m_KeyCache.Length - 1; + int min = 0; + while (max - min > 1) + { + int imid = (min + max) / 2; + if (t > m_KeyCache[imid]) + min = imid; + else + max = imid; + } + m_LastIndex = max; + return m_KeyCache[max]; + } + + m_LastIndex = 0; + return m_KeyCache[0]; + } + if (key < m_KeyCache.Last() + m_Epsilon) + { + m_LastIndex = m_KeyCache.Length - 1; + return Mathf.Max(key, m_KeyCache.Last()); + } + } + m_LastIndex = -1; + return key; + } + + public float GetPrevKey(float key, int dirtyStamp) + { + CheckCache(dirtyStamp); + if (m_KeyCache.Length > 0) + { + if (key > m_KeyCache[0] + m_Epsilon) + { + if (key < m_KeyCache.Last() + m_Epsilon) + { + float t = key - m_Epsilon; + + // binary search + int max = m_KeyCache.Length - 1; + int min = 0; + while (max - min > 1) + { + int imid = (min + max) / 2; + if (t < m_KeyCache[imid]) + max = imid; + else + min = imid; + } + m_LastIndex = min; + return m_KeyCache[min]; + } + m_LastIndex = m_KeyCache.Length - 1; + return m_KeyCache.Last(); + } + if (key >= m_KeyCache[0] - m_Epsilon) + { + m_LastIndex = 0; + return Mathf.Min(key, m_KeyCache[0]); + } + } + m_LastIndex = -1; + return key; + } + + public int GetKeyCount(int dirtyStamp) + { + CheckCache(dirtyStamp); + return m_KeyCache.Length; + } + } +} |
