public override void MoveHandleTo(PointF point, int handleNumber) { RemoveAnimation(); base.MoveHandleTo(point, handleNumber); OnHandleMove?.Invoke(handleNumber); AddAnimation(); }
public void HandleMove(InputAction.CallbackContext context) { OnHandleMove?.Invoke(context); }
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(); } }