SW 중심대학 OSS GIT 서버
박건태, 이승준, 고기완, 이준호
새로운 배포
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
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; } }}
|