private void DrawSelectedSplineHandle(Spline instance, int point_index) { var splinePoint = instance.Points[point_index]; Handles.color = Color.white; var anyMoved = false; var anyRotated = false; var anyScaled = false; var splinePointDelta = Vector3.zero; if (instance.GetSplineSpace() == Space.Self) { splinePoint = instance.TransformSplinePoint(splinePoint); } switch (Tools.current) { case Tool.Move: anyMoved = DrawHandle(Vector3.zero, ref splinePoint.position, out splinePointDelta); break; case Tool.Rotate: anyRotated = DrawHandleRotation(splinePoint.position, ref splinePoint.rotation); break; case Tool.Scale: anyScaled = DrawHandleScale(splinePoint.position, ref splinePoint.scale); break; } if (instance.GetSplineSpace() == Space.Self) { splinePoint = instance.InverseTransformSplinePoint(splinePoint); } if (anyMoved || anyRotated || anyScaled) { Undo.RegisterCompleteObjectUndo(instance, "Move Point"); var original_point = instance.Points[point_index]; instance.Points[point_index] = splinePoint; instance.EnsureSplineStaysClosed(); if (LockHandleLength) { var pointIsHandle = SplinePoint.IsHandle(instance.GetSplineMode(), point_index); if (pointIsHandle) { var anchor_index = SplinePoint.GetAnchorIndex(instance.GetSplineMode(), point_index); var anchor_point = instance.Points[anchor_index]; var to_anchor = splinePoint.position - anchor_point.position; var dir_anchor = to_anchor.normalized; splinePoint.position = anchor_point.position + dir_anchor * LockedHandleLength; instance.Points[point_index] = splinePoint; } } UpdateHandlesWhenPointMoved(instance, point_index, splinePointDelta); if (anyMoved) { var delta_move = splinePoint.position - original_point.position; for (var i = 0; i < SelectedPoints.Count; ++i) { var other_index = SelectedPoints[i]; if (other_index == point_index) { continue; } UpdateHandlesWhenPointMoved(instance, other_index, splinePointDelta); instance.Points[other_index].position += delta_move; } Repaint(); } if (anyRotated) { var delta_rotation = Quaternion.Inverse(original_point.rotation) * splinePoint.rotation; for (var i = 0; i < SelectedPoints.Count; ++i) { var other_index = SelectedPoints[i]; if (other_index == point_index) { continue; } instance.Points[other_index].rotation *= delta_rotation; } Repaint(); } if (anyScaled) { var delta_scale = splinePoint.scale - original_point.scale; for (var i = 0; i < SelectedPoints.Count; ++i) { var other_index = SelectedPoints[i]; if (other_index == point_index) { continue; } instance.Points[other_index].scale += delta_scale; } Repaint(); } instance.UpdateNative(); } }
private void OnSceneGUI() { var instance = (Spline)target; if (Event.current.button == 1) { if (Event.current.type == EventType.MouseDown) { _rightMouseHeld = true; } if (Event.current.type == EventType.MouseUp) { _rightMouseHeld = false; } } // pointless for now // DrawToolbar(); // if moving camera with mouse, dont draw all our gizmos.. (they would block trying to click the handles) if ((Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) && Event.current.button != 0) { return; } // try consuming the delete key (delete points) if ((Event.current.type == EventType.KeyDown) && Event.current.keyCode == KeyCode.Delete) { if (SelectedPoints.Count == 0) { return; } else { // sort, 0, 1, 2, etc SelectedPoints.Sort(); // copy points into easier to modify list var pointList = instance.Points.ToList(); // then delete from highest to lowest for (var i = SelectedPoints.Count - 1; i >= 0; --i) { var point_index = SelectedPoints[i]; // don't allow deleting handles directly? var isHandle = SplinePoint.IsHandle(instance.GetSplineMode(), point_index); if (isHandle) { continue; } switch (instance.GetSplineMode()) { // if we have neighbor handles, find them and delete them too.. case SplineMode.Bezier: SplinePoint.GetHandleIndexes(instance.GetSplineMode(), instance.GetSplineClosed(), instance.Points.Length, point_index, out int handleIndex0, out int handleIndex1); if (pointList.Count > 0 && pointList.Count > handleIndex1) { pointList.RemoveAt(handleIndex1); } if (pointList.Count > 0 && pointList.Count > point_index) { pointList.RemoveAt(point_index); } if (pointList.Count > 0 && pointList.Count > handleIndex0) { pointList.RemoveAt(handleIndex0); } break; // otherwise, just the point case SplineMode.Linear: case SplineMode.BSpline: if (pointList.Count > 0 && pointList.Count > point_index) { pointList.RemoveAt(point_index); } break; } } // update original points with modified list instance.Points = pointList.ToArray(); // deselect all points SelectedPoints.Clear(); // consume event and exit Event.current.Use(); return; } } if (PlacingPoint) { if (Event.current.isKey && Event.current.keyCode == KeyCode.Escape) { PlacingPoint = false; return; } // hold right click, press left click if (_rightMouseHeld && (Event.current.type == EventType.MouseDown && Event.current.button == 0)) { PlacingPoint = false; return; } DrawPlacePointView(instance); } else { if (SelectedPoints.Count > 0) { var first_selected_point = SelectedPoints[0]; DrawSelectedSplineHandle(instance, first_selected_point); } // todo, draw these in PlacingPoint too, but non selectable DrawSelectablePoints(instance); } }