private void OnEnable() { spline = (SplineComponent)target; isEditingControlPoints = CreatePref(PrefIsEditing, false); isEditingRotation = CreatePref(PrefIsEditingRotation, false); isEditingScaling = CreatePref(PrefIsEditingScaling, false); showRoadVisualization = CreatePref(PrefRoadVisualization, false); selectedControlPoint = -1; selectedRotationPoint = -1; selectedScalingPoint = -1; }
static private T HandleEditButtons <T>(T values, ref int selected, SplineComponent spline, string insertLabel, InsertPoint <T> insert, string removeLabel, RemovePoint <T> remove) { if (GUILayout.Button(insertLabel)) { Undo.RecordObject(spline, insertLabel); values = insert(values, ref selected); } if (values != null && selected >= 0) { if (GUILayout.Button(removeLabel)) { Undo.RecordObject(spline, removeLabel); values = remove(values, ref selected); } } return(values); }
void DrawPointHandlers <T>(bool isUsed, T[] values, ref int selectedIndex, SplineComponent spline, string changeMessage, int idCountForDrawer, PointHandleDrawer <T> draw) where T : struct { if (IDBuffer.Length < idCountForDrawer) { IDBuffer = new int[idCountForDrawer]; } if (isUsed && values != null && values.Length > 0) { for (int i = 0; i < values.Length; ++i) { for (int j = 0; j < IDBuffer.Length; ++j) { IDBuffer[j] = (j < idCountForDrawer) ? GUIUtility.GetControlID(FocusType.Passive) : -1; } var value = values[i]; bool changed = draw(IDBuffer, ref value, i == selectedIndex); if (changed) { Undo.RecordObject(spline, changeMessage); values[i] = value; } foreach (var id in IDBuffer) { if (id == EditorGUIUtility.hotControl) { selectedIndex = i; } else if (id == -1) { break; } } } } }
static private int CalcPointCount(SplineComponent spline) => Mathf.Max(2, spline.SegmentCount * spline.SegmentLookupCount);
static private SplineModifier.ValueAtDistance <T>[] HandleDistanceValueEditButtons <T>(SplineModifier.ValueAtDistance <T>[] distValues, ref int selectedIndex, SplineComponent spline, string insertLabel, string removeLabel) where T : struct => HandleEditButtons(distValues, ref selectedIndex, spline, insertLabel, (SplineModifier.ValueAtDistance <T>[] values, ref int index) => { var newValues = new List <SplineModifier.ValueAtDistance <T> >(); if (values != null && values.Length > 0) { newValues.AddRange(values); } float distance = 0; T value = default; if (index < newValues.Count) { distance = (index < newValues.Count - 1) ? Mathf.Lerp(values[index].Distance, values[index + 1].Distance, 0.5f) : newValues[index].Distance + 1f; } if (index >= 0 && index < newValues.Count) { newValues.Insert(index + 1, new SplineModifier.ValueAtDistance <T>(distance, value)); } else { newValues.Add(new SplineModifier.ValueAtDistance <T>(distance, value)); } return(newValues.ToArray()); }, removeLabel, (SplineModifier.ValueAtDistance <T>[] values, ref int index) => { if (index < values.Length) { if (values.Length == 1) { index = -1; return(null); } var newValues = new List <SplineModifier.ValueAtDistance <T> >(values); newValues.RemoveAt(index); values = newValues.ToArray(); index = Mathf.Min(index, newValues.Count - 1); } return(values); } );
static private void HandleControlPointEditButtons(SplineComponent spline, ref int selected) => HandleEditButtons(spline, ref selected, spline, "Insert Point", (SplineComponent s, ref int index) => { if (s != null) { int count = s.ControlPointCount; if (count == 0) { index = 0; s.AddControlPoint(0, s.transform.position + Vector3.forward); } else { if (index >= 0 && index < count - 1) { s.AddControlPoint(index + 1, CurveHalfPoint(index, index + 1)); index = index + 1; } else { Vector3 lastPoint = CP(count - 1); Vector3 pos; if (count == 1) { pos = lastPoint + Vector3.right * PointAddDistance; } else { if (spline.Spline.IsClosed) { pos = CurveHalfPoint(count - 1, 0); } else { Vector3 delta = lastPoint - CP(count - 2); pos = lastPoint + ((delta.sqrMagnitude > 0) ? delta.normalized : Vector3.right) * PointAddDistance; } } s.AddControlPoint(count, pos); index = s.ControlPointCount - 1; } } } Vector3 CurveHalfPoint(int a, int b) => s.ArcCalculator.Calculate(ToFloat3Array(spline.ControlPoints), a, b, 0.5f, s.Spline.IsClosed); Vector3 CP(int i) => s.ControlPoints[i]; return(s); }, "Remove Point", (SplineComponent s, ref int index) => { if (index >= 0 && index < s.ControlPointCount) { s.RemoveControlPoint(index); index = -1; } return(s); } );