/// <summary> /// Draw a custom inspector for the selected point in the curve /// </summary> private void DrawSelectedPointInspector() { GUILayout.Label("Selected Point"); //point EditorGUI.BeginChangeCheck(); Vector3 point = EditorGUILayout.Vector3Field("Position", spline.GetControlpoint(selectedIndex)); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(spline, "Move Point"); EditorUtility.SetDirty(spline); spline.SetControlPoint(selectedIndex, handleTransform.InverseTransformPoint(point)); } //mode EditorGUI.BeginChangeCheck(); BezierPointMode.BezierControlPointMode mode = (BezierPointMode.BezierControlPointMode)EditorGUILayout.EnumPopup("Mode", spline.GetControlPointMode(selectedIndex)); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(spline, "Change Point Mode"); spline.SetControlPointmode(selectedIndex, mode); EditorUtility.SetDirty(spline); } }
/// <summary> /// Enforces the three types of point adjustements: /// Free: any point anywhere /// Aligned: Point opposite maintains distance while the moved points' distance is scaled. /// Mirrored: Changes made to adjusted point is reflected in the opposite point /// </summary> /// <param name="index"></param> private void EnforceMode(int index) { int modeIndex = (index + 1) / 3; BezierPointMode.BezierControlPointMode mode = modes[modeIndex]; //check if we should be doing anything if (mode == BezierPointMode.BezierControlPointMode.Free || !loop && (modeIndex == 0 || modeIndex == modeIndex - 1)) { return; } //calculate where the points we are adjusting are at int middleIndex = modeIndex * 3; int fixedIndex, enforcedIndex; //if we have the middle mpoit selected, leave the previous alone and enforce onto the other side if (index <= middleIndex) { fixedIndex = middleIndex - 1; if (fixedIndex < 0) { fixedIndex = points.Length - 2; } enforcedIndex = middleIndex + 1; if (enforcedIndex >= points.Length) { enforcedIndex = 1; } } //if we don't, keep the one we're at fixed and change the opposite side else { fixedIndex = middleIndex + 1; if (fixedIndex > points.Length) { fixedIndex = 1; } enforcedIndex = middleIndex - 1; if (enforcedIndex < 0) { enforcedIndex = points.Length - 2; } } //Mirrored. Vector3 middle = points[middleIndex]; Vector3 enforcedTangent = middle - points[fixedIndex]; //get the vector from middle to fixed (fixed - middle), then invert it //if we are aligned, make sure the new tangent is the same length as the old one if (mode == BezierPointMode.BezierControlPointMode.Aligned) { enforcedTangent = enforcedTangent.normalized * Vector3.Distance(middle, points[enforcedIndex]); //normalize, then multiply by distance of middle and old enforced point } points[enforcedIndex] = middle + enforcedTangent; //then add it to the middle to get the point }
/// <summary> /// Set a mode for the point /// </summary> /// <param name="index"></param> /// <param name="mode"></param> public void SetControlPointmode(int index, BezierPointMode.BezierControlPointMode mode) { int modeIndex = (index + 1) / 3; modes[modeIndex] = mode; //make sure the first and last modes are equal to each other in case we are looping if (loop) { if (modeIndex == 0) { modes[modes.Length - 1] = mode; } else if (modeIndex == modes.Length - 1) { modes[0] = mode; } } EnforceMode(index); }