void DrawTangentControl(int i)
        {
            SplineData.Point wp   = data.points[i];
            Vector3          hPos = wp.position + wp.tangent;

            Handles.color = tangentColor;
            Handles.DrawLine(wp.position, hPos);

            Quaternion rotation;

            if (Tools.pivotRotation == PivotRotation.Local)
            {
                rotation = Quaternion.identity;
            }
            else
            {
                rotation = Quaternion.Inverse(spline.transform.rotation);
            }

            float size = HandleUtility.GetHandleSize(hPos) * 0.1f;

            Handles.SphereHandleCap(0, hPos, rotation, size, EventType.Repaint);
            Vector3 newPos = Vector3.zero;

            if (Tools.current == Tool.Move)
            {
                EditorGUI.BeginChangeCheck();

                newPos = Handles.PositionHandle(hPos, rotation);

                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Edit Waypoint Tangent");
                    wp.tangent     = newPos - wp.position;
                    data.points[i] = wp;
                    if (updateMeshConstantly)
                    {
                        spline.OnChanged(true);
                    }
                    else
                    {
                        meshNeedsUpdate = true;
                    }
                }
            }
        }
        void InsertWaypointAtIndex(int indexA)
        {
            Vector3 pos     = Vector3.forward;
            Vector3 tangent = Vector3.right;
            float   roll    = 0;

            int numWaypoints = data.points.Length;

            if (indexA < 0)
            {
                indexA = numWaypoints - 1;
            }
            if (indexA >= 0)
            {
                int indexB = indexA + 1;
                if (data.closed && indexB >= numWaypoints)
                {
                    indexB = 0;
                }

                if (indexB >= numWaypoints)
                {
                    if (data.points[indexA].tangent.sqrMagnitude >= 0.0001f)
                    {
                        tangent = data.points[indexA].tangent;
                    }
                    pos  = data.points[indexA].position + tangent;
                    roll = data.points[indexA].roll;
                }
                else
                {
                    float interp = (0.5f + indexA) / data.max;
                    pos     = data.GetPointNonUniform(interp);
                    tangent = data.GetTangent(interp);
                    roll    = data.GetRoll(interp);
                }
            }
            Undo.RecordObject(spline, "Add waypoint");
            var wp = new SplineData.Point();

            wp.position = pos;
            wp.tangent  = tangent;
            wp.roll     = roll;
            ArrayUtility.Insert(ref data.points, indexA + 1, wp);
            pointList.index = indexA + 1;
        }
        void DrawPositionControl(int i)
        {
            SplineData.Point wp = data.points[i];
            Handles.color = pointColor;
            Quaternion rotation;

            if (Tools.current == Tool.Rotate || Tools.current == Tool.Scale)
            {
                rotation = data.GetPointRotation(i) * Quaternion.AngleAxis(data.points[i].roll, Vector3.forward);
            }
            else if (Tools.pivotRotation == PivotRotation.Local)
            {
                rotation = Quaternion.identity;
            }
            else
            {
                rotation = Quaternion.Inverse(spline.transform.rotation);
            }
            float size = HandleUtility.GetHandleSize(wp.position) * 0.1f;

            Handles.SphereHandleCap(0, wp.position, rotation, size, EventType.Repaint);

            if (Tools.current == Tool.Move)
            {
                EditorGUI.BeginChangeCheck();
                Vector3 pos = Handles.PositionHandle(wp.position, rotation);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Move Waypoint");
                    wp.position    = pos;
                    data.points[i] = wp;
                    if (updateMeshConstantly)
                    {
                        spline.OnChanged(true);
                    }
                    else
                    {
                        meshNeedsUpdate = true;
                    }
                }
            }
            else if (Tools.current == Tool.Rotate)
            {
                EditorGUI.BeginChangeCheck();
                Quaternion rot = Handles.RotationHandle(rotation, wp.position);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Edit Waypoint Tangent");
                    float f = wp.tangent.magnitude;
                    wp.tangent = rot * Vector3.forward * f;
                    float rollMod = (Quaternion.Inverse(rotation) * rot).eulerAngles.z;
                    rollMod = ((rollMod % 360) + 360) % 360;
                    if (rollMod > 180)
                    {
                        rollMod -= 360;
                    }
                    wp.roll       += rollMod;
                    data.points[i] = wp;
                    if (updateMeshConstantly)
                    {
                        spline.OnChanged(true);
                    }
                    else
                    {
                        meshNeedsUpdate = true;
                    }
                }
            }
            else if (Tools.current == Tool.Scale)
            {
                EditorGUI.BeginChangeCheck();
                float scale = Handles.ScaleSlider(wp.tangent.magnitude, wp.position, wp.tangent.normalized, Quaternion.identity, size * 10, 0);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Edit Waypoint Tangent");
                    float f = wp.tangent.magnitude;
                    wp.tangent     = wp.tangent.normalized * scale;
                    data.points[i] = wp;
                    if (updateMeshConstantly)
                    {
                        spline.OnChanged(true);
                    }
                    else
                    {
                        meshNeedsUpdate = true;
                    }
                }
            }
        }