/// <summary> /// Updates the dictionary of context menu for the given curve. /// </summary> /// <param name='keysAddedCount'> /// Number of keys added(removed, if is negative) outside of this curve editor /// </param> internal void UpdateDictContextMenu(AnimationCurve curve, int keysAddedCount) { //TODO //a much more correct way of updating the list of context menu structs ,for example inserting or deleting the exact item in/from the list //for now,it's just adding/removing at the end of the list, so when just adding a key in the middle of the curve,outside of this curve editor, //the curve in this curve editor ,might have some context menu changed(shifted) for the existing keys after the newly added key //for now,this easier solution,shouldn't harm , as there is not likely to change a curve outside of this curve editor List <ContextMenuStruct> listContextMenus = dictCurvesContextMenus[curve]; if (keysAddedCount > 0) { for (int i = 0; i < keysAddedCount; ++i) { ContextMenuStruct contextMenuStruct = new ContextMenuStruct(); contextMenuStruct.freeSmooth = true; listContextMenus.Add(contextMenuStruct); } } else { for (int i = 0; i < -keysAddedCount; ++i) { listContextMenus.RemoveAt(curve.length); } } }
internal void UpdateContextMenuList(AnimationCurve curve) { List <ContextMenuStruct> listContextMenus = new List <ContextMenuStruct>(); foreach (Keyframe keyframe in curve.keys) { ContextMenuStruct contextMenuStruct = new ContextMenuStruct(); contextMenuStruct.freeSmooth = true; if (IsKeyframeFlat(keyframe)) { contextMenuStruct.flat = true; } listContextMenus.Add(contextMenuStruct); } dictCurvesContextMenus[curve] = listContextMenus; }
static internal void LoadData(string configName, Object obj, CurveWindow crvWindow, Transform collTransf, CurveLines crvLines, List <CurveStruct> curveStructList, Dictionary <AnimationCurve, List <ContextMenuStruct> > dictCurvesContextMenus) { string data = PlayerPrefs.GetString(configName); string[] elements = data.Split(':'); int i = 1;//first element should be empty string Vector3 locPos = Vector3.zero; locPos.x = float.Parse(elements[i]); i += 1; locPos.y = float.Parse(elements[i]); i += 1; locPos.z = float.Parse(elements[i]); i += 1; crvWindow.transform.localPosition = locPos; collTransf.localPosition = locPos; Vector3 locScale = Vector3.zero; locScale.x = float.Parse(elements[i]); i += 1; locScale.y = float.Parse(elements[i]); i += 1; locScale.z = float.Parse(elements[i]); i += 1; crvWindow.transform.localScale = locScale; collTransf.localScale = locScale; crvWindow.windowClosed = (int.Parse(elements[i]) == 1); i += 1; int curveStrCount = int.Parse(elements[i]); i += 1; string name; AnimationCurve activeCurve = null; for (int k = 0; k < curveStrCount; ++k) { bool isPair = (int.Parse(elements[i]) == 1); i += 1; name = elements[i]; i += 1; int length = int.Parse(elements[i]); i += 1; FieldInfo fieldInfo = obj.GetType().GetField(name); AnimationCurve curve = fieldInfo.GetValue(obj) as AnimationCurve; if (length > 0) { if (curve == null) { curve = new AnimationCurve(); //the curve is null,but after loading won't be } while (curve.length > 0) { curve.RemoveKey(0); } for (int j = 0; j < length; ++j) { //Debug.Log("curve data:"+elements[i+2]+" "+elements[i+3]+" "+elements[i]+" "+elements[i+1]); Keyframe key = new Keyframe(float.Parse(elements[i + 2]), float.Parse(elements[i + 3]), float.Parse(elements[i]), float.Parse(elements[i + 1])); curve.AddKey(key); i += 4; } bool isActiveCurveStr = (int.Parse(elements[i]) == 1); if (isActiveCurveStr) { activeCurve = curve; } i += 1; bool firstCurveSelected = bool.Parse(elements[i]); i += 1; Rect loadGradRect = new Rect(); loadGradRect.x = float.Parse(elements[i]); i += 1; loadGradRect.y = float.Parse(elements[i]); i += 1; loadGradRect.width = float.Parse(elements[i]); i += 1; loadGradRect.height = float.Parse(elements[i]); i += 1; if (elements[i] == "") { i += 1; } int length2 = 0; AnimationCurve curve2 = null; if (isPair) { name = elements[i]; i += 1; length2 = int.Parse(elements[i]); i += 1; FieldInfo fieldInfo2 = obj.GetType().GetField(name); curve2 = fieldInfo2.GetValue(obj) as AnimationCurve; if (length2 > 0) { if (curve2 == null) { curve2 = new AnimationCurve(); //the curve is null,but after loading won't be } while (curve2.length > 0) { curve2.RemoveKey(0); } for (int j = 0; j < length2; ++j) { //Debug.Log("curve data:"+elements[i+2]+" "+elements[i+3]+" "+elements[i]+" "+elements[i+1]); Keyframe key = new Keyframe(float.Parse(elements[i + 2]), float.Parse(elements[i + 3]), float.Parse(elements[i]), float.Parse(elements[i + 1])); curve2.AddKey(key); i += 4; } } else { curve2 = null; } fieldInfo2.SetValue(obj, curve2); if (elements[i] == "") { i += 1; } } crvLines.AddCurveStruct(curve, curve2); crvLines.gradRect = loadGradRect; dictCurvesContextMenus[curve].Clear(); for (int j = 0; j < length; ++j) { ContextMenuStruct contextMenu = new ContextMenuStruct(); contextMenu.UnpackData(elements[i]); dictCurvesContextMenus[curve].Add(contextMenu); i += 1; } if (elements[i] == "") { i += 1; } if (null != curve2) { dictCurvesContextMenus[curve2].Clear(); for (int j = 0; j < length2; ++j) { ContextMenuStruct contextMenu = new ContextMenuStruct(); contextMenu.UnpackData(elements[i]); dictCurvesContextMenus[curve2].Add(contextMenu); i += 1; } if (!firstCurveSelected) { CurveStruct crvStruct = curveStructList.Find(x => x.curve1 == curve); crvStruct.firstCurveSelected = false; crvLines.UpdateCurveStruct(crvStruct); } if (elements[i] == "") { i += 1; } } } //if else //the curve is not null,but after loading saved data,it will be { curve = null; } fieldInfo.SetValue(obj, curve); } //for CrvStrCount crvLines.ChangeActiveCurve(activeCurve); FieldInfo[] fields = obj.GetType().GetFields(); foreach (FieldInfo field in fields) { if (field.FieldType == typeof(AnimationCurve)) { AnimationCurve curve = field.GetValue(obj) as AnimationCurve; if (curveStructList.Find(x => x.curve1 == curve).curve1 == null && curveStructList.Find(x => x.curve2 == curve).curve2 == null) { //these is a curve not added to editor curve name = elements[i]; i += 1; int length = int.Parse(elements[i]); i += 1; if (curve == null) { curve = new AnimationCurve(); //the curve is null,but after loading won't be } while (curve.length > 0) { curve.RemoveKey(0); } for (int j = 0; j < length; ++j) { Keyframe key = new Keyframe(float.Parse(elements[i + 2]), float.Parse(elements[i + 3]), float.Parse(elements[i]), float.Parse(elements[i + 1])); curve.AddKey(key); i += 4; } if (elements[i] == "") { i += 1; } field.SetValue(obj, curve); } } } PlayerPrefs.SetString(lastFileLoaded, configName); PlayerPrefs.Save(); }
static void DrawOneCurve(Color color, AnimationCurve curve, bool activeCurve, int selectedKey, Rect gridRect, Rect gradRect, bool isIcon = false, float clip = 1.0f) { float margin = CurveLines.marginNoDpi * 0.6f; for (int i = 0; i < curve.length; ++i) { Vector2 val = new Vector2(curve[i].time, curve[i].value); val = CurveLines.Convert(val, gridRect, gradRect); //outside of the interval,just draw straigt lines outside from the 1st and last key respectively if (i == 0 && curve.keys[i].time > gradRect.xMin) { GL.Begin(GL.LINES); //GL.Color(color); lineMaterial.color = color; lineMaterial.SetPass(0); GL.Vertex3(gridRect.xMin, val.y, mZ); GL.Vertex3(val.x, val.y, mZ); GL.End(); } if (i == curve.length - 1 && curve.keys[i].time < gradRect.xMax) { GL.Begin(GL.LINES); //GL.Color(color); lineMaterial.color = color; lineMaterial.SetPass(0); GL.Vertex3(val.x, val.y, mZ); GL.Vertex3(gridRect.xMax, val.y, mZ); GL.End(); } if (curve.length > i + 1) { //draw bezier between consecutive keys Vector2 val2 = new Vector2(curve[i + 1].time, curve[i + 1].value); val2 = CurveLines.Convert(val2, gridRect, gradRect); Vector2 c1 = Vector2.zero; Vector2 c2 = Vector2.zero; float tangOut = curve[i].outTangent; float tangIn = curve[i + 1].inTangent; float ratio = (gridRect.height / gridRect.width) * (gradRect.width / gradRect.height); float tangOutScaled = Mathf.Atan(tangOut * ratio); float tangInScaled = Mathf.Atan(tangIn * ratio); if (tangOut != float.PositiveInfinity && tangIn != float.PositiveInfinity) { GetControlPoints(val, val2, tangOut * ratio, tangIn * ratio, out c1, out c2); int samples = (int)(Screen.height * 0.5f * (val2.x - val.x)); DrawBezier(curve, color, samples, val, c1, c2, val2, gridRect, gradRect, clip); } else { DrawConstant(color, val, val2); } if (activeCurve) { if (selectedKey == i) { ContextMenuStruct contextMenu = dictCurvesContextMenus[curve][selectedKey]; if (!contextMenu.auto && (!contextMenu.broken || contextMenu.rightTangent.free)) { Vector2 tangPeak = new Vector2(val.x + CurveLines.tangFixedLength * Mathf.Cos(tangOutScaled), val.y + CurveLines.tangFixedLength * Mathf.Sin(tangOutScaled)); GL.Begin(GL.LINES); lineMaterial.color = Color.gray; lineMaterial.SetPass(0); GL.Vertex3(val.x, val.y, mZ); GL.Vertex3(tangPeak.x, tangPeak.y, mZ); GL.End(); DrawQuad(Color.gray, tangPeak, margin); } } if (selectedKey == i + 1) { ContextMenuStruct contextMenu = dictCurvesContextMenus[curve][selectedKey]; if (!contextMenu.auto && (!contextMenu.broken || contextMenu.leftTangent.free)) { Vector2 tangPeak = new Vector2(val2.x - CurveLines.tangFixedLength * Mathf.Cos(tangInScaled), val2.y - CurveLines.tangFixedLength * Mathf.Sin(tangInScaled)); GL.Begin(GL.LINES); lineMaterial.color = Color.gray; lineMaterial.SetPass(0); GL.Vertex3(val2.x, val2.y, mZ); GL.Vertex3(tangPeak.x, tangPeak.y, mZ); GL.End(); DrawQuad(Color.gray, tangPeak, margin); } } } } if (activeCurve) { if (selectedKey == i) { DrawQuad(lightGray, val, 1.33333f * margin); } } if (!isIcon) { DrawQuad(color, val, margin); } } }