/// <summary> /// sets the Mode of the control point /// </summary> /// <param name="index"></param> /// <param name="mode"></param> public void SetControlPointMode(int index, Bezier.BezierControlPointMode mode) { if (index < 0 || index > Points.Length - 1) { Debug.LogError($"Control Point index {index} is out of Bounds!"); return; } // get the mode int modeIndex = (index + 1) / 3; _modes[modeIndex] = mode; // keep this a loop if (IsLoop) { if (modeIndex == 0) { _modes[_modes.Length - 1] = mode; } else if (modeIndex == _modes.Length - 1) { _modes[0] = mode; } } // enforce mode EnforceMode(index); // presample if desired if (DoPresample) { Presample(); } }
// ######################## FUNCTIONALITY ######################## // /// <summary> /// Draws the Properties of the selected point /// </summary> protected override void DrawSelectedPointInspector() { base.DrawSelectedPointInspector(); EditorGUI.BeginChangeCheck(); Bezier.BezierControlPointMode mode = (Bezier.BezierControlPointMode) EditorGUILayout.EnumPopup("Mode", _spline.GetControlPointMode(SelectedIndex)); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(_spline, "Change Point Mode"); _spline.SetControlPointMode(SelectedIndex, mode); EditorUtility.SetDirty(_spline); if (AutoPresampleInEditMode) { _spline.Presample(); } } }
/// <summary> /// Makes sure that the Control Point modes on both sides of a segment point are the same /// </summary> /// <param name="index"></param> private void EnforceMode(int index) { // calculate the mode index and get the mode int modeIndex = (index + 1) / 3; Bezier.BezierControlPointMode mode = _modes[modeIndex]; // if the mode is FREE or we are not a loop and this is the start or end point of the spline, we don't need to do anything if (mode == Bezier.BezierControlPointMode.FREE || !IsLoop && (modeIndex == 0 || modeIndex == _modes.Length - 1)) { return; } // get the index of the middle point int middleIndex = modeIndex * 3; int fixedIndex, enforcedIndex; // if we are before the middle point, the point before that is the fixed point if (index <= middleIndex) { // set fixed index, considering looping fixedIndex = middleIndex - 1; if (fixedIndex < 0) { fixedIndex = Points.Length - 2; } // set the enforced index to the point after the middle point, considering looping enforcedIndex = middleIndex + 1; if (enforcedIndex >= Points.Length) { enforcedIndex = 1; } } else // if we are after the middle point, the point after that is the fixed point { // set fixed index, considering looping fixedIndex = middleIndex + 1; if (fixedIndex >= Points.Length) { fixedIndex = 1; } // set the enforced index to the point after the middle point, considering looping enforcedIndex = middleIndex - 1; if (enforcedIndex < 0) { enforcedIndex = Points.Length - 2; } } // get the middle point Vector3 middle = Points[middleIndex]; // calculate the tangent that should be used Vector3 enforcedTangent = middle - Points[fixedIndex]; // if we are in aligned mode, we need to calculate the length of the tangent if (mode == Bezier.BezierControlPointMode.ALIGNED) { enforcedTangent = enforcedTangent.normalized * Vector3.Distance(middle, Points[enforcedIndex]); } // set the enforced point Points[enforcedIndex] = middle + enforcedTangent; }