From c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Sun, 19 Apr 2020 17:19:32 -0400 Subject: Inital commit --- .../Editor/State/SequenceHierarchy.cs | 298 +++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/State/SequenceHierarchy.cs (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/State/SequenceHierarchy.cs') diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/State/SequenceHierarchy.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/State/SequenceHierarchy.cs new file mode 100644 index 0000000..08a73e6 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/State/SequenceHierarchy.cs @@ -0,0 +1,298 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Playables; +using UnityEngine.Timeline; + +namespace UnityEditor.Timeline +{ + class SequenceHierarchy : ScriptableObject + { + readonly List m_Sequences = new List(); + + WindowState m_WindowState; + + [SerializeField] + SequencePath m_SerializedPath; + + public ISequenceState masterSequence + { + get { return m_Sequences.FirstOrDefault(); } + } + + public ISequenceState editSequence + { + get { return m_Sequences.LastOrDefault(); } + } + + public int count + { + get { return m_Sequences.Count; } + } + + public IEnumerable allSequences + { + get { return m_Sequences; } + } + + public static SequenceHierarchy CreateInstance() + { + var hierarchy = ScriptableObject.CreateInstance(); + hierarchy.hideFlags = HideFlags.HideAndDontSave; + return hierarchy; + } + + public void Init(WindowState owner) + { + m_WindowState = owner; + } + + // This is called when performing Undo operations. + // It needs to be called here since some operations are not + // allowed (EditorUtility.InstanceIDToObject, for example) + // during the ISerializationCallbackReceiver methods. + void OnValidate() + { + if (m_SerializedPath == null || m_WindowState == null || m_WindowState.GetWindow() == null) + return; + + m_WindowState.SetCurrentSequencePath(m_SerializedPath, true); + } + + public void Add(TimelineAsset asset, PlayableDirector director, TimelineClip hostClip) + { + if (hostClip == null) + AddToCurrentUndoGroup(this); // Merge with selection undo + else + TimelineUndo.PushUndo(this, "Edit Sub-Timeline"); + + Add_Internal(asset, director, hostClip); + + UpdateSerializedPath(); + } + + public void Remove() + { + if (m_Sequences.Count == 0) return; + + TimelineUndo.PushUndo(this, "Go to Sub-Timeline"); + + Remove_Internal(); + + UpdateSerializedPath(); + } + + public ISequenceState GetStateAtIndex(int index) + { + return m_Sequences[index]; + } + + public void RemoveUntilCount(int expectedCount) + { + if (expectedCount < 0 || m_Sequences.Count <= expectedCount) return; + + TimelineUndo.PushUndo(this, "Go to Sub-Timeline"); + + RemoveUntilCount_Internal(expectedCount); + + UpdateSerializedPath(); + } + + public void Clear() + { + if (m_Sequences.Count == 0) return; + + AddToCurrentUndoGroup(this); + Clear_Internal(); + UpdateSerializedPath(); + } + + public SequencePath ToSequencePath() + { + var path = new SequencePath(); + + if (m_Sequences.Count == 0) + return path; + + var rootSequence = m_Sequences[0]; + var root = 0; + if (rootSequence.director != null && rootSequence.director.gameObject != null) + root = rootSequence.director.gameObject.GetInstanceID(); + else if (rootSequence.asset != null) + root = rootSequence.asset.GetInstanceID(); + + path.SetSelectionRoot(root); + + var resolver = rootSequence.director; + + if (m_Sequences.Count > 1) + { + for (int i = 1, n = m_Sequences.Count; i < n; ++i) + { + path.AddSubSequence(m_Sequences[i], resolver); + resolver = m_Sequences[i].director; + } + } + + return path; + } + + public bool NeedsUpdate(SequencePath path, bool forceRebuild) + { + return forceRebuild || !SequencePath.AreEqual(m_SerializedPath, path); + } + + public void FromSequencePath(SequencePath path, bool forceRebuild) + { + if (!NeedsUpdate(path, forceRebuild)) + return; + + Clear_Internal(); + + var rootObject = EditorUtility.InstanceIDToObject(path.selectionRoot); + if (rootObject == null) + { + UpdateSerializedPath(); + return; + } + + var candidateAsset = rootObject as TimelineAsset; + if (candidateAsset != null) + { + Add_Internal(candidateAsset, null, null); + UpdateSerializedPath(); + return; + } + + var candidateGameObject = rootObject as GameObject; + if (candidateGameObject == null) + { + UpdateSerializedPath(); + return; + } + + var director = TimelineUtility.GetDirectorComponentForGameObject(candidateGameObject); + var asset = TimelineUtility.GetTimelineAssetForDirectorComponent(director); + Add_Internal(asset, director, null); + + if (!path.subElements.Any()) + { + UpdateSerializedPath(); + return; + } + + List buildingBlocks; + if (ValidateSubElements(path.subElements, director, out buildingBlocks)) + { + foreach (var buildingBlock in buildingBlocks) + Add_Internal(buildingBlock.asset, buildingBlock.director, buildingBlock.hostClip); + } + + UpdateSerializedPath(); + } + + void Add_Internal(TimelineAsset asset, PlayableDirector director, TimelineClip hostClip) + { + if (hostClip == null) + Clear_Internal(); + + var parent = m_Sequences.Count > 0 ? editSequence : null; + m_Sequences.Add(new SequenceState(m_WindowState, asset, director, hostClip, (SequenceState)parent)); + } + + void Remove_Internal() + { + m_Sequences.Last().Dispose(); + m_Sequences.RemoveAt(m_Sequences.Count - 1); + } + + void RemoveUntilCount_Internal(int expectedCount) + { + while (m_Sequences.Count > expectedCount) + { + Remove_Internal(); + } + } + + void Clear_Internal() + { + RemoveUntilCount_Internal(0); + } + + void UpdateSerializedPath() + { + m_SerializedPath = ToSequencePath(); + } + + static bool ValidateSubElements(List subElements, PlayableDirector director, out List buildingBlocks) + { + buildingBlocks = new List(subElements.Count); + var currentDirector = director; + + foreach (var element in subElements) + { + var timeline = currentDirector.playableAsset as TimelineAsset; + if (timeline == null) + return false; + if (timeline.trackObjects == null) + return false; + + var track = timeline.GetOutputTracks().FirstOrDefault(t => t.GetInstanceID() == element.trackInstanceID); + if (track == null) + return false; + if (track.Hash() != element.trackHash) + return false; + if (track.clips == null) + return false; + if (track.clips.Length <= element.clipIndex) + return false; + + var clip = track.clips[element.clipIndex]; + if (clip == null) + return false; + if (clip.Hash() != element.clipHash) + return false; + + var candidateDirectors = TimelineUtility.GetSubTimelines(clip, director); + + if (element.subDirectorIndex < 0 || element.subDirectorIndex >= candidateDirectors.Count) + return false; + + var candidateDirector = candidateDirectors[element.subDirectorIndex]; + + if (candidateDirector == null || !(candidateDirector.playableAsset is TimelineAsset)) + return false; + + currentDirector = candidateDirector; + + buildingBlocks.Add( + new SequenceBuildingBlock + { + asset = currentDirector.playableAsset as TimelineAsset, + director = currentDirector, + hostClip = clip + }); + } + + return true; + } + + struct SequenceBuildingBlock + { + public TimelineAsset asset; + public PlayableDirector director; + public TimelineClip hostClip; + } + + static void AddToCurrentUndoGroup(Object target) + { + if (target == null) return; + + var group = Undo.GetCurrentGroup(); + var groupName = Undo.GetCurrentGroupName(); + EditorUtility.SetDirty(target); + Undo.RegisterCompleteObjectUndo(target, groupName); + Undo.CollapseUndoOperations(group); + } + } +} -- cgit v1.2.3