Exemple #1
0
 public override void MoveHandleTo(PointF point, int handleNumber)
 {
     RemoveAnimation();
     base.MoveHandleTo(point, handleNumber);
     OnHandleMove?.Invoke(handleNumber);
     AddAnimation();
 }
Exemple #2
0
 public void HandleMove(InputAction.CallbackContext context)
 {
     OnHandleMove?.Invoke(context);
 }
Exemple #3
0
        private void InteractHandle()
        {
            //Set the starting point of the drag to the position of the handle
            drag.origin = parentTransform.position;

            //Reset the persistent variables of each tool
            prevPosition         = parentTransform.position;
            rotationDisplacement = 0f;
            prevScale            = scale;
            prevCursorDist       = currCursorDist;

            //Only rotate the handle if the mouse was moved
            if (mouseDisplacement.magnitude > 0f)
            {
                switch (Tool)
                {
                case Tool.Translate:
                    //If the plane translate is selected, use the whole hit point as the position of the handle
                    if (draggingAxes > 1)
                    {
                        //Get the position under the cursor but on the movement plane
                        Vector3 planeHit = GetMovementPlaneHit();

                        //If the position is not valid, don't move the tool handle
                        for (int axis = 0; axis < 3; axis++)
                        {
                            if (float.IsNaN(planeHit[axis]))
                            {
                                return;
                            }
                        }

                        //If the point is valid, move the tool handle to the point under the cursor
                        parentTransform.position = planeHit - drag.offset;
                    }
                    //If only one axis is selected, use the component of the mouse displacement parallel to the drag axis
                    else
                    {
                        //Get the displacement of the mouse in the handle's local space along the drag axis
                        Vector3 translationVector = GetDragDisplacement(mouseDisplacement);
                        //Scale the translation vector by the translation speed and distance to camera
                        translationVector *= cameraDist / 1000 * translationSpeed.GetSpeed();

                        //Translate the tool handle
                        parentTransform.Translate(translationVector, Space.Self);

                        //If any of the axes of the object went out of bounds, set it back to the maximum valid value
                        for (int axis = 0; axis < 3; axis++)
                        {
                            if (Mathf.Abs(parentTransform.position[axis]) > maxDistance)
                            {
                                //Get the sign of the current position
                                float positionSign = Mathf.Sign(parentTransform.position[axis]);

                                //Set the position to back in bounds
                                Vector3 fixedPosition = parentTransform.position;
                                fixedPosition[axis]      = maxDistance * positionSign;
                                parentTransform.position = fixedPosition;
                            }
                        }
                    }
                    break;

                case Tool.Rotate:
                    //Project the mouse displacement onto the tangent vector to get the component tangent to the rotation handle
                    Vector2 tangentDisplacement = ProjectBontoA(mouseDisplacement, clickTangent);
                    //Use the dot product between the tangent displacement and click tangent to get the sign of the rotation
                    sign = Vector2.Dot(tangentDisplacement, clickTangent) > 0 ? 1f : -1f;

                    //Use the magnitude of the displacement as the angle displacement
                    float angleDisplacement = tangentDisplacement.magnitude * sign;
                    //Add the displacement to the angle after scaling it by the rotation speed
                    rotationDisplacement = angleDisplacement / 10 * rotationSpeed.GetSpeed();
                    axisAngle           += rotationDisplacement;

                    //Rotate the tool handle
                    parentTransform.rotation = Quaternion.AngleAxis(axisAngle, drag.worldAxis) * handleOrigin.Rotation;

                    break;

                //If the tool isn't translate or rotate, it is scale
                default:
                    //Stores the scale factor of each axis
                    Vector3 scaleVector;

                    //If all axes are being dragged, scale based on the distance between the cursor and tool handle
                    if (draggingAxes > 1)
                    {
                        //Get the distance in screen space between the tool handle and the cursor
                        currCursorDist = GetMouseHandleDist(currentMousePosition + mouseOffest);
                        //Calculate the displacement of the distance since last frame
                        float displacement = currCursorDist - prevCursorDist;
                        //Multiply the drag axis by the displacement
                        scaleVector = new Vector3(displacement, displacement, displacement);
                    }
                    //If only one axis is being dragged, only use the mouse displacement parallel to the axis being dragged
                    else
                    {
                        scaleVector = GetDragDisplacement(mouseDisplacement);
                    }

                    //Scale the vector by the translation speed and distance to camera
                    scaleVector *= scaleSpeed.GetSpeed() / 100;

                    //Scale the axis of the scale vector by the scale displacement
                    for (int axis = 0; axis < 3; axis++)
                    {
                        if (scaleVector[axis] != 0)
                        {
                            scale[axis] += scaleVector[axis];
                        }
                    }

                    break;
                }
            }

            //Notify all listeners that the handle was moved
            OnHandleMove?.Invoke();
        }
        void Update()
        {
            if (IsHidden)
            {
                return;
            }

            if (Input.GetMouseButtonDown(0) && !Input.GetKey(KeyCode.LeftAlt))
            {
                OnMouseDown();
            }

            if (DraggingHandle)
            {
                if (Input.GetKey(KeyCode.LeftAlt))
                {
                    OnFinishHandleMovement();
                }

#if DEBUG
                Vector3 dir      = drag.axis * 2f;
                Color   col      = new Color(Mathf.Abs(drag.axis.x), Mathf.Abs(drag.axis.y), Mathf.Abs(drag.axis.z), 1f);
                float   lineTime = 0f;
                Debug.DrawRay(drag.origin, dir * 1f, col, lineTime, false);
                Debug.DrawLine(drag.origin + dir, (drag.origin + dir * .9f) + (Trs.up * .1f), col, lineTime, false);
                Debug.DrawLine(drag.origin + dir, (drag.origin + dir * .9f) + (Trs.forward * .1f), col, lineTime, false);
                Debug.DrawLine(drag.origin + dir, (drag.origin + dir * .9f) + (Trs.right * .1f), col, lineTime, false);
                Debug.DrawLine(drag.origin + dir, (drag.origin + dir * .9f) + (-Trs.up * .1f), col, lineTime, false);
                Debug.DrawLine(drag.origin + dir, (drag.origin + dir * .9f) + (-Trs.forward * .1f), col, lineTime, false);
                Debug.DrawLine(drag.origin + dir, (drag.origin + dir * .9f) + (-Trs.right * .1f), col, lineTime, false);

                Debug.DrawLine(drag.origin, drag.origin + drag.mouse, Color.red, lineTime, false);
                Debug.DrawLine(drag.origin, drag.origin + drag.cross, Color.black, lineTime, false);
#endif
            }

            if (Input.GetMouseButton(0) && DraggingHandle)
            {
                Vector3 a = Vector3.zero;

                bool valid = false;

                if (draggingAxes < 2 && tool != Tool.Rotate)
                {
                    valid = pb_HandleUtility.PointOnLine(new Ray(Trs.position, drag.axis), Cam.ScreenPointToRay(Input.mousePosition), out a, out Vector3 b);
                }
                else
                {
                    Ray ray = Cam.ScreenPointToRay(Input.mousePosition);
                    if (drag.plane.Raycast(ray, out float hit))
                    {
                        a     = ray.GetPoint(hit);
                        valid = true;
                    }
                }

                if (valid)
                {
                    drag.origin = Trs.position;

                    switch (tool)
                    {
                    case Tool.Position:
                    {
                        Trs.position = pb_Snap.Snap(a - drag.offset, positionSnapValue);
                    }
                    break;

                    case Tool.Rotate:
                    {
                        Vector2 delta = (Vector2)Input.mousePosition - mouseOrigin;
                        mouseOrigin = Input.mousePosition;
                        float sign = pb_HandleUtility.CalcMouseDeltaSignWithAxes(Cam, drag.origin, drag.axis, drag.cross, delta);
                        axisAngle        += delta.magnitude * sign;
                        Trs.localRotation = Quaternion.AngleAxis(pb_Snap.Snap(axisAngle, rotationSnapValue), drag.axis) * handleOrigin.Rotation;                        // trs.localRotation;
                    }
                    break;

                    case Tool.Scale:
                    {
                        Vector3 v;

                        if (draggingAxes > 1)
                        {
                            v = SetUniformMagnitude(((a - drag.offset) - Trs.position));
                        }
                        else
                        {
                            v = Quaternion.Inverse(handleOrigin.Rotation) * ((a - drag.offset) - Trs.position);
                        }

                        v    += Vector3.one;
                        scale = pb_Snap.Snap(v, scaleSnapValue);
                        RebuildGizmoMesh(scale);
                    }
                    break;
                    }

                    OnHandleMove?.Invoke(GetTransform());

                    RebuildGizmoMatrix();
                }
            }

            if (Input.GetMouseButtonUp(0))
            {
                OnFinishHandleMovement();
            }
        }