Ejemplo n.º 1
0
        public void AddTag(Type tagType, float startTime = 0f, float duration = -1f)
        {
            if (!Valid)
            {
                return;
            }

            if (duration < 0)
            {
                duration = DurationInSeconds - startTime;
            }

            int existing = tags.Count(t => t.Type == tagType &&
                                      FloatComparer.AreEqual(t.startTime, startTime, FloatComparer.kEpsilon) &&
                                      FloatComparer.AreEqual(t.duration, duration, FloatComparer.kEpsilon));

            if (existing > 0)
            {
                return;
            }

            Undo.RecordObject(m_Asset, $"Add {TagAttribute.GetDescription(tagType)} tag");

            TagAnnotation newTag = TagAnnotation.Create(tagType, startTime, duration);

            tags.Add(newTag);

            NotifyChanged();
        }
        public static TagAnnotation Create <T>(T payload, float startTime, float duration) where T : struct
        {
            TagAnnotation tag = Create(typeof(T), startTime, duration);

            tag.payload.SetValue(payload);
            return(tag);
        }
Ejemplo n.º 3
0
        TaggedAnimationClip(AnimationClip animationClip, Asset asset, ETagImportOption tagImportOption)
        {
            m_Asset = asset;
            SetClip(animationClip);

            foreach (var method in Utility.GetExtensionMethods(GetType()))
            {
                method.Invoke(null, new object[] { this, tagImportOption });
            }

            if (tagImportOption == ETagImportOption.AddDefaultTag)
            {
                object tag = DefaultTagAttribute.CreateDefaultTag();
                if (tag != null)
                {
                    TagAnnotation tagAnnotation = TagAnnotation.Create(tag.GetType(), 0.0f, DurationInSeconds);
                    tagAnnotation.payload.SetValueObject(tag);
                    AddTag(tagAnnotation);
                }
            }

            if (animationClip.isLooping)
            {
                TaggedPreBoundaryClip  = this;
                TaggedPostBoundaryClip = this;
            }

            // Obsolete V1 variables
            m_PreBoundaryClip  = null;
            m_PostBoundaryClip = null;
        }
        public bool ReorderTagElement(ITimelineElement element, int direction)
        {
            if (direction == 0 || element == null)
            {
                return(false);
            }

            TagAnnotation tag = element.Object as TagAnnotation;

            if (tag == null)
            {
                return(false);
            }

            int currentIndex = m_TaggedClip.Tags.IndexOf(tag);
            int newIndex     = currentIndex + direction;

            if (newIndex < 0 || newIndex > m_TaggedClip.Tags.Count - 1)
            {
                return(false);
            }

            Undo.RecordObject(m_TaggedClip.Asset, "Reorder Tag");
            m_TaggedClip.Tags.Remove(tag);
            m_TaggedClip.Tags.Insert(newIndex, tag);
            Insert(newIndex, (element as VisualElement));

            return(true);
        }
Ejemplo n.º 5
0
 public void RemoveTag(TagAnnotation tag)
 {
     Undo.RecordObject(m_Asset, $"Remove {TagAttribute.GetDescription(tag.Type)} tag");
     tags.RemoveAll(x => x == tag);
     tag.Dispose();
     TagRemoved?.Invoke(tag);
     NotifyChanged();
 }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        public void AddTag(TagAnnotation tag)
        {
            if (!Valid)
            {
                return;
            }

            Undo.RecordObject(m_Asset, $"Add {TagAttribute.GetDescription(tag.Type)} tag");
            tags.Add(tag);
            TagAdded?.Invoke(tag);
            NotifyChanged();
        }
        bool IsTagAssociatedToMetric(TagAnnotation tag)
        {
            string tagName = TagAnnotation.GetTagTypeFullName(tag);

            foreach (Asset.Metric metric in asset.Metrics)
            {
                if (metric.TagTypes.Contains(tagName))
                {
                    return(true);
                }
            }
            return(false);
        }
        bool DoesSegmentCoverMetric(Segment segment)
        {
            foreach (TagAnnotation tag in segment.tags)
            {
                string tagName = TagAnnotation.GetTagTypeFullName(tag);

                foreach (Asset.Metric metric in asset.Metrics)
                {
                    if (metric.TagTypes.Contains(tagName))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public static string GetTagTypeFullName(TagAnnotation t)
        {
            if (t.payload == null || t.payload.Type == null)
            {
                return(null);
            }

            string name;

            if (k_TagTypeFullNameCache.TryGetValue(t.payload.Type, out name))
            {
                return(name);
            }

            if (t.payload.Type != null && t.payload.ScriptableObject != null)
            {
                name = t.payload.Type.FullName;
                k_TagTypeFullNameCache[t.payload.Type] = name;
                return(name);
            }

            return($"{TagAttribute.k_UnknownTagType} - {t.payload.SimplifiedTypeName} ");
        }
Ejemplo n.º 11
0
 public int GetMetricIndexCoveringTimeOnTag(TagAnnotation tag)
 {
     return(GetMetricIndexCoveringTimeOnTag(TagAnnotation.GetTagTypeFullName(tag)));
 }
Ejemplo n.º 12
0
        internal TagEditor(TagAnnotation tag, TaggedAnimationClip clip)
        {
            m_Tag  = tag;
            m_Clip = clip;

            UIElementsUtils.CloneTemplateInto("Inspectors/TagEditor.uxml", this);
            UIElementsUtils.ApplyStyleSheet(AnnotationsEditor.k_AnnotationsEditorStyle, this);
            AddToClassList(AnnotationsEditor.k_AnnotationsContainer);
            AddToClassList("drawerElement");

            var deleteButton = this.Q <Button>("deleteButton");

            deleteButton.clickable.clicked += () => { RemoveTag(m_Tag); };

            if (!tag.payload.ValidPayloadType)
            {
                Clear();
                var unknownLabel = new Label {
                    text = TagAttribute.k_UnknownTagType
                };
                unknownLabel.AddToClassList(AnnotationsEditor.k_UnknownAnnotationType);
                Add(unknownLabel);
                return;
            }

            TextField tagType = this.Q <TextField>("tagType");

            tagType.value = TagAttribute.GetDescription(m_Tag.Type);
            tagType.SetEnabled(false);

            Asset asset = m_Clip.Asset;

            TextField tagName = this.Q <TextField>("name");

            tagName.value = m_Tag.name;
            tagName.RegisterValueChangedCallback(evt =>
            {
                if (!evt.newValue.Equals(m_Tag.name, StringComparison.Ordinal))
                {
                    Undo.RecordObject(asset, "Change tag name");
                    m_Tag.name = evt.newValue;
                    m_Tag.NotifyChanged();
                    asset.MarkDirty();
                }
            });

            TextField metricLabel = this.Q <TextField>("metricLabel");
            var       metric      = asset.GetMetricForTagType(m_Tag.Type);

            if (metric != null)
            {
                metricLabel.value = metric.name;
                metricLabel.SetEnabled(false);
            }
            else
            {
                metricLabel.style.display = DisplayStyle.None;
            }

            TimeField stf = this.Q <TimeField>("startTime");

            stf.Init(m_Clip, m_Tag.startTime);
            stf.TimeChanged += (newTime) =>
            {
                if (!EqualityComparer <float> .Default.Equals(m_Tag.startTime, newTime))
                {
                    Undo.RecordObject(asset, "Change tag start time");
                    m_Tag.startTime = newTime;
                    m_Tag.NotifyChanged();
                    asset.MarkDirty();
                }
            };


            TimeField dtf = this.Q <TimeField>("durationTime");

            dtf.Init(m_Clip, m_Tag.duration);
            dtf.TimeChanged += (newTime) =>
            {
                if (!EqualityComparer <float> .Default.Equals(m_Tag.duration, newTime))
                {
                    Undo.RecordObject(asset, "Change tag duration");
                    m_Tag.duration = newTime;
                    m_Tag.NotifyChanged();
                    asset.MarkDirty();
                }
            };

            var so = m_Tag.payload.ScriptableObject;

            if (so != null)
            {
                m_PayloadInspector = UnityEditor.Editor.CreateEditor(so) as GenericStructInspector;
                m_PayloadInspector.StructModified += () =>
                {
                    m_Tag.payload.Serialize();
                    m_Tag.NotifyChanged();
                    m_Clip.Asset.MarkDirty();
                };

                VisualElement inspectorElement   = m_PayloadInspector.CreateInspectorGUI() ?? new IMGUIContainer(m_PayloadInspector.OnInspectorGUI);
                var           inspectorContainer = this.Q <VisualElement>("payloadInspector");
                inspectorContainer.Add(inspectorElement);
            }

            RegisterCallback <DetachFromPanelEvent>(OnDetachFromPanel);

            m_Tag.Changed += Refresh;
            asset.AssetWasDeserialized += Refresh;
        }
Ejemplo n.º 13
0
 void RemoveTag(TagAnnotation tag)
 {
     m_Clip.RemoveTag(tag);
 }
Ejemplo n.º 14
0
        protected override void OnMouseMoveEvent(MouseMoveEvent evt)
        {
            Timeline            timeline            = TagElement.Timeline;
            TaggedAnimationClip taggedAnimationClip = timeline.TaggedClip;

            if (!m_Active || !target.HasMouseCapture() || !taggedAnimationClip.Valid || EditorApplication.isPlaying)
            {
                return;
            }

            if (Math.Abs(m_MousePreviousPosition.x - evt.mousePosition.x) < k_MinDistanceForTagCreation)
            {
                if (Math.Abs(m_MouseDownPosition.y - evt.mousePosition.y) >= k_MinDistanceForTagCreation)
                {
                    OnMouseMoveReorderEvent(evt);
                }

                return;
            }

            Vector2        position  = evt.mousePosition;
            MouseDirection direction = GetMouseDirection(position);

            m_MousePreviousPosition = position;
            float framerate = taggedAnimationClip.SampleRate;

            TagAnnotation tag = TagElement.m_Tag;

            Asset asset = taggedAnimationClip.Asset;

            Mode mode = m_Mode;

            if (m_OverrideMode == Mode.None)
            {
                float mousePos  = evt.mousePosition.x;
                float fromStart = Math.Abs(mousePos - TagElement.worldBound.x);
                float fromEnd   = Math.Abs(mousePos - TagElement.worldBound.xMax);
                // If the tag element is this small it will be too difficult to accurately grab the center and even accurately pick either end
                // we'll figure out which side of the tag is closest and assume the user meant to click that side.
                if (TagElement.layout.width <= 14f)
                {
                    if (fromStart <= fromEnd)
                    {
                        mode = Mode.StartTime;
                    }
                    else
                    {
                        mode = Mode.Duration;
                    }

                    m_OverrideMode = mode;
                }
            }
            else
            {
                mode = m_OverrideMode;
            }

            float newTime = float.NaN;

            float dragPosition = position.x;
            bool  canPreview   = timeline.CanPreview();

            // when we're dragging the entire tag we need to snap the edges of the tag, not the mouse position so we'll handle that inside its switch case
            if (mode != Mode.Body)
            {
                if (m_Target.SnapValid(dragPosition))
                {
                    return;
                }

                TryToSnap(dragPosition, direction, taggedAnimationClip.SampleRate, out newTime, snapToPlayhead: !canPreview);
            }

            float previewTime = -1f;

            switch (mode)
            {
            case Mode.StartTime:
                float endTime = tag.startTime + tag.duration;
                Undo.RecordObject(asset, "Drag Tag start");

                float delta = newTime - tag.startTime;
                if (tag.duration - delta < TagElement.MinTagDuration)
                {
                    tag.startTime = endTime - TagElement.MinTagDuration;
                    tag.duration  = TagElement.MinTagDuration;
                }
                else
                {
                    tag.startTime = newTime;
                    tag.duration  = endTime - tag.startTime;
                }

                TagElement.Timeline.ShowStartGuideline(tag.startTime);
                previewTime = newTime;

                break;

            case Mode.Duration:
                Undo.RecordObject(asset, "Drag Tag Duration");
                float newDuration = newTime - tag.startTime;
                if (newDuration <= TagElement.MinTagDuration)
                {
                    tag.duration = TagElement.MinTagDuration;
                }
                else
                {
                    tag.duration = newDuration;
                }

                TagElement.Timeline.ShowEndGuideline(tag.EndTime);
                previewTime = tag.EndTime;
                break;

            case Mode.Body:
                Undo.RecordObject(asset, "Drag Tag");
                newTime = m_Target.Timeline.WorldPositionToTime(position.x);
                if (TagElement.Timeline.TimelineUnits == TimelineViewMode.frames)
                {
                    newTime = (float)TimelineUtility.RoundToFrame(newTime - m_TimeOffsetAtMouseDown, framerate);
                }
                else
                {
                    newTime -= m_TimeOffsetAtMouseDown;
                }

                if (!m_Target.SnapValid(newTime) && !m_Target.SnapValid(newTime + tag.duration))
                {
                    float mouseOffset = TagElement.Timeline.TimeToWorldPos(newTime);
                    if (!TryToSnap(mouseOffset, direction, taggedAnimationClip.SampleRate, out newTime, snapToPlayhead: !canPreview))
                    {
                        float durationPos = TagElement.Timeline.TimeToWorldPos(newTime + tag.duration);
                        //Try to snap via the end of the current tag
                        if (TryToSnap(durationPos, direction, taggedAnimationClip.SampleRate, out float candidateEndTime, snapToPlayhead: !canPreview))
                        {
                            newTime = candidateEndTime - tag.duration;
                        }
                    }

                    tag.startTime = newTime;

                    TagElement.Timeline.ShowGuidelines(tag.startTime, tag.EndTime);
                }

                previewTime = tag.EndTime;

                break;
            }

            if (canPreview && previewTime >= 0f)
            {
                TagElement.Timeline.SetActiveTime(previewTime);
            }

            tag.NotifyChanged();
            TagElement.Timeline.SendTagModified();

            evt.StopPropagation();

            TagElement.ShowManipulationLabel();
        }
 public bool Equals(TagAnnotation other)
 {
     return(Type == other.Type &&
            FloatComparer.AreEqual(startTime, other.startTime, FloatComparer.kEpsilon) &&
            FloatComparer.AreEqual(duration, other.duration, FloatComparer.kEpsilon));
 }