private Vector3 ClosestPointInEdge(IGUIState guiState, Vector2 mousePosition, int index)
        {
            if (GetShapeType() == ShapeType.Polygon)
            {
                var p0 = GetPoint(index).position;
                var p1 = NextControlPoint(index).position;
                var mouseWorldPosition = GUIToWorld(guiState, mousePosition);

                var dir1 = (mouseWorldPosition - p0);
                var dir2 = (p1 - p0);

                return(Mathf.Clamp01(Vector3.Dot(dir1, dir2.normalized) / dir2.magnitude) * dir2 + p0);
            }
            else if (GetShapeType() == ShapeType.Spline)
            {
                var   nextIndex = NextIndex(index);
                float t;
                return(BezierUtility.ClosestPointOnCurve(
                           GUIToWorld(guiState, mousePosition),
                           GetPoint(index).position,
                           GetPoint(nextIndex).position,
                           GetRightTangent(index),
                           GetLeftTangent(nextIndex),
                           out t));
            }

            return(Vector3.zero);
        }
        public void CreatePoint(int index, Vector3 position)
        {
            ClearSelection();

            if (editablePath.shapeType == ShapeType.Polygon)
            {
                editablePath.InsertPoint(index + 1, new ControlPoint()
                {
                    position = position
                });
            }
            else if (editablePath.shapeType == ShapeType.Spline)
            {
                var nextIndex    = NextIndex(index);
                var currentPoint = editablePath.GetPoint(index);
                var nextPoint    = editablePath.GetPoint(nextIndex);

                float t;
                var   closestPoint = BezierUtility.ClosestPointOnCurve(
                    position,
                    currentPoint.position,
                    nextPoint.position,
                    GetRightTangentPosition(index),
                    GetLeftTangentPosition(nextIndex),
                    out t);

                Vector3 leftStartPosition;
                Vector3 leftEndPosition;
                Vector3 leftStartTangent;
                Vector3 leftEndTangent;

                Vector3 rightStartPosition;
                Vector3 rightEndPosition;
                Vector3 rightStartTangent;
                Vector3 rightEndTangent;

                BezierUtility.SplitBezier(t, currentPoint.position, nextPoint.position, GetRightTangentPosition(index), GetLeftTangentPosition(nextIndex),
                                          out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent,
                                          out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent);

                var newPointIndex = index + 1;
                var newPoint      = new ControlPoint()
                {
                    position     = closestPoint,
                    leftTangent  = leftEndTangent,
                    rightTangent = rightStartTangent,
                    tangentMode  = TangentMode.Continuous
                };

                currentPoint.rightTangent = leftStartTangent;
                nextPoint.leftTangent     = rightEndTangent;

                if (currentPoint.tangentMode == TangentMode.Linear && nextPoint.tangentMode == TangentMode.Linear)
                {
                    newPoint.tangentMode           = TangentMode.Linear;
                    newPoint.localLeftTangent      = Vector3.zero;
                    newPoint.localRightTangent     = Vector3.zero;
                    currentPoint.localRightTangent = Vector3.zero;
                    nextPoint.localLeftTangent     = Vector3.zero;
                }
                else
                {
                    if (currentPoint.tangentMode == TangentMode.Linear)
                    {
                        currentPoint.tangentMode = TangentMode.Broken;
                    }

                    if (nextPoint.tangentMode == TangentMode.Linear)
                    {
                        nextPoint.tangentMode = TangentMode.Broken;
                    }
                }

                editablePath.SetPoint(index, currentPoint);
                editablePath.SetPoint(nextIndex, nextPoint);
                editablePath.InsertPoint(newPointIndex, newPoint);
            }
        }