internal static Vector3 DoPositionHandle(PositionHandleIds ids, Vector3 position, Quaternion rotation) { Event evt = Event.current; switch (evt.type) { case EventType.KeyDown: // Holding 'V' turns on the FreeMove transform gizmo and enables vertex snapping. if (evt.keyCode == Tools.vertexDraggingShortcutEvent.keyCode && evt.modifiers == Tools.vertexDraggingShortcutEvent.modifiers && !currentlyDragging) { s_FreeMoveMode = true; } break; case EventType.KeyUp: // If the user has released the 'V' key, then rendering the transform gizmo // one last time with Free Move mode off is technically incorrect since it can // add one additional frame of input with FreeMove enabled, but the // implementation is a fair bit simpler this way. // Basic idea: Leave this call above the 'if' statement. position = DoPositionHandle_Internal(ids, position, rotation, PositionHandleParam.DefaultHandle); if (evt.keyCode == Tools.vertexDraggingShortcutEvent.keyCode && evt.modifiers == Tools.vertexDraggingShortcutEvent.modifiers && !evt.shift && !currentlyDragging) { s_FreeMoveMode = false; } return(position); case EventType.Layout: if (Tools.vertexDragging && !s_FreeMoveMode) { s_FreeMoveMode = true; } if (!currentlyDragging && !Tools.vertexDragging) { s_FreeMoveMode = evt.shift; } break; } var param = s_FreeMoveMode ? PositionHandleParam.DefaultFreeMoveHandle : PositionHandleParam.DefaultHandle; return(DoPositionHandle_Internal(ids, position, rotation, param)); }
static Vector3 DoPositionHandle_Internal(PositionHandleIds ids, Vector3 position, Quaternion rotation, PositionHandleParam param) { Color temp = color; bool isDisabled = !GUI.enabled; // Calculate the camera view vector in Handle draw space // this handle the case where the matrix is skewed var handlePosition = matrix.MultiplyPoint3x4(position); var drawToWorldMatrix = matrix * Matrix4x4.TRS(position, rotation, Vector3.one); var invDrawToWorldMatrix = drawToWorldMatrix.inverse; var viewVectorDrawSpace = GetCameraViewFrom(handlePosition, invDrawToWorldMatrix); var size = HandleUtility.GetHandleSize(position); // Calculate per axis camera lerp for (var i = 0; i < 3; ++i) { s_DoPositionHandle_Internal_CameraViewLerp[i] = ids[i] == GUIUtility.hotControl ? 0 : GetCameraViewLerpForWorldAxis(viewVectorDrawSpace, GetAxisVector(i)); } // Calculate per plane camera lerp (xy, yz, xz) for (var i = 0; i < 3; ++i) { s_DoPositionHandle_Internal_CameraViewLerp[3 + i] = Mathf.Max(s_DoPositionHandle_Internal_CameraViewLerp[i], s_DoPositionHandle_Internal_CameraViewLerp[(i + 1) % 3]); } var isHot = ids.Has(GUIUtility.hotControl); var axisOffset = param.axisOffset; var planeOffset = param.planeOffset; if (isHot) { axisOffset = Vector3.zero; planeOffset = Vector3.zero; } // Draw plane handles (xy, yz, xz) var planeSize = isHot ? param.planeSize + param.planeOffset : param.planeSize; for (var i = 0; i < 3; ++i) { if (!param.ShouldShow(3 + i) || isHot && ids[3 + i] != GUIUtility.hotControl) { continue; } var cameraLerp = isHot ? 0 : s_DoPositionHandle_Internal_CameraViewLerp[3 + i]; if (cameraLerp <= kCameraViewThreshold) { var offset = planeOffset * size; offset[s_DoPositionHandle_Internal_PrevIndex[i]] = 0; var planarSize = Mathf.Max(planeSize[i], planeSize[s_DoPositionHandle_Internal_NextIndex[i]]); position = DoPlanarHandle(ids[3 + i], i, position, offset, rotation, size * planarSize, cameraLerp, viewVectorDrawSpace, param.planeOrientation); } } // Draw axis sliders // Draw last to have priority over the planes for (var i = 0; i < 3; ++i) { if (!param.ShouldShow(i)) { continue; } if (!currentlyDragging) { switch (param.axesOrientation) { case PositionHandleParam.Orientation.Camera: s_DoPositionHandle_AxisHandlesOctant[i] = viewVectorDrawSpace[i] > 0.01f ? -1 : 1; break; case PositionHandleParam.Orientation.Signed: s_DoPositionHandle_AxisHandlesOctant[i] = 1; break; } } var isThisAxisHot = isHot && ids[i] == GUIUtility.hotControl; var axisColor = GetColorByAxis(i); color = isDisabled ? Color.Lerp(axisColor, staticColor, staticBlend) : axisColor; GUI.SetNextControlName(s_DoPositionHandle_Internal_AxisNames[i]); // if we are hot here, the hot handle must be opaque var cameraLerp = isThisAxisHot ? 0 : s_DoPositionHandle_Internal_CameraViewLerp[i]; if (cameraLerp <= kCameraViewThreshold) { color = Color.Lerp(color, Color.clear, cameraLerp); var axisVector = GetAxisVector(i); var dir = rotation * axisVector; var offset = dir * axisOffset[i] * size; dir *= s_DoPositionHandle_AxisHandlesOctant[i]; offset *= s_DoPositionHandle_AxisHandlesOctant[i]; if (isHot && !isThisAxisHot) { color = s_DisabledHandleColor; } // A plane with this axis is hot if (isHot && (ids[s_DoPositionHandle_Internal_PrevPlaneIndex[i]] == GUIUtility.hotControl || ids[i + 3] == GUIUtility.hotControl)) { color = selectedColor; } color = ToActiveColorSpace(color); s_DoPositionHandle_ArrowCapConeOffset = isHot ? rotation * Vector3.Scale(Vector3.Scale(axisVector, param.axisOffset), s_DoPositionHandle_AxisHandlesOctant) : Vector3.zero; position = Slider(ids[i], position, offset, dir, size * param.axisSize[i], DoPositionHandle_ArrowCap, GridSnapping.active ? 0f : EditorSnapSettings.move[i]); } } VertexSnapping.HandleMouseMove(ids.xyz); if (param.ShouldShow(PositionHandleParam.Handle.XYZ) && (isHot && ids.xyz == GUIUtility.hotControl || !isHot)) { color = ToActiveColorSpace(centerColor); GUI.SetNextControlName("FreeMoveAxis"); position = FreeMoveHandle(ids.xyz, position, rotation, size * kFreeMoveHandleSizeFactor, GridSnapping.active ? Vector3.zero : EditorSnapSettings.move, RectangleHandleCap); } if (GridSnapping.active) { position = GridSnapping.Snap(position); } color = temp; return(position); }
public TransformHandleIds(PositionHandleIds position, RotationHandleIds rotation, ScaleHandleIds scale) { this.position = position; this.rotation = rotation; this.scale = scale; }