private float ShowMidpointControls(Ferr2DPath aPath, int i, PathEditorUtil.Selection aSelection, Matrix4x4 aTransform, SerializedProperty aPathProp, float aCurrDistance)
    {
        EventType eType = Event.current.type;

        // calculate distance data for finding the midpoint
        float segmentDistance = aPath.GetDistanceBetween(i, PathUtil.WrapIndex(i + 1, aPath.Count, aPath.Closed));
        float nextDistance    = aCurrDistance + segmentDistance;
        float midDist         = aCurrDistance + (segmentDistance) / 2;

        // if we have no segment on the control vert, skip this midpoint
        if (aPath.Count <= 1 || (i == aPath.Count - 1 && !aPath.Closed))
        {
            return(nextDistance);
        }

        // find the midpoint of this line
        Vector2 midPoint       = aPath.GetPointAtDistance(midDist);
        Vector2 midNormal      = aPath.GetNormalAtDistance(midDist);
        Vector3 midWorldPoint  = aTransform.MultiplyPoint(midPoint);
        Vector3 midWorldNormal = aTransform.MultiplyVector(midNormal);
        float   midSize        = eType == EventType.Layout || eType == EventType.Repaint ? HandleUtility.GetHandleSize(midWorldPoint) : 0;

        // edge override button
        int direction = aPath.GetData(i).directionOverride;

        if (terrain.EdgeMode != Ferr2D_SectionMode.None && (i == activeSegment || aSelection.IsSegmentSelected(i, aPath.Count, aPath.Closed) || direction != (int)Ferr2DT_TerrainDirection.None))
        {
            if (Event.current.alt)
            {
                if (direction != (int)Ferr2DT_TerrainDirection.None && Handles.Button(midWorldPoint + midWorldNormal * midSize * sizeLargeHandle * 2, Quaternion.identity, midSize * sizeSmallHandle, midSize * sizeSmallHandle, Ferr2DT_Caps.CapDotReset))
                {
                    aSelection.EachSegment(i, aPath.Count, aPath.Closed, id => {
                        SerializedProperty overrideProp = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(id).FindPropertyRelative("directionOverride");
                        overrideProp.intValue           = (int)Ferr2DT_TerrainDirection.None;
                    });
                }
            }
            else
            {
                if (Handles.Button(midWorldPoint + midWorldNormal * midSize * sizeLargeHandle * 2, Quaternion.identity, midSize * sizeSmallHandle, midSize * sizeSmallHandle, Ferr2DT_Caps.GetEdgeCap(direction)))
                {
                    CycleEdgeOverride(aPathProp, i);
                    SerializedProperty cycledOverride = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(i).FindPropertyRelative("directionOverride");
                    aSelection.EachSegment(i, aPath.Count, aPath.Closed, id => {
                        SerializedProperty overrideProp = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(id).FindPropertyRelative("directionOverride");
                        overrideProp.intValue           = cycledOverride.intValue;
                    });
                }
            }
        }

        // new point button
        if (!Event.current.alt && i == activeSegment && Handles.Button(midWorldPoint, Quaternion.identity, midSize * sizeLargeHandle, midSize * sizeLargeHandle, Ferr2DT_Caps.CapDotPlus))
        {
            PathEditorUtil.AddPoint(aPathProp, midPoint, i + 1);
            ProcessNewPoint(aPathProp, i + 1);
        }

        return(nextDistance);
    }
    private void ShowPathGUI(Transform aTransform, Ferr2DPath aPath, SerializedProperty aPathProp)
    {
        EventType eType = Event.current.type;
        Matrix4x4 mat   = aTransform.localToWorldMatrix;

        // show the path and all its standard controls
        PathEditorUtil.OnSceneGUI(aTransform.localToWorldMatrix, aTransform.worldToLocalMatrix, aPathProp, aPath, true, ProcessNewPoint, ProcessRemovePoint, Path2D.Plane.XY, Ferr2DT_Menu.PathSnapMode, Ferr2DT_Menu.SmartSnap?Ferr2DT_Menu.SmartSnapDist:0, KeyCode.C, visuals);
        PathEditorUtil.Selection selection = PathEditorUtil.GetSelection(aPath);

        // find which segments and points are active
        FindActiveControls(aPath, mat, aTransform.worldToLocalMatrix);

        if (Ferr2DT_SceneOverlay.segmentLockMode)
        {
            ShowTexSegmentSelect(aPath, aPathProp, mat);
        }
        else
        {
            float currDistance = 0;
            for (int i = 0; i < aPath.Count; i++)
            {
                // show all the data at the control points
                ShowPointControls(aPath, i, selection, mat, aPathProp);

                // show midpoint controls
                currDistance = ShowMidpointControls(aPath, i, selection, mat, aPathProp, currDistance);
            }
        }

        // drag select has to happen last, otherwise it steals control ahead of the other handles
        ShowDragSelect(aPath, mat);
    }
    private void  ShowDragSelect(Ferr2DPath aPath, Matrix4x4 aTransform)
    {
        if (!Ferr2DT_Menu.DragSelect)
        {
            return;
        }

        // manually make a move widget, since we have to override Unity's widget
        Vector3 center = Vector3.zero;

        if (Tools.pivotMode == PivotMode.Center)
        {
            center = PathUtil.Average(aPath.GetPathRaw());
        }
        Vector3 newPos = Handles.DoPositionHandle(terrain.transform.position + center, Quaternion.identity) - center;

        if (newPos != terrain.transform.position)
        {
            Undo.RecordObject(terrain.transform, "Move Terrain Object");
            terrain.transform.position = newPos;
        }
        // execute the drag-select code
        PathEditorUtil.DoDragSelect(aTransform, aPath, new Rect(0, EditorGUIUtility.singleLineHeight, Screen.width, Screen.height - EditorGUIUtility.singleLineHeight), visuals);
    }