void OnDisable() { Clear(); if (target is TimelineSelectionContainer selectionContainer) { selectionContainer.AnnotationsChanged -= Refresh; if (selectionContainer != null) { TaggedAnimationClip clip = selectionContainer.Clip; if (clip != null) { Asset asset = clip.Asset; if (asset != null) { asset.BuildStarted -= BuildStarted; asset.BuildStopped -= BuildStopped; } } } } if (m_Root != null) { EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; } }
public TimeIndex RetrieveDebugTimeIndex(ref Binary binary) { if (Debugger.instance.rewind) { TaggedAnimationClip taggedClip = m_Timeline.TaggedClip; if (taggedClip != null) { float sampleTimeInSeconds = m_Timeline.DebugTime; if (sampleTimeInSeconds >= 0.0f) { AnimationSampleTime animSampleTime = new AnimationSampleTime() { clip = taggedClip, sampleTimeInSeconds = sampleTimeInSeconds }; return(animSampleTime.GetTimeIndex(ref binary)); } } } return(TimeIndex.Invalid); }
IntervalTree <MetricRange> BuildIntervalTree(TaggedAnimationClip clip) { List <TagAnnotation> tags = clip.Tags; Profiler.BeginSample("MetricsTrack.BuildIntervalTree"); IntervalTree <MetricRange> intervalTree = new IntervalTree <MetricRange>(); for (var i = 0; i < tags.Count; i++) { var tag = tags[i]; int metricIndex = clip.GetMetricIndexCoveringTimeOnTag(tag); if (metricIndex < 0 || metricIndex >= TargetAsset.Metrics.Count) { continue; } string metricName = TargetAsset.GetMetric(metricIndex).name; intervalTree.Add(new MetricRange { intervalStart = tag.startTime, intervalEnd = tag.EndTime, name = metricName, priority = i }); } Profiler.EndSample(); return(intervalTree); }
public override void SetClip(TaggedAnimationClip taggedClip) { if (m_TaggedClip != null) { m_TaggedClip.MarkerAdded -= OnMarkerAdded; m_TaggedClip.MarkerRemoved -= OnMarkerRemoved; } List <MarkerElement> markers = GetMarkerElements().ToList(); foreach (MarkerElement markerElement in markers) { markerElement.MarkerElementDragged -= OnMarkerElementDragged; markerElement.Selected -= OnMarkerSelected; markerElement.RemoveFromHierarchy(); } base.SetClip(taggedClip); if (m_TaggedClip != null) { m_TaggedClip.MarkerAdded += OnMarkerAdded; m_TaggedClip.MarkerRemoved += OnMarkerRemoved; } ReloadElements(); }
public void Reposition(bool notify) { TaggedAnimationClip clip = m_Track.Clip; if (clip == null) { return; } float leftBefore = style.left.value.value; float timeLeftValue = Timeline.TimeToLocalPos(value, m_Track); style.left = timeLeftValue; if (m_TimelineGuideline == null) { SetupTimelineGuideline(); } m_TimelineGuideline.style.left = timeLeftValue; if (notify && !FloatComparer.s_ComparerWithDefaultTolerance.Equals(leftBefore, timeLeftValue)) { MarkerElementDragged?.Invoke(this, m_PreviousTime, value, leftBefore, timeLeftValue); m_PreviousTime = value; } }
void SetPostBoundaryClip(TaggedAnimationClip boundary) { if (m_TaggedClip != null && m_TaggedClip.TaggedPostBoundaryClip != boundary) { m_TaggedClip.TaggedPostBoundaryClip = boundary; m_Owner.PreviewActiveTime(); } }
public void SetClip(TaggedAnimationClip taggedClip, bool updateTimeRange = true) { ClearSelection(); m_ClipLengthBar.style.display = DisplayStyle.None; m_ActiveTimeField.SetEnabled(false); TaggedClip = taggedClip; foreach (var tt in m_TrackElements) { tt.SetClip(TaggedClip); } if (TaggedClip == null || TargetAsset == null) { SetFPSLabelText(); m_TimeRuler.SetIMGUIVisible(false); m_ClipArea.style.visibility = Visibility.Hidden; m_ActiveTick.style.visibility = Visibility.Hidden; return; } m_TimeRuler.SetIMGUIVisible(true); m_ActiveTick.style.visibility = Visibility.Visible; m_ClipArea.style.visibility = Visibility.Visible; TaggedClip.MarkerAdded += ShowMarkerTrack; TaggedClip.DataChanged += AdjustTagBackgrounds; if (updateTimeRange) { UpdateTimeRange(); } SelectionContainer.Select(TaggedClip); // display specific information from the clip in the inspector, like the retarget source avatar, even if no tags/markers have been selected yet Selection.activeObject = SelectionContainer; if (!TaggedClip.Valid) { SetFPSLabelText(); return; } PreviewActiveTime(); SetFPSLabelText(); AdjustTicks(); m_ClipLengthBar.style.display = DisplayStyle.Flex; m_ActiveTimeField.SetEnabled(true); ResetTimeRuler(); }
public bool Unselect(TaggedAnimationClip clip) { if (Selection.Remove(clip)) { SelectionChanged?.Invoke(); return(true); } return(false); }
public TagElement(Track track, TaggedAnimationClip clip, TagAnnotation tag) : base(track) { m_Tag = tag; focusable = true; AddToClassList("clipTagRoot"); m_ManipulateStartLabel = new Label(); m_ManipulateStartLabel.AddToClassList("tagManipulateStartLabel"); m_ManipulateStartLabel.AddToClassList("tagManipulateLabel"); m_ManipulateEndLabel = new Label(); m_ManipulateEndLabel.AddToClassList("tagManipulateEndLabel"); m_ManipulateEndLabel.AddToClassList("tagManipulateLabel"); m_BackgroundColor = AnnotationAttribute.GetColor(m_Tag.Type); var background = m_BackgroundColor; background.r *= k_BackgroundAlpha; background.g *= k_BackgroundAlpha; background.b *= k_BackgroundAlpha; style.backgroundColor = background; int hash = new Random(m_Tag.payload.GetHashedData()).Next(); Color colorFromValueHash = ColorUtility.FromHtmlString("#" + Convert.ToString(hash, 16)); Color borderColor = background; borderColor.r = (borderColor.r + colorFromValueHash.r) / 2; borderColor.g = (borderColor.g + colorFromValueHash.g) / 2; borderColor.b = (borderColor.b + colorFromValueHash.b) / 2; style.borderLeftColor = borderColor; style.borderBottomColor = borderColor; style.borderRightColor = borderColor; VisualElement startHandle = CreateHandle(TagManipulator.Mode.StartTime); startHandle.style.left = -4; Insert(0, startHandle); startHandle.Add(m_ManipulateStartLabel); m_LabelContainer.AddManipulator(new TagManipulator(this, TagManipulator.Mode.Body)); m_Label.text = string.IsNullOrEmpty(m_Tag.name) ? m_Tag.Name : m_Tag.name; VisualElement endHandle = CreateHandle(TagManipulator.Mode.Duration); endHandle.style.left = 4; Add(endHandle); endHandle.Add(m_ManipulateEndLabel); var contextMenuManipulator = new ContextualMenuManipulator(OpenTagRemoveMenu); this.AddManipulator(contextMenuManipulator); RegisterCallback <AttachToPanelEvent>(OnAttachToPanel); }
public Segment(TaggedAnimationClip clip, Asset asset, float startTime, float endTime) { this.clip = clip; this.asset = asset; this.startTime = startTime; this.endTime = endTime; tags = new List <TagInterval>(); tags.Add(new TagInterval() { firstFrame = FirstFrame, lastFrame = LastFrame }); }
public void SelectItem(TaggedAnimationClip obj) { if (itemsSource == null) { return; } int index = itemsSource.IndexOf(obj); if (index >= 0) { SetSelection(index); } }
public virtual void SetClip(TaggedAnimationClip clip) { if (m_TaggedClip != null) { m_TaggedClip.DataChanged -= ReloadElements; } m_TaggedClip = clip; if (m_TaggedClip != null) { m_TaggedClip.DataChanged += ReloadElements; } }
protected override void OnMouseMoveEvent(MouseMoveEvent evt) { if (!m_Active || !target.HasMouseCapture() || EditorApplication.isPlaying) { return; } Timeline timeline = MarkerElement.Timeline; Asset asset = timeline.TargetAsset; TaggedAnimationClip clip = timeline.TaggedClip; if (m_StartingDrag) { Undo.RecordObject(asset, "Moving marker"); m_StartingDrag = false; } Vector2 position = evt.mousePosition; MouseDirection direction = GetMouseDirection(position); m_MousePreviousPosition = position; float framerate = clip.SampleRate; float dragPosition = position.x; if (m_Target.SnapValid(dragPosition)) { return; } bool canPreview = m_Target.Timeline.CanPreview(); TryToSnap(dragPosition, direction, framerate, out float newTime, snapToPlayhead: !canPreview); if (!FloatComparer.s_ComparerWithDefaultTolerance.Equals(MarkerElement.value, newTime)) { m_MarkerDragged = true; MarkerElement.value = newTime; MarkerElement.ShowManipulationLabel(); if (canPreview) { m_Target.Timeline.SetActiveTime(newTime); } } evt.StopPropagation(); }
public bool Select(TaggedAnimationClip clip, bool notify = true) { if (!Selection.Contains(clip)) { Selection.Add(clip); if (notify) { SelectionChanged?.Invoke(); } return(true); } return(false); }
public override void SetClip(TaggedAnimationClip taggedClip) { base.SetClip(taggedClip); if (m_TaggedClip != null) { this.AddManipulator(m_TracksContextManipulator); } else { this.RemoveManipulator(m_TracksContextManipulator); } ReloadElements(); }
List <Segment> ComputeSegments(TaggedAnimationClip clip, Asset asset) { List <Segment> segments = new List <Segment>(); foreach (TagAnnotation tag in clip.Tags) { if (clip.GetMetricIndexCoveringTimeOnTag(tag) < 0) { continue; } segments.Add(new Segment ( clip, asset, Mathf.Max(0.0f, tag.startTime), Mathf.Min(clip.DurationInSeconds, tag.EndTime) ) ); } segments.Sort((x, y) => x.startTime.CompareTo(y.startTime)); // merge overlapping segments for (int i = 0; i < segments.Count - 1;) { if (segments[i + 1].startTime > segments[i].endTime) { ++i; continue; } segments[i] = new Segment { clip = clip, asset = asset, startTime = segments[i].startTime, endTime = Mathf.Max(segments[i].endTime, segments[i + 1].endTime), tags = segments[i].tags }; segments[i].tags.AddRange(segments[i + 1].tags); segments.RemoveAt(i + 1); } return(segments); }
public override void SetClip(TaggedAnimationClip taggedClip) { base.SetClip(taggedClip); if (m_TaggedClip != null) { m_PreBoundaryClipElement.style.display = DisplayStyle.Flex; m_PostBoundaryClipElement.style.display = DisplayStyle.Flex; } else { m_PreBoundaryClipElement.style.display = DisplayStyle.None; m_PostBoundaryClipElement.style.display = DisplayStyle.None; } UpdateBoundaryClips(); }
public override void ShowManipulationLabel() { TaggedAnimationClip clip = Track.Clip; float sampleRate = clip.SampleRate; string start = TimelineUtility.GetTimeString(Timeline.ViewMode, m_Tag.startTime, (int)sampleRate); m_ManipulateStartLabel.text = start; string end = TimelineUtility.GetTimeString(Timeline.ViewMode, m_Tag.EndTime, (int)sampleRate); float estimatedTextSize = TimelineUtility.EstimateTextSize(m_ManipulateStartLabel); float controlWidth = Math.Max(float.IsNaN(estimatedTextSize) ? m_ManipulateStartLabel.layout.width : estimatedTextSize, 8) + 6; m_ManipulateStartLabel.style.left = -controlWidth; m_ManipulateEndLabel.text = end; m_ManipulateStartLabel.style.visibility = Visibility.Visible; m_ManipulateEndLabel.style.visibility = Visibility.Visible; }
void OnClipReimport() { TaggedAnimationClip importedClip = clip; float currentTime = previousTime; ResetAnimationSampler(); if (!InitAnimationSampler(importedClip)) { return; } if (currentTime >= 0.0f) { SamplePose(currentTime); EnableDisplayTrajectory(); } }
static List <Segment> GenerateSegments(Asset asset, TaggedAnimationClip animationClip) { var segments = new List <Segment>(); var tags = animationClip.Tags.ToList(); tags.Sort((x, y) => x.startTime.CompareTo(y.startTime)); foreach (TagAnnotation tag in tags) { float startTime = math.max(0.0f, tag.startTime); float endTime = math.min(animationClip.DurationInSeconds, tag.EndTime); float duration = endTime - startTime; if (duration <= 0.0f) { Debug.LogWarning($"One '{tag.Name}' tag is laying entirely outside of '{animationClip.ClipName}' clip range, it will therefore be ignored. (Tag starting at {tag.startTime:0.00} seconds, whose duration is {tag.duration:0.00} seconds)."); continue; } int firstFrame = animationClip.ClampedTimeInSecondsToIndex(startTime); int numFrames = animationClip.ClampedDurationInSecondsToFrames(duration); int onePastLastFrame = math.min(firstFrame + numFrames, animationClip.NumFrames); var interval = new Interval(firstFrame, onePastLastFrame); var segment = new Segment { clip = animationClip, source = interval, destination = Interval.Empty }; segment.tags.Add(tag); segments.Add(segment); } Coalesce(segments); return(segments); }
public override VisualElement CreateInspectorGUI() { m_Root = new VisualElement(); UIElementsUtils.CloneTemplateInto($"Inspectors/TaggedAnimationClipEditor.uxml", m_Root); UIElementsUtils.ApplyStyleSheet(k_AnnotationsEditorStyle, m_Root); UIElementsUtils.ApplyStyleSheet(BuilderWindow.k_Stylesheet, m_Root); #if !UNITY_2020_1_OR_NEWER var retargetingInput = m_Root.Q <VisualElement>("retargeting"); retargetingInput.style.display = DisplayStyle.None; #endif m_ClipField = m_Root.Q <TextField>("clipName"); m_ClipField.SetEnabled(false); m_RetargetSourceAvatarField = m_Root.Q <ObjectField>("retargetSourceAvatar"); m_RetargetSourceAvatarField.allowSceneObjects = false; m_RetargetSourceAvatarField.objectType = typeof(Avatar); m_RetargetSourceAvatarField.RegisterValueChangedCallback(OnRetargetSourceAvatarChanged); Refresh(); var annotationsList = target as TimelineSelectionContainer; annotationsList.AnnotationsChanged += Refresh; TaggedAnimationClip clip = annotationsList.Clip; Asset asset = null; if (clip != null) { asset = clip.Asset; if (asset != null) { asset.BuildStarted += BuildStarted; asset.BuildStopped += BuildStopped; } } if (EditorApplication.isPlaying || asset != null && asset.BuildInProgress) { SetInputEnabled(false); } EditorApplication.playModeStateChanged += OnPlayModeStateChanged; return(m_Root); }
public static List <TaggedAnimationClip> BuildFromClips(List <AnimationClip> animationClips, Asset asset, ETagImportOption tagImportOption) { var taggedClips = new List <TaggedAnimationClip>(); if (animationClips == null) { return(taggedClips); } for (int i = 0; i < animationClips.Count; ++i) { var animationClip = animationClips[i]; TaggedAnimationClip taggedClip = BuildFromClip(animationClip, asset, tagImportOption); taggedClips.Add(taggedClip); } return(taggedClips); }
void OnDragPerform(DragPerformEvent evt) { if (EditorApplication.isPlaying) { return; } var clips = DragAndDrop.objectReferences.OfType <AnimationClip>().ToList(); var taggedClips = TaggedAnimationClip.BuildFromClips(clips, m_Window.Asset, ETagImportOption.AddDefaultTag); if (taggedClips.Any()) { if (m_Window.Asset != null) { m_Window.Asset.AddClips(taggedClips); Refresh(); } } }
void ResetAnimationSampler() { DisableDisplayTrajectory(); clip = null; sourceAvatar = null; if (clipAssetCallbacks != null) { clipAssetCallbacks.Dispose(); clipAssetCallbacks = null; } if (sampler != null) { sampler.Dispose(); sampler = null; } previousTime = -1.0f; }
void HighlightAnimationClip(TaggedAnimationClip animationClip) { foreach (VisualElement clipElement in m_AnimationLibraryListView.Children()) { if (!(clipElement.userData is TaggedAnimationClip taggedClip)) { continue; } IStyle clipStyle = clipElement.ElementAt(k_ClipHighlight).style; if (taggedClip.AnimationClipGuid == animationClip.AnimationClipGuid) { clipStyle.visibility = Visibility.Visible; clipStyle.opacity = new StyleFloat(1f); } else { clipStyle.visibility = Visibility.Hidden; } } }
void HighlightCurrentSamplingTime(TaggedAnimationClip animationClip, float sampleTimeInSeconds, bool debug = false) { TaggedAnimationClip taggedClip = m_Timeline.TaggedClip; if (animationClip != null && taggedClip != null && taggedClip.AnimationClipGuid == animationClip.AnimationClipGuid) { if (debug) { m_Timeline.SetActiveTickVisible(false); m_Timeline.SetDebugTime(sampleTimeInSeconds); } else { m_Timeline.SetActiveTime(sampleTimeInSeconds); m_Timeline.SetActiveTickVisible(true); } } else { m_Timeline.SetActiveTickVisible(false); } }
/// <summary> /// Creates and adds a new TaggedAnimationClip in the asset from an AnimationClip /// </summary> /// <completionlist cref=""/> /// <param name=clip>AnimationClip to use. Must be an asset on disk</param> /// <exception cref="System.ArgumentNullException">Thrown if argument clip is null</exception> /// <exception cref="System.ArgumentException">Thrown if argument clip no an asset on disk</exception> /// <returns>Returns the TaggedAnimationClip created from the supplied AnimationClip</returns> internal TaggedAnimationClip AddAnimationClip(AnimationClip clip) { if (clip == null) { throw new ArgumentNullException("clip"); } TaggedAnimationClip taggedAnimationClip = null; SerializableGuid clipGuid = SerializableGuidUtility.GetSerializableGuidFromAsset(clip); if (!clipGuid.IsSet()) { throw new ArgumentException("argument \"clip\" must be an asset on the disk"); } //Don't add existing AnimationClip to library if (AnimationLibrary.Any((TaggedAnimationClip taggedClip) => { return(taggedClip.AnimationClipGuid == clipGuid); })) { return(null); } try { taggedAnimationClip = TaggedAnimationClip.BuildFromClip(clip, this, ETagImportOption.Import); } catch (InvalidOperationException) { throw new ArgumentException("argument \"clip\" must be an asset on disk"); } Undo.RecordObject(this, string.Format("Add Animation Clip {0}", clip.name)); AnimationLibrary.Add(taggedAnimationClip); taggedAnimationClip.DataChanged += MarkDirty; MarkDirty(); return(taggedAnimationClip); }
bool InitAnimationSampler(TaggedAnimationClip clip) { this.clip = clip; if (clipAssetCallbacks != null) { clipAssetCallbacks.Dispose(); } AnimationClip animationClip = clip.GetOrLoadClipSync(); clipAssetCallbacks = new AssetPostprocessCallbacks(animationClip); clipAssetCallbacks.importDelegate = OnClipReimport; clipAssetCallbacks.deleteDelegate = OnClipDelete; sourceAvatar = clip.RetargetSourceAvatar; if (sampler != null) { sampler.Dispose(); sampler = null; } try { sampler = new AnimationSampler(targetRig, animationClip); } catch (Exception e) { Debug.LogError(e.Message); return(false); } previousTime = -1.0f; return(true); }
internal void PreviewTime(TaggedAnimationClip clip, float time) { if (targetObject == null) { return; } if (Application.isPlaying) { return; } if (this.clip != clip) { //TODO - do we need to call this when hte clip doesn't change but the target avatar does? if (!InitAnimationSampler(clip)) { return; } } SamplePose(time); EnableDisplayTrajectory(); }
public override void SetClip(TaggedAnimationClip clip) { base.SetClip(clip); ReloadElements(); }