Explorar o código

Added a method for loading data from an animation clip into the animation editor

BearishSun %!s(int64=9) %!d(string=hai) anos
pai
achega
c3e885d504
Modificáronse 1 ficheiros con 220 adicións e 11 borrados
  1. 220 11
      Source/MBansheeEditor/Windows/AnimationWindow.cs

+ 220 - 11
Source/MBansheeEditor/Windows/AnimationWindow.cs

@@ -512,17 +512,191 @@ namespace BansheeEditor
         {
             curves.Clear();
             selectedFields.Clear();
+            guiFieldDisplay.SetFields(new string[0]);
 
             clipIsImported = IsClipImported(clip);
 
             AnimationCurves clipCurves = clip.Curves;
-            foreach (var curve in clipCurves.PositionCurves)
+            EditorCurveData editorCurveData = null;
+
+            string resourcePath = ProjectLibrary.GetPath(clip);
+            if (!string.IsNullOrEmpty(resourcePath))
+            {
+                LibraryEntry entry = ProjectLibrary.GetEntry(resourcePath);
+                string clipName = PathEx.GetTail(resourcePath);
+
+                if (entry != null && entry.Type == LibraryEntryType.File)
+                {
+                    FileEntry fileEntry = (FileEntry)entry;
+                    ResourceMeta[] metas = fileEntry.ResourceMetas;
+
+                    for (int i = 0; i < metas.Length; i++)
+                    {
+                        if (clipName == metas[i].SubresourceName)
+                        {
+                            editorCurveData = metas[i].EditorData as EditorCurveData;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if(editorCurveData == null)
+                editorCurveData = new EditorCurveData();
+
+            Action<NamedVector3Curve[], EditorVector3CurveTangents[], string> loadVector3Curve =
+                (curves, tangents, subPath) =>
+                {
+                    foreach (var curveEntry in curves)
+                    {
+                        TangentMode[] tangentsX = null;
+                        TangentMode[] tangentsY = null;
+                        TangentMode[] tangentsZ = null;
+                        foreach (var tangentEntry in tangents)
+                        {
+                            if (tangentEntry.name == curveEntry.Name)
+                            {
+                                tangentsX = tangentEntry.tangentsX;
+                                tangentsY = tangentEntry.tangentsY;
+                                tangentsZ = tangentEntry.tangentsZ;
+                                break;
+                            }
+                        }
+
+                        FieldCurves fieldCurves = new FieldCurves();
+                        fieldCurves.type = SerializableProperty.FieldType.Vector3;
+                        fieldCurves.curves = new EdAnimationCurve[3];
+
+                        fieldCurves.curves[0] = new EdAnimationCurve(curveEntry.X, tangentsX);
+                        fieldCurves.curves[1] = new EdAnimationCurve(curveEntry.Y, tangentsY);
+                        fieldCurves.curves[2] = new EdAnimationCurve(curveEntry.Z, tangentsZ);
+
+                        string curvePath = curveEntry.Name.TrimEnd('/') + subPath;
+                        guiFieldDisplay.AddField(curvePath);
+                        this.curves[curvePath] = fieldCurves;
+                    }
+                };
+
+            loadVector3Curve(clipCurves.PositionCurves, editorCurveData.positionCurves, "/Position");
+            loadVector3Curve(clipCurves.RotationCurves, editorCurveData.rotationCurves, "/Rotation");
+            loadVector3Curve(clipCurves.ScaleCurves, editorCurveData.scaleCurves, "/Scale");
+
+            // Find which individual float curves belong to the same field
+            Dictionary<string, Tuple<int, bool>> suffixToIdxMapping = new Dictionary<string, Tuple<int, bool>>();
+            suffixToIdxMapping[".x"] = Tuple.Create(0, true);
+            suffixToIdxMapping[".y"] = Tuple.Create(1, true);
+            suffixToIdxMapping[".z"] = Tuple.Create(2, true);
+            suffixToIdxMapping[".w"] = Tuple.Create(3, true);
+            suffixToIdxMapping[".r"] = Tuple.Create(0, false);
+            suffixToIdxMapping[".g"] = Tuple.Create(1, false);
+            suffixToIdxMapping[".b"] = Tuple.Create(2, false);
+            suffixToIdxMapping[".a"] = Tuple.Create(3, false);
+
+            Dictionary<string, Tuple<int, int, bool>[]> floatCurveMapping = new Dictionary<string, Tuple<int, int, bool>[]>();
+            {
+                int curveIdx = 0;
+                foreach (var curveEntry in clipCurves.FloatCurves)
+                {
+                    string path = curveEntry.Name;
+                    string pathNoSuffix = null;
+
+                    string pathSuffix;
+                    if (path.Length >= 2)
+                    {
+                        pathSuffix = path.Substring(path.Length - 2, 2);
+                        pathNoSuffix = path.Substring(0, path.Length - 2);
+                    }
+                    else
+                        pathSuffix = "";
+
+                    int tangentIdx = -1;
+                    int currentTangentIdx = 0;
+                    foreach (var tangentEntry in editorCurveData.floatCurves)
+                    {
+                        if (tangentEntry.name == curveEntry.Name)
+                        {
+                            tangentIdx = currentTangentIdx;
+                            break;
+                        }
+
+                        currentTangentIdx++;
+                    }
+
+                    Tuple<int, bool> suffixInfo;
+                    if (suffixToIdxMapping.TryGetValue(pathSuffix, out suffixInfo))
+                    {
+                        Tuple<int, int, bool>[] curveInfo;
+                        if (!floatCurveMapping.TryGetValue(pathNoSuffix, out curveInfo))
+                            curveInfo = new Tuple<int, int, bool>[4];
+
+                        curveInfo[suffixInfo.Item1] = Tuple.Create(curveIdx, tangentIdx, suffixInfo.Item2);
+                        floatCurveMapping[pathNoSuffix] = curveInfo;
+                    }
+                    else
+                    {
+                        Tuple<int, int, bool>[] curveInfo = new Tuple<int, int, bool>[4];
+                        curveInfo[0] = Tuple.Create(curveIdx, tangentIdx, suffixInfo.Item2);
+
+                        floatCurveMapping[path] = curveInfo;
+                    }
+
+                    curveIdx++;
+                }
+            }
+
+            foreach (var KVP in floatCurveMapping)
             {
-                // TODO (don't forget tangents)
+                int numCurves = 0;
+                for (int i = 0; i < 4; i++)
+                {
+                    if (KVP.Value[i] == null)
+                        continue;
 
-            // TODO - Trim last / if needed
+                    numCurves++;
+                }
+
+                if (numCurves == 0)
+                    continue; // Invalid curve
+
+                FieldCurves fieldCurves = new FieldCurves();
+
+                // Deduce type (note that all single value types are assumed to be float even if their source type is int or bool)
+                if (numCurves == 1)
+                    fieldCurves.type = SerializableProperty.FieldType.Float;
+                else if (numCurves == 2)
+                    fieldCurves.type = SerializableProperty.FieldType.Vector2;
+                else if (numCurves == 3)
+                    fieldCurves.type = SerializableProperty.FieldType.Vector3;
+                else // 4 curves
+                {
+                    bool isVector = KVP.Value[0].Item3;
+                    if (isVector)
+                        fieldCurves.type = SerializableProperty.FieldType.Vector4;
+                    else
+                        fieldCurves.type = SerializableProperty.FieldType.Color;
+                }
+
+                fieldCurves.curves = new EdAnimationCurve[numCurves];
+
+                for (int i = 0; i < numCurves; i++)
+                {
+                    int curveIdx = KVP.Value[i].Item1;
+                    int tangentIdx = KVP.Value[i].Item2;
+
+                    TangentMode[] tangents = null;
+                    if (tangentIdx != -1)
+                        tangents = editorCurveData.floatCurves[tangentIdx].tangents;
+
+                    fieldCurves.curves[i] = new EdAnimationCurve(clipCurves.FloatCurves[curveIdx].Curve, tangents);
+                }
+
+                string curvePath = KVP.Key;
+
+                guiFieldDisplay.AddField(curvePath);
+                curves[curvePath] = fieldCurves;
             }
 
+            // Add events
             events.AddRange(clip.Events);
         }
 
@@ -588,16 +762,51 @@ namespace BansheeEditor
                     }
                     else
                     {
-                        NamedFloatCurve curve = new NamedFloatCurve(kvp.Key,
-                            new AnimationCurve(kvp.Value.curves[0].KeyFrames));
+                        Action<int, string> addCurve = (idx, subPath) =>
+                        {
+                            string path = kvp.Key + subPath;
 
-                        EditorFloatCurveTangents tangents = new EditorFloatCurveTangents();
-                        tangents.name = kvp.Key;
-                        tangents.tangents = kvp.Value.curves[0].TangentModes;
+                            NamedFloatCurve curve = new NamedFloatCurve(path,
+                            new AnimationCurve(kvp.Value.curves[idx].KeyFrames));
 
-                        floatCurves.Add(curve);
-                        floatTangents.Add(tangents);
-                    } 
+                            EditorFloatCurveTangents tangents = new EditorFloatCurveTangents();
+                            tangents.name = path;
+                            tangents.tangents = kvp.Value.curves[idx].TangentModes;
+
+                            floatCurves.Add(curve);
+                            floatTangents.Add(tangents);
+                        };
+
+                        switch (kvp.Value.type)
+                        {
+                            case SerializableProperty.FieldType.Vector2:
+                                addCurve(0, ".x");
+                                addCurve(1, ".y");
+                                break;
+                            case SerializableProperty.FieldType.Vector3:
+                                addCurve(0, ".x");
+                                addCurve(1, ".y");
+                                addCurve(2, ".z");
+                                break;
+                            case SerializableProperty.FieldType.Vector4:
+                                addCurve(0, ".x");
+                                addCurve(1, ".y");
+                                addCurve(2, ".z");
+                                addCurve(3, ".w");
+                                break;
+                            case SerializableProperty.FieldType.Color:
+                                addCurve(0, ".r");
+                                addCurve(1, ".g");
+                                addCurve(2, ".b");
+                                addCurve(3, ".a");
+                                break;
+                            case SerializableProperty.FieldType.Bool:
+                            case SerializableProperty.FieldType.Int:
+                            case SerializableProperty.FieldType.Float:
+                                addCurve(0, "");
+                                break;
+                        }
+                    }
                 }
 
                 AnimationCurves newClipCurves = new AnimationCurves();