Esempio n. 1
0
        void DrawHandle(int i)
        {
            Vector3 handlePosition = MathUtility.TransformPoint(bezierPath[i], creator.transform, bezierPath.Space);

            float anchorHandleSize  = GetHandleDiameter(globalDisplaySettings.anchorSize * data.bezierHandleScale, bezierPath[i]);
            float controlHandleSize = GetHandleDiameter(globalDisplaySettings.controlSize * data.bezierHandleScale, bezierPath[i]);

            bool  isAnchorPoint     = i % 3 == 0;
            bool  isInteractive     = isAnchorPoint || bezierPath.ControlPointMode != BezierPath.ControlMode.Automatic;
            float handleSize        = (isAnchorPoint) ? anchorHandleSize : controlHandleSize;
            bool  doTransformHandle = i == handleIndexToDisplayAsTransform;

            PathHandle.HandleColours handleColours = (isAnchorPoint) ? splineAnchorColours : splineControlColours;
            if (i == handleIndexToDisplayAsTransform)
            {
                handleColours.defaultColour = (isAnchorPoint) ? globalDisplaySettings.anchorSelected : globalDisplaySettings.controlSelected;
            }
            var cap = capFunctions[(isAnchorPoint) ? globalDisplaySettings.anchorShape : globalDisplaySettings.controlShape];

            PathHandle.HandleInputType handleInputType;
            handlePosition = PathHandle.DrawHandle(handlePosition, bezierPath.Space, isInteractive, handleSize, cap, handleColours, out handleInputType, i);

            if (doTransformHandle)
            {
                // Show normals rotate tool
                if (data.showNormals && Tools.current == Tool.Rotate && isAnchorPoint && bezierPath.Space == PathSpace.xyz)
                {
                    Handles.color = handlesStartCol;

                    int     attachedControlIndex = (i == bezierPath.NumPoints - 1) ? i - 1 : i + 1;
                    Vector3 dir             = (bezierPath[attachedControlIndex] - handlePosition).normalized;
                    float   handleRotOffset = (360 + bezierPath.GlobalNormalsAngle) % 360;
                    anchorAngleHandle.radius = handleSize * 3;
                    anchorAngleHandle.angle  = handleRotOffset + bezierPath.GetAnchorNormalAngle(i / 3);
                    Vector3   handleDirection = Vector3.Cross(dir, Vector3.up);
                    Matrix4x4 handleMatrix    = Matrix4x4.TRS(
                        handlePosition,
                        Quaternion.LookRotation(handleDirection, dir),
                        Vector3.one
                        );

                    using (new Handles.DrawingScope(handleMatrix)) {
                        // draw the handle
                        EditorGUI.BeginChangeCheck();
                        anchorAngleHandle.DrawHandle();
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject(creator, "Set angle");
                            bezierPath.SetAnchorNormalAngle(i / 3, anchorAngleHandle.angle - handleRotOffset);
                        }
                    }
                }
                else
                {
                    handlePosition = Handles.DoPositionHandle(handlePosition, Quaternion.identity);
                }
            }

            switch (handleInputType)
            {
            case PathHandle.HandleInputType.LMBDrag:
                draggingHandleIndex             = i;
                handleIndexToDisplayAsTransform = -1;
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBRelease:
                draggingHandleIndex             = -1;
                handleIndexToDisplayAsTransform = -1;
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBClick:
                draggingHandleIndex = -1;
                if (Event.current.shift)
                {
                    handleIndexToDisplayAsTransform = -1;     // disable move tool if new point added
                }
                else
                {
                    if (handleIndexToDisplayAsTransform == i)
                    {
                        handleIndexToDisplayAsTransform = -1;     // disable move tool if clicking on point under move tool
                    }
                    else
                    {
                        handleIndexToDisplayAsTransform = i;
                    }
                }
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBPress:
                if (handleIndexToDisplayAsTransform != i)
                {
                    handleIndexToDisplayAsTransform = -1;
                    Repaint();
                }
                break;
            }

            Vector3 localHandlePosition = MathUtility.InverseTransformPoint(handlePosition, creator.transform, bezierPath.Space);

            if (bezierPath[i] != localHandlePosition)
            {
                Undo.RecordObject(creator, "Move point");
                bezierPath.MovePoint(i, localHandlePosition);
            }
        }
Esempio n. 2
0
        void DrawHandle(int i)
        {
            Vector3 handlePosition = bezierPath[i];

            float anchorHandleSize  = GetHandleDiameter(globalDisplaySettings.anchorSize * data.bezierHandleScale, bezierPath[i]);
            float controlHandleSize = GetHandleDiameter(globalDisplaySettings.controlSize * data.bezierHandleScale, bezierPath[i]);

            bool  isAnchorPoint     = i % 3 == 0;
            bool  isInteractive     = isAnchorPoint || bezierPath.ControlPointMode != BezierPath.ControlMode.Automatic;
            float handleSize        = (isAnchorPoint) ? anchorHandleSize : controlHandleSize;
            bool  doTransformHandle = i == handleIndexToDisplayAsTransform;

            PathHandle.HandleColours handleColours = (isAnchorPoint) ? splineAnchorColours : splineControlColours;
            if (i == handleIndexToDisplayAsTransform)
            {
                handleColours.defaultColour = (isAnchorPoint) ? globalDisplaySettings.anchorSelected : globalDisplaySettings.controlSelected;
            }
            var cap = capFunctions[(isAnchorPoint) ? globalDisplaySettings.anchorShape : globalDisplaySettings.controlShape];

            PathHandle.HandleInputType handleInputType;
            handlePosition = PathHandle.DrawHandle(handlePosition, bezierPath.Space, isInteractive, handleSize, cap, handleColours, out handleInputType, i);

            if (doTransformHandle)
            {
                // Show normals rotate tool
                if (data.showNormals && Tools.current == Tool.Rotate && isAnchorPoint && bezierPath.Space == PathSpace.xyz)
                {
                    Handles.color = handlesStartCol;

                    int     attachedControlIndex = (i == bezierPath.NumPoints - 1) ? i - 1 : i + 1;
                    Vector3 dir             = (bezierPath[attachedControlIndex] - handlePosition).normalized;
                    float   handleRotOffset = (360 + bezierPath.GlobalNormalsAngle) % 360;
                    anchorAngleHandle.radius = handleSize * 3;
                    anchorAngleHandle.angle  = handleRotOffset + bezierPath.GetAnchorNormalAngle(i / 3);
                    Vector3   handleDirection = Vector3.Cross(dir, Vector3.up);
                    Matrix4x4 handleMatrix    = Matrix4x4.TRS(
                        handlePosition,
                        Quaternion.LookRotation(handleDirection, dir),
                        Vector3.one
                        );

                    using (new Handles.DrawingScope(handleMatrix)) {
                        // draw the handle
                        EditorGUI.BeginChangeCheck();
                        anchorAngleHandle.DrawHandle();
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject(creator, "Set angle");
                            bezierPath.SetAnchorNormalAngle(i / 3, anchorAngleHandle.angle - handleRotOffset);
                        }
                    }
                }
                else
                {
                    handlePosition = Handles.DoPositionHandle(handlePosition, Quaternion.identity);
                }
            }

            switch (handleInputType)
            {
            case PathHandle.HandleInputType.LMBDrag:
                draggingHandleIndex             = i;
                handleIndexToDisplayAsTransform = -1;
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBRelease:
                draggingHandleIndex             = -1;
                handleIndexToDisplayAsTransform = -1;
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBClick:
                if (Event.current.shift)
                {
                    handleIndexToDisplayAsTransform = -1;     // disable move tool if new point added
                }
                else
                {
                    if (handleIndexToDisplayAsTransform == i)
                    {
                        handleIndexToDisplayAsTransform = -1;     // disable move tool if clicking on point under move tool
                    }
                    else
                    {
                        handleIndexToDisplayAsTransform = i;
                    }
                }
                Repaint();
                break;

            case PathHandle.HandleInputType.LMBPress:
                if (handleIndexToDisplayAsTransform != i)
                {
                    handleIndexToDisplayAsTransform = -1;
                    Repaint();
                }
                break;
            }

            if (bezierPath[i] != handlePosition)
            {
                Undo.RecordObject(creator, "Move point");
                bezierPath.MovePoint(i, handlePosition);

                // If the use is holding alt, try and mirror the control point.
                if (Event.current.modifiers == EventModifiers.Alt)
                {
                    // 0 = Anchor, 1 = Left Control, 2 = Right Control
                    var pointType = i % 3;

                    // If we are selecting a control point
                    if (pointType != 0)
                    {
                        // If we are selecting the left control point
                        if (pointType == 2)
                        {
                            // If the path doesn't loop and the user is selecting the last control point there isn't a control point to mirror
                            if (i < bezierPath.NumPoints - 2 && !bezierPath.IsClosed)
                            {
                                return;
                            }
                            // Get the index of this control's anchor.
                            var anchorIndex = (i + 1) % bezierPath.NumPoints;
                            var anchorPoint = bezierPath[anchorIndex];
                            // Get the index of the anchors other control.
                            // We don't have to loop this index b/c if it's the last control, it's anchors index will be 1.
                            var otherControlPointIndex = anchorIndex + 1;
                            // Move the other control point to the opposite of the selected control point's position relative to it's anchor.
                            bezierPath.MovePoint(otherControlPointIndex, anchorPoint - (handlePosition - anchorPoint));
                        }
                        // If we are selecting the right control point
                        else if (pointType == 1)
                        {
                            // If the path doesn't loop and the user is selecting the first control point there isn't a control point to mirror.
                            if (i > 1 && !bezierPath.IsClosed)
                            {
                                return;
                            }
                            // Get the index of this control's anchor.
                            var anchorIndex = i - 1;
                            var anchorPoint = bezierPath[anchorIndex];
                            // Get the index of the anchors other control.
                            var otherControlPointIndex = anchorIndex - 1;
                            // Make sure to loop this index back around if it is < 1.
                            if (otherControlPointIndex < 0)
                            {
                                otherControlPointIndex = bezierPath.NumPoints - Mathf.Abs(otherControlPointIndex);
                            }
                            // Move the other control point to the opposite of the selected control point's position relative to it's anchor.
                            bezierPath.MovePoint(otherControlPointIndex, anchorPoint - (handlePosition - anchorPoint));
                        }
                    }
                }
            }
        }