/// <summary> /// The Editing handles are used to manipulate and resize ProBuilderShapes /// These handles are used in 2 tools : EditShapeTool and DrawShapeTool. In this second tool, /// these handles allow to modified the last created shape. /// </summary> /// <param name="proBuilderShape">The Shape on which to attach the handles</param> /// <param name="updatePrefs">Parameter used to update the DrawShapeTool when needed</param> internal static void DoEditingHandles(ProBuilderShape proBuilderShape, bool updatePrefs = false) { if (proBuilderShape == null) { return; } var scale = proBuilderShape.transform.lossyScale; var position = proBuilderShape.transform.position + Vector3.Scale(proBuilderShape.transform.TransformDirection(proBuilderShape.shapeBox.center), scale); var matrix = Matrix4x4.TRS(position, proBuilderShape.transform.rotation, Vector3.one); using (new Handles.DrawingScope(matrix)) { EditorShapeUtility.UpdateFaces(proBuilderShape.editionBounds, scale, faces); for (int i = 0; i < 4; ++i) { k_OrientationControlIDs[i] = GUIUtility.GetControlID(FocusType.Passive); } for (int i = 0; i < faces.Length; ++i) { s_FaceControlIDs[i] = GUIUtility.GetControlID(FocusType.Passive); } var absSize = Math.Abs(proBuilderShape.editionBounds.size); if (absSize.x > Mathf.Epsilon && absSize.y > Mathf.Epsilon && absSize.z > Mathf.Epsilon) { DoOrientationHandles(proBuilderShape, updatePrefs); } DoSizeHandles(proBuilderShape, updatePrefs); } }
static void DoSizeHandles(ProBuilderShape proBuilderShape, bool updatePrefs) { int faceCount = s_Faces.Length; var evt = Event.current; var is2D = proBuilderShape.shape is Plane || proBuilderShape.shape is Sprite; for (int i = 0; i < faceCount; i++) { var face = faces[i]; if (is2D && !face.IsValid) { continue; } if (Event.current.type == EventType.Repaint) { Color color = k_BoundsHandleColor; color.a *= face.IsVisible ? 1f : 0.5f; using (new Handles.DrawingScope(color)) { int pointsCount = face.Points.Length; for (int k = 0; k < pointsCount; k++) { Handles.DrawLine(face.Points[k], face.Points[(k + 1) % pointsCount]); } } } if (DoFaceSizeHandle(face, s_FaceControlIDs[i])) { if (!s_SizeManipulationInit) { s_StartCenter = proBuilderShape.transform.position + proBuilderShape.transform.TransformVector(proBuilderShape.shapeBox.center); s_StartScale = proBuilderShape.transform.lossyScale; s_StartScaleInverse = new Vector3(1f / Mathf.Abs(s_StartScale.x), 1f / Mathf.Abs(s_StartScale.y), 1f / Mathf.Abs(s_StartScale.z)); s_StartPositionLocal = face.CenterPosition; s_StartPositionGlobal = proBuilderShape.transform.TransformPoint(Vector3.Scale(face.CenterPosition, s_StartScale)); s_StartSize = proBuilderShape.size; s_SizeManipulationInit = true; s_Scaling = Vector3.Scale(face.Normal, Math.Sign(s_StartSize)); } var targetSize = s_StartSize; if (Math.IsCardinalAxis(proBuilderShape.transform.up) && EditorSnapSettings.gridSnapEnabled && !EditorSnapSettings.incrementalSnapActive && !evt.alt) { var faceDelta = (s_SizeDelta * s_Faces[i].Normal); var facePosition = s_StartPositionGlobal + faceDelta; facePosition = ProBuilderSnapping.Snap(facePosition, EditorSnapping.activeMoveSnapValue); targetSize += Vector3.Scale((facePosition - s_StartPositionGlobal), s_Scaling); } else { //Should we expand on the 2 sides? var modifier = evt.alt ? 2f : 1f; var delta = modifier * (s_SizeDelta * s_Faces[i].Normal); delta.Scale(s_Scaling); delta.Scale(s_StartScaleInverse); targetSize += delta; var snap = EditorSnapSettings.incrementalSnapActive ? Vector3.Scale(EditorSnapping.activeMoveSnapValue, Math.Abs(face.Normal)) : Vector3.zero; targetSize = ProBuilderSnapping.Snap(targetSize, snap); } var center = Vector3.zero; if (!evt.alt) { center = Vector3.Scale((targetSize - s_StartSize) / 2f, s_Scaling); center = Vector3.Scale(center, Math.Sign(s_StartScale)); center = proBuilderShape.transform.TransformVector(center); } ApplyProperties(proBuilderShape, s_StartCenter + center, targetSize); if (updatePrefs) { DrawShapeTool.SaveShapeParams(proBuilderShape); } } } }