예제 #1
0
        public List <AnimationWindowHierarchyNode> CreateTreeFromCurves()
        {
            List <AnimationWindowHierarchyNode> nodes = new List <AnimationWindowHierarchyNode>();
            List <AnimationWindowCurve>         singlePropertyCurves = new List <AnimationWindowCurve>();

            AnimationWindowCurve[]       curves     = state.allCurves.ToArray();
            AnimationWindowHierarchyNode parentNode = (AnimationWindowHierarchyNode)m_RootItem;

            for (int i = 0; i < curves.Length; i++)
            {
                AnimationWindowCurve curve = curves[i];

                if (!state.ShouldShowCurve(curve))
                {
                    continue;
                }

                AnimationWindowCurve nextCurve = i < curves.Length - 1 ? curves[i + 1] : null;

                singlePropertyCurves.Add(curve);

                bool areSameGroup       = nextCurve != null && AnimationWindowUtility.GetPropertyGroupName(nextCurve.propertyName) == AnimationWindowUtility.GetPropertyGroupName(curve.propertyName);
                bool areSamePathAndType = nextCurve != null && curve.path.Equals(nextCurve.path) && curve.type == nextCurve.type;

                // We expect curveBindings to come sorted by propertyname
                // So we compare curve vs nextCurve. If its different path or different group (think "scale.xyz" as group), then we know this is the last element of such group.
                if (i == curves.Length - 1 || !areSameGroup || !areSamePathAndType)
                {
                    if (singlePropertyCurves.Count > 1)
                    {
                        nodes.Add(AddPropertyGroupToHierarchy(singlePropertyCurves.ToArray(), parentNode));
                    }
                    else
                    {
                        nodes.Add(AddPropertyToHierarchy(singlePropertyCurves[0], parentNode));
                    }
                    singlePropertyCurves.Clear();
                }
            }

            return(nodes);
        }
예제 #2
0
 public static bool DoesPropertyPathMatch(string a, string b)
 {
     return(AnimationWindowUtility.GetPropertyGroupName(a).Equals(AnimationWindowUtility.GetPropertyGroupName(b)) || IsRotationCurve(a) && IsRotationCurve(b));
 }
예제 #3
0
        static bool IsRotationCurve(string propertyName)
        {
            string groupName = AnimationWindowUtility.GetPropertyGroupName(propertyName);

            return(groupName == kLocalRotation || groupName == kLocalEulerHint);
        }
        static void AddRotationKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time)
        {
            if (prop.propertyType != SerializedPropertyType.Quaternion)
            {
                return;
            }

            var updateCurves   = new List <AnimationCurve>();
            var updateBindings = new List <EditorCurveBinding>();

            var info = AnimationClipCurveCache.Instance.GetCurveInfo(clip);

            for (var i = 0; i < info.bindings.Length; i++)
            {
                if (sourceBind.type != info.bindings[i].type)
                {
                    continue;
                }

                if (info.bindings[i].propertyName.Contains("localEuler"))
                {
                    updateBindings.Add(info.bindings[i]);
                    updateCurves.Add(info.curves[i]);
                }
            }

            // use this instead of serialized properties because the editor will attempt to maintain
            // correct localeulers
            var eulers = ((Transform)prop.serializedObject.targetObject).localEulerAngles;

            if (updateBindings.Count == 0)
            {
                var propName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName);
                updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".x"));
                updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".y"));
                updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".z"));

                var curveX = new AnimationCurve();
                var curveY = new AnimationCurve();
                var curveZ = new AnimationCurve();
                AddKeyFrameToCurve(curveX, (float)time, clip.frameRate, eulers.x, false);
                AddKeyFrameToCurve(curveY, (float)time, clip.frameRate, eulers.y, false);
                AddKeyFrameToCurve(curveZ, (float)time, clip.frameRate, eulers.z, false);

                updateCurves.Add(curveX);
                updateCurves.Add(curveY);
                updateCurves.Add(curveZ);
            }

            for (var i = 0; i < updateBindings.Count; i++)
            {
                var c     = updateBindings[i].propertyName.Last();
                var value = eulers.x;
                if (c == 'y')
                {
                    value = eulers.y;
                }
                else if (c == 'z')
                {
                    value = eulers.z;
                }
                AddKeyFrameToCurve(updateCurves[i], (float)time, clip.frameRate, value, false);
            }

            UpdateEditorCurves(clip, updateBindings, updateCurves);
        }
        // Add a floating point curve key
        static void AddFloatKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time)
        {
            var updateCurves   = new List <AnimationCurve>();
            var updateBindings = new List <EditorCurveBinding>();

            var updated = false;
            var info    = AnimationClipCurveCache.Instance.GetCurveInfo(clip);

            for (var i = 0; i < info.bindings.Length; i++)
            {
                var binding = info.bindings[i];
                if (binding.type != sourceBind.type)
                {
                    continue;
                }

                SerializedProperty valProp = null;
                var curve = info.curves[i];

                // perfect match on property path, editting a float
                if (prop.propertyPath.Equals(binding.propertyName))
                {
                    valProp = prop;
                }
                // this is a child object
                else if (binding.propertyName.Contains(prop.propertyPath))
                {
                    valProp = prop.serializedObject.FindProperty(binding.propertyName);
                }

                if (valProp != null)
                {
                    var value = GetKeyValue(valProp);
                    if (!float.IsNaN(value)) // Nan indicates an error retrieving the property value
                    {
                        updated = true;
                        AddKeyFrameToCurve(curve, (float)time, clip.frameRate, value, valProp.propertyType == SerializedPropertyType.Boolean);
                        updateCurves.Add(curve);
                        updateBindings.Add(binding);
                    }
                }
            }

            // Curves don't exist, add them
            if (!updated)
            {
                var propName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName);
                if (!prop.hasChildren)
                {
                    var value = GetKeyValue(prop);
                    if (!float.IsNaN(value))
                    {
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, sourceBind.propertyName));
                        var curve = new AnimationCurve();
                        AddKeyFrameToCurve(curve, (float)time, clip.frameRate, value, prop.propertyType == SerializedPropertyType.Boolean);
                        updateCurves.Add(curve);
                    }
                }
                else
                {
                    // special case because subproperties on color aren't 'visible' so you can't iterate over them
                    if (prop.propertyType == SerializedPropertyType.Color)
                    {
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".r"));
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".g"));
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".b"));
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".a"));

                        var c = prop.colorValue;
                        for (var i = 0; i < 4; i++)
                        {
                            var curve = new AnimationCurve();
                            AddKeyFrameToCurve(curve, (float)time, clip.frameRate, c[i], prop.propertyType == SerializedPropertyType.Boolean);
                            updateCurves.Add(curve);
                        }
                    }
                    else
                    {
                        prop = prop.Copy();
                        foreach (SerializedProperty cp in prop)
                        {
                            updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, cp.propertyPath));
                            var curve = new AnimationCurve();
                            AddKeyFrameToCurve(curve, (float)time, clip.frameRate, GetKeyValue(cp), cp.propertyType == SerializedPropertyType.Boolean);
                            updateCurves.Add(curve);
                        }
                    }
                }
            }

            UpdateEditorCurves(clip, updateBindings, updateCurves);
        }
예제 #6
0
 public AnimationWindowHierarchyPropertyGroupNode(System.Type animatableObjectType, int setId, string propertyName, string path, TreeViewItem parent)
     : base(AnimationWindowUtility.GetPropertyNodeID(setId, path, animatableObjectType, propertyName), parent != null ? parent.depth + 1 : -1, parent, animatableObjectType, AnimationWindowUtility.GetPropertyGroupName(propertyName), path, AnimationWindowUtility.GetNicePropertyGroupDisplayName(animatableObjectType, propertyName))
 {
 }
 public static string GetGroupID(this EditorCurveBinding binding)
 {
     return(binding.get_type() + AnimationWindowUtility.GetPropertyGroupName(binding.propertyName));
 }
예제 #8
0
        public int CompareTo(AnimationWindowCurve obj)
        {
            if (!path.Equals(obj.path))
            {
                return(ComparePaths(obj.path));
            }

            bool sameTransformComponent  = type == typeof(Transform) && obj.type == typeof(Transform);
            bool oneIsTransformComponent = (type == typeof(Transform) || obj.type == typeof(Transform));

            // We want to sort position before rotation
            if (sameTransformComponent)
            {
                string propertyGroupA = AnimationWindowUtility.GetNicePropertyGroupDisplayName(typeof(Transform), AnimationWindowUtility.GetPropertyGroupName(propertyName));
                string propertyGroupB = AnimationWindowUtility.GetNicePropertyGroupDisplayName(typeof(Transform), AnimationWindowUtility.GetPropertyGroupName(obj.propertyName));

                if (propertyGroupA.Contains("Position") && propertyGroupB.Contains("Rotation"))
                {
                    return(-1);
                }
                if (propertyGroupA.Contains("Rotation") && propertyGroupB.Contains("Position"))
                {
                    return(1);
                }
            }
            // Transform component should always come first.
            else if (oneIsTransformComponent)
            {
                if (type == typeof(Transform))
                {
                    return(-1);
                }
                else
                {
                    return(1);
                }
            }

            // Sort (.r, .g, .b, .a) and (.x, .y, .z, .w)
            if (obj.type == type)
            {
                int lhsIndex = AnimationWindowUtility.GetComponentIndex(obj.propertyName);
                int rhsIndex = AnimationWindowUtility.GetComponentIndex(propertyName);
                if (lhsIndex != -1 && rhsIndex != -1 && propertyName.Substring(0, propertyName.Length - 2) == obj.propertyName.Substring(0, obj.propertyName.Length - 2))
                {
                    return(rhsIndex - lhsIndex);
                }
            }

            return(string.Compare((path + type + propertyName), obj.path + obj.type + obj.propertyName, StringComparison.Ordinal));
        }
 public AddCurvesPopupPropertyNode(TreeViewItem parent, EditorCurveBinding[] curveBindings)
     : base(curveBindings[0].GetHashCode(), parent.depth + 1, parent, AnimationWindowUtility.NicifyPropertyGroupName(curveBindings[0].type, AnimationWindowUtility.GetPropertyGroupName(curveBindings[0].propertyName)))
 {
     this.curveBindings = curveBindings;
 }
        private TreeViewItem AddAnimatableObjectToHierarchy(EditorCurveBinding[] curveBindings, TreeViewItem parentNode, string path)
        {
            TreeViewItem node = new AddCurvesPopupObjectNode(parentNode, path, GetClassName(curveBindings[0]));

            node.icon = GetIcon(curveBindings[0]);

            List <TreeViewItem>       childNodes             = new List <TreeViewItem>();
            List <EditorCurveBinding> singlePropertyBindings = new List <EditorCurveBinding>();

            for (int i = 0; i < curveBindings.Length; i++)
            {
                EditorCurveBinding curveBinding = curveBindings[i];

                singlePropertyBindings.Add(curveBinding);

                // We expect curveBindings to come sorted by propertyname
                if (i == curveBindings.Length - 1 || AnimationWindowUtility.GetPropertyGroupName(curveBindings[i + 1].propertyName) != AnimationWindowUtility.GetPropertyGroupName(curveBinding.propertyName))
                {
                    TreeViewItem newNode = CreateNode(singlePropertyBindings.ToArray(), node);
                    if (newNode != null)
                    {
                        childNodes.Add(newNode);
                    }
                    singlePropertyBindings.Clear();
                }
            }

            childNodes.Sort();

            TreeViewUtility.SetChildParentReferences(childNodes, node);
            return(node);
        }
        private static void AddFloatKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time)
        {
            List <AnimationCurve>     list  = new List <AnimationCurve>();
            List <EditorCurveBinding> list2 = new List <EditorCurveBinding>();
            bool flag = false;
            AnimationClipCurveInfo curveInfo = AnimationClipCurveCache.Instance.GetCurveInfo(clip);

            for (int i = 0; i < curveInfo.bindings.Length; i++)
            {
                EditorCurveBinding item = curveInfo.bindings[i];
                if (item.get_type() == sourceBind.get_type())
                {
                    SerializedProperty serializedProperty = null;
                    AnimationCurve     animationCurve     = curveInfo.curves[i];
                    if (prop.get_propertyPath().Equals(item.propertyName))
                    {
                        serializedProperty = prop;
                    }
                    else if (item.propertyName.Contains(prop.get_propertyPath()))
                    {
                        serializedProperty = prop.get_serializedObject().FindProperty(item.propertyName);
                    }
                    if (serializedProperty != null)
                    {
                        float keyValue = CurveEditUtility.GetKeyValue(serializedProperty);
                        if (!float.IsNaN(keyValue))
                        {
                            flag = true;
                            CurveEditUtility.AddKeyFrameToCurve(animationCurve, (float)time, clip.get_frameRate(), keyValue, serializedProperty.get_propertyType() == 1);
                            list.Add(animationCurve);
                            list2.Add(item);
                        }
                    }
                }
            }
            if (!flag)
            {
                string propertyGroupName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName);
                if (!prop.get_hasChildren())
                {
                    float keyValue2 = CurveEditUtility.GetKeyValue(prop);
                    if (!float.IsNaN(keyValue2))
                    {
                        list2.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.get_type(), sourceBind.propertyName));
                        AnimationCurve animationCurve2 = new AnimationCurve();
                        CurveEditUtility.AddKeyFrameToCurve(animationCurve2, (float)time, clip.get_frameRate(), keyValue2, prop.get_propertyType() == 1);
                        list.Add(animationCurve2);
                    }
                }
                else if (prop.get_propertyType() == 4)
                {
                    list2.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.get_type(), propertyGroupName + ".r"));
                    list2.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.get_type(), propertyGroupName + ".g"));
                    list2.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.get_type(), propertyGroupName + ".b"));
                    list2.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.get_type(), propertyGroupName + ".a"));
                    Color colorValue = prop.get_colorValue();
                    for (int j = 0; j < 4; j++)
                    {
                        AnimationCurve animationCurve3 = new AnimationCurve();
                        CurveEditUtility.AddKeyFrameToCurve(animationCurve3, (float)time, clip.get_frameRate(), colorValue.get_Item(j), prop.get_propertyType() == 1);
                        list.Add(animationCurve3);
                    }
                }
                else
                {
                    prop = prop.Copy();
                    IEnumerator enumerator = prop.GetEnumerator();
                    try
                    {
                        while (enumerator.MoveNext())
                        {
                            SerializedProperty serializedProperty2 = (SerializedProperty)enumerator.Current;
                            list2.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.get_type(), serializedProperty2.get_propertyPath()));
                            AnimationCurve animationCurve4 = new AnimationCurve();
                            CurveEditUtility.AddKeyFrameToCurve(animationCurve4, (float)time, clip.get_frameRate(), CurveEditUtility.GetKeyValue(serializedProperty2), serializedProperty2.get_propertyType() == 1);
                            list.Add(animationCurve4);
                        }
                    }
                    finally
                    {
                        IDisposable disposable;
                        if ((disposable = (enumerator as IDisposable)) != null)
                        {
                            disposable.Dispose();
                        }
                    }
                }
            }
            CurveEditUtility.UpdateEditorCurves(clip, list2, list);
        }
        private void FillInMissingTransformCurves(List <AnimationWindowCurve> transformCurves, ref List <AnimationWindowCurve> curvesCache)
        {
            EditorCurveBinding lastBinding = transformCurves[0].binding;
            var    propertyGroup           = new EditorCurveBinding?[3];
            string propertyGroupName;

            foreach (var transformCurve in transformCurves)
            {
                var transformBinding = transformCurve.binding;
                //if it's a new property group
                if (transformBinding.path != lastBinding.path ||
                    AnimationWindowUtility.GetPropertyGroupName(transformBinding.propertyName) != AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName))
                {
                    propertyGroupName = AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName);

                    FillPropertyGroup(ref propertyGroup, lastBinding, propertyGroupName, ref curvesCache);

                    lastBinding = transformBinding;

                    propertyGroup = new EditorCurveBinding?[3];
                }

                AssignBindingToRightSlot(transformBinding, ref propertyGroup);
            }
            FillPropertyGroup(ref propertyGroup, lastBinding, AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName), ref curvesCache);
        }
 static bool DoesPropertyPathMatch(string a, string b)
 {
     return(AnimationWindowUtility.GetPropertyGroupName(a).Equals(AnimationWindowUtility.GetPropertyGroupName(a)));
 }
예제 #14
0
        private AnimationWindowHierarchyPropertyGroupNode AddPropertyGroupToHierarchy(AnimationWindowCurve[] curves, AnimationWindowHierarchyNode parentNode)
        {
            List <AnimationWindowHierarchyNode> childNodes = new List <AnimationWindowHierarchyNode>();

            System.Type animatableObjectType = curves[0].type;
            AnimationWindowHierarchyPropertyGroupNode node = new AnimationWindowHierarchyPropertyGroupNode(animatableObjectType, 0, AnimationWindowUtility.GetPropertyGroupName(curves[0].propertyName), curves[0].path, parentNode);

            node.icon = GetIcon(curves[0].binding);

            node.indent = curves[0].depth;
            node.curves = curves;

            foreach (AnimationWindowCurve curve in curves)
            {
                AnimationWindowHierarchyPropertyNode childNode = AddPropertyToHierarchy(curve, node);
                // For child nodes we do not want to display the type in front (It is already shown by the group node)
                childNode.displayName = AnimationWindowUtility.GetPropertyDisplayName(childNode.propertyName);
                childNodes.Add(childNode);
            }

            TreeViewUtility.SetChildParentReferences(new List <TreeViewItem>(childNodes.ToArray()), node);
            return(node);
        }