public bool Has(int id) { return(position.Has(id) || rotation.Has(id) || scale.Has(id)); }
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 static Vector3 DrawHandles(Vector3 position, float zProjectionDistance, Quaternion rotation) { var isHot = ids.Has(GUIUtility.hotControl); var planeSize = isHot ? paramXY.planeSize + paramXY.planeOffset : paramXY.planeSize; var planarSize = Mathf.Max(planeSize[0], planeSize[s_DoPositionHandle_Internal_NextIndex[0]]); Vector3 sliderRotatedWorldPos = Quaternion.Inverse(rotation) * position; var size1D = HandleUtility.GetHandleSize(sliderRotatedWorldPos); var size2D = HandleUtility.GetHandleSize(sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance)) * planarSize * .5f; Vector3 depthSlider = sliderRotatedWorldPos; EditorGUI.BeginChangeCheck(); { // dot offset = transform position seen as a sphere EditorGUI.BeginChangeCheck(); depthSlider = Handles.Slider(depthSlider, Vector3.forward, size1D * .1f, Handles.SphereHandleCap, -1); if (EditorGUI.EndChangeCheck()) { sliderRotatedWorldPos.z = depthSlider.z; } // 2D slider: square xy-axis Vector3 sliderFaceProjected = sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance); sliderFaceProjected.x += size2D; sliderFaceProjected.y += size2D; using (new Handles.DrawingScope(Handles.zAxisColor)) { verts[0] = sliderFaceProjected + (Vector3.right + Vector3.up) * size2D; verts[1] = sliderFaceProjected + (-Vector3.right + Vector3.up) * size2D; verts[2] = sliderFaceProjected + (-Vector3.right - Vector3.up) * size2D; verts[3] = sliderFaceProjected + (Vector3.right - Vector3.up) * size2D; float faceOpacity = 0.8f; if (GUIUtility.hotControl == ids.xy) { Handles.color = Handles.selectedColor; } else if (IsHovering(ids.xy, Event.current)) { faceOpacity = 0.4f; } else { faceOpacity = 0.1f; } Color faceColor = new Color(Handles.zAxisColor.r, Handles.zAxisColor.g, Handles.zAxisColor.b, Handles.zAxisColor.a * faceOpacity); Handles.DrawSolidRectangleWithOutline(verts, faceColor, Color.clear); EditorGUI.BeginChangeCheck(); sliderFaceProjected = Handles.Slider2D(ids.xy, sliderFaceProjected, Vector3.forward, Vector3.right, Vector3.up, size2D, Handles.RectangleHandleCap, s_IsGridSnappingActive() ? Vector2.zero : new Vector2(EditorSnapSettings.move[0], EditorSnapSettings.move[1]), false); if (EditorGUI.EndChangeCheck()) { sliderRotatedWorldPos.x = sliderFaceProjected.x; sliderRotatedWorldPos.y = sliderFaceProjected.y; } } sliderFaceProjected.x -= size2D; sliderFaceProjected.y -= size2D; // 2D slider: x-axis EditorGUI.BeginChangeCheck(); using (new Handles.DrawingScope(Handles.xAxisColor)) sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.right); if (EditorGUI.EndChangeCheck()) { sliderRotatedWorldPos.x = sliderFaceProjected.x; } // 2D slider: y-axis EditorGUI.BeginChangeCheck(); using (new Handles.DrawingScope(Handles.yAxisColor)) sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.up); if (EditorGUI.EndChangeCheck()) { sliderRotatedWorldPos.y = sliderFaceProjected.y; } // depth: z-axis EditorGUI.BeginChangeCheck(); using (new Handles.DrawingScope(Handles.zAxisColor)) depthSlider = Handles.Slider(depthSlider, Vector3.forward); if (EditorGUI.EndChangeCheck()) { sliderRotatedWorldPos.z = depthSlider.z; } } if (EditorGUI.EndChangeCheck()) { position = rotation * sliderRotatedWorldPos; } return(position); }