static void FixLoops(TimelineClip clip, bool completeLastLoop) { if (!TimelineHelpers.HasUsableAssetDuration(clip)) { return; } var loopDuration = TimelineHelpers.GetLoopDuration(clip); var firstLoopDuration = loopDuration - clip.clipIn * (1.0 / clip.timeScale); // Making sure we don't trim to zero if (!completeLastLoop && firstLoopDuration > clip.duration) { return; } var numLoops = (clip.duration - firstLoopDuration) / loopDuration; var numCompletedLoops = Math.Floor(numLoops); if (!(numCompletedLoops < numLoops)) { return; } if (completeLastLoop) { numCompletedLoops += 1; } var newEnd = clip.start + firstLoopDuration + loopDuration * numCompletedLoops; UndoExtensions.RegisterClip(clip, L10n.Tr("Trim Clip Last Loop")); TrimClipWithEditMode(clip, TrimEdge.End, newEnd); }
public static bool TrimStart(TimelineClip clip, double trimTime) { if (clip.asset == null) { return(false); } if (clip.start > trimTime) { return(false); } if (clip.end < trimTime) { return(false); } UndoExtensions.RegisterClip(clip, L10n.Tr("Trim Clip Start")); // Note: We are NOT using edit modes in this case because we want the same result // regardless of the selected EditMode: split at cursor and delete left part SetStart(clip, trimTime, false); clip.ConformEaseValues(); return(true); }
public static bool MatchContent(TimelineClip clip) { if (clip.asset == null) { return(false); } UndoExtensions.RegisterClip(clip, L10n.Tr("Match Clip Content")); var newStartCandidate = clip.start - clip.clipIn / clip.timeScale; var newStart = newStartCandidate < 0.0 ? 0.0 : newStartCandidate; TrimClipWithEditMode(clip, TrimEdge.Start, newStart); // In case resetting the start was blocked by edit mode or timeline start, we do the best we can clip.clipIn = (clip.start - newStartCandidate) * clip.timeScale; if (clip.clipAssetDuration > 0 && TimelineHelpers.HasUsableAssetDuration(clip)) { var duration = TimelineHelpers.GetLoopDuration(clip); var offset = (clip.clipIn / clip.timeScale) % duration; TrimClipWithEditMode(clip, TrimEdge.End, clip.start - offset + duration); } return(true); }
public static bool Split(IEnumerable <TimelineClip> clips, double splitTime, PlayableDirector director) { var result = false; foreach (var clip in clips) { if (clip.start >= splitTime) { continue; } if (clip.end <= splitTime) { continue; } UndoExtensions.RegisterClip(clip, L10n.Tr("Split Clip")); TimelineClip newClip = TimelineHelpers.Clone(clip, director, director, clip.start); clip.easeInDuration = 0; newClip.easeOutDuration = 0; SetStart(clip, splitTime, false); SetEnd(newClip, splitTime, false); // Sort produced by cloning clips on top of each other is unpredictable (it varies between mono runtimes) clip.GetParentTrack().SortClips(); result = true; } return(result); }
protected override bool MouseDrag(Event evt, WindowState state) { if (!m_IsCaptured) { return(false); } if (!m_UndoSaved) { var uiClip = m_EaseClipHandler.clipGUI; string undoName = m_Edges == ManipulateEdges.Left ? EaseInClipText : EaseOutClipText; UndoExtensions.RegisterClip(uiClip.clip, undoName); m_UndoSaved = true; } double d = state.PixelDeltaToDeltaTime(evt.delta.x); var duration = m_Clip.duration; var easeInDurationLimit = duration - m_Clip.easeOutDuration; var easeOutDurationLimit = duration - m_Clip.easeInDuration; if (m_Edges == ManipulateEdges.Left) { m_Clip.easeInDuration = Math.Min(easeInDurationLimit, Math.Max(0, m_Clip.easeInDuration + d)); } else if (m_Edges == ManipulateEdges.Right) { m_Clip.easeOutDuration = Math.Min(easeOutDurationLimit, Math.Max(0, m_Clip.easeOutDuration - d)); } RefreshOverlayStrings(m_EaseClipHandler, state); return(true); }
public static bool ResetSpeed(IEnumerable <TimelineClip> clips) { foreach (var clip in clips) { if (clip.timeScale != 1.0) { UndoExtensions.RegisterClip(clip, L10n.Tr("Reset Clip Speed")); clip.timeScale = 1.0; } } return(true); }
public static bool HalfSpeed(IEnumerable <TimelineClip> clips) { foreach (var clip in clips) { if (clip.SupportsSpeedMultiplier()) { UndoExtensions.RegisterClip(clip, L10n.Tr("Half Clip Speed")); clip.timeScale = clip.timeScale * 0.5f; } } return(true); }
public static bool DoubleSpeed(IEnumerable <TimelineClip> clips) { foreach (var clip in clips) { if (clip.SupportsSpeedMultiplier()) { UndoExtensions.RegisterClip(clip, "Double Clip Speed"); clip.timeScale = clip.timeScale * 2.0f; } } return(true); }
protected override bool MouseDrag(Event evt, WindowState state) { if (state.editSequence.isReadOnly) { return(false); } if (!m_IsCaptured) { return(false); } var uiClip = m_TrimClipHandler.clipGUI; if (!m_UndoSaved) { UndoExtensions.RegisterClip(uiClip.clip, "Trim Clip"); if (TimelineUtility.IsRecordableAnimationClip(uiClip.clip)) { TimelineUndo.PushUndo(uiClip.clip.animationClip, "Trim Clip"); } m_UndoSaved = true; } //Reset to original ease values. The trim operation will calculate the proper blend values. uiClip.clip.easeInDuration = m_OriginalEaseInDuration; uiClip.clip.easeOutDuration = m_OriginalEaseOutDuration; if (m_SnapEngine != null) { m_SnapEngine.Snap(evt.mousePosition, evt.modifiers); } RefreshOverlayStrings(m_TrimClipHandler, state); if (Selection.activeObject != null) { EditorUtility.SetDirty(Selection.activeObject); } // updates the duration of the graph without rebuilding state.UpdateRootPlayableDuration(state.editSequence.duration); return(true); }
public static bool ResetEditing(TimelineClip clip) { if (clip.asset == null) { return(false); } UndoExtensions.RegisterClip(clip, L10n.Tr("Reset Clip Editing")); clip.clipIn = 0.0; if (clip.clipAssetDuration < double.MaxValue) { var duration = clip.clipAssetDuration / clip.timeScale; TrimClipWithEditMode(clip, TrimEdge.End, clip.start + duration); } return(true); }
public static bool TrimEnd(TimelineClip clip, double trimTime) { if (clip.asset == null) { return(false); } if (clip.start > trimTime) { return(false); } if (clip.end < trimTime) { return(false); } UndoExtensions.RegisterClip(clip, L10n.Tr("Trim Clip End")); TrimClipWithEditMode(clip, TrimEdge.End, trimTime); return(true); }
public void PushUndo(string operation) { UndoExtensions.RegisterClip(m_Clip, operation); }