/// <summary> /// Renders all handles and tangents when applicable. /// </summary> private void RenderHandles() { int pointCount = spline.GetControlPointCount(); int index = 0; Handles.color = Color.white; for (int i = pointCount - 1; i >= 0; i--) { ControlPoint p = spline.GetControlPoint(i); ShowPoint(p, index); index++; } int segCount = spline.GetCurveCount(); if (segCount <= 0) { return; } for (int i = segCount - 1; i >= 0; i--) { BezierCurve seg = spline.GetCurve(i); Handles.color = Color.green; //Display Tangents if (!deletePointMode) { if (seg.GetStartPoint().tangentForward) { ShowTangentPoint(seg.GetStartPoint(), seg.GetStartPoint().tangentForward, index); index++; } if (seg.GetEndPoint().tangentBackward) { ShowTangentPoint(seg.GetEndPoint(), seg.GetEndPoint().tangentBackward, index); index++; } } } }
/// <summary> /// Handle the drag and drop of the control point. /// </summary> public override void MouseUp(int x, int y) { if (selectedPoint != null) { // Update the selected point to the mouse button release location. selectedPoint.x = x; selectedPoint.y = y; selectedPoint = null; } else { // No control point was selected, the mouse up event must be the // user clicking to add another control point. controlPoints.Add(new Vector2(x, y)); } // Generate the bezier curve. bezier = new BezierCurve(controlPoints); }
private void OnSceneGUI() { _curve = target as BezierCurve; _handleTransform = _curve.transform; _handleRotation = Tools.pivotRotation == PivotRotation.Local ? _handleTransform.rotation : Quaternion.identity; Vector3 p0 = ShowPoint(0); Vector3 p1 = ShowPoint(1); Vector3 p2 = ShowPoint(2); Vector3 p3 = ShowPoint(3); // The color of the line Handles.color = Color.gray; Handles.DrawLine(p0, p1); Handles.DrawLine(p2, p3); ShowDirections(); Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2.0f); }
/// <summary> /// Splits a Curve and adds a new ControlPoint. /// </summary> /// <param name="point">Point to insert.</param> /// <param name="curve">Curve to be split.</param> public void InsertControlPoint(ControlPoint point, BezierCurve curve) { int index = curves.IndexOf(curve); ControlPoint last = controlPoints[index]; ControlPoint next = controlPoints[index + 1]; controlPoints.Insert(index + 1, point); curves[index] = new BezierCurve(this, point, next); BezierCurve newCurve = new BezierCurve(this, last, point); curves.Insert(index, newCurve); if (index + 2 >= curves.Count) { return; } for (int i = index + 2; i < curves.Count; i++) { curves[i].controlPointIndices[0]++; curves[i].controlPointIndices[1]++; } }
private void OnSceneGUI() { GetCurveAndTransform(); Handles.BeginGUI(); GUIStyle sceneLabelStyle = new GUIStyle(); sceneLabelStyle.normal.textColor = Color.white; sceneLabelStyle.alignment = TextAnchor.UpperCenter; #region Scene View Labels if (addPointMode) { GUI.Label(new Rect(Screen.width * 0.5f - 125, 10, 250, 30), "Left click to add a point", sceneLabelStyle); } if (insertPointMode) { GUI.Label(new Rect(Screen.width * 0.5f - 125, 10, 250, 30), "Left click to place a point", sceneLabelStyle); } if (selectedIndex > -1) { GUI.Label(new Rect(Screen.width * 0.5f - 125, 10, 250, 30), "Left click a point to move it", sceneLabelStyle); } if (deletePointMode) { GUI.Label(new Rect(Screen.width * 0.5f - 125, 10, 250, 30), "Left click a point to delete it", sceneLabelStyle); } Handles.EndGUI(); #endregion #region Intercept Clicks if ((addPointMode || insertPointMode || deletePointMode) && Event.current.type == EventType.Layout) { HandleUtility.AddDefaultControl(0); } #endregion #region Add/Insert Control Points if ((addPointMode || insertPointMode) && Event.current.type == EventType.MouseDown && Event.current.button == 0) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); Plane plane = new Plane(-Camera.current.transform.forward, handleTransform.position); float enter = 0.0f; if (addPointMode && plane.Raycast(ray, out enter)) { Vector3 hitPoint = handleTransform.InverseTransformPoint(ray.GetPoint(enter)); Undo.RecordObject(spline, "Add Control Point"); EditorUtility.SetDirty(spline); lastPoint = new ControlPoint(hitPoint); if (spline.GetControlPointCount() > 0) { Vector3 p = spline.GetControlPoint(0); Vector3 rayToP = (p - ray.origin); float angle = Mathf.Deg2Rad * Vector3.Angle(rayToP.normalized, ray.direction); float dist = Mathf.Sin(angle) * rayToP.magnitude; if (dist < 0.2f) { lastPoint = spline.GetControlPoint(0); addPointMode = false; ResetTools(); SceneView.RepaintAll(); } } spline.AddControlPoint(lastPoint); } else if (insertPointMode) { float t; float dist = -1; if (spline.GetClosestDistanceToRay(ray, out dist)) { Undo.RecordObject(spline, "Insert Control Point"); EditorUtility.SetDirty(spline); Vector3 localPos = handleTransform.InverseTransformPoint(spline.GetPointOnSplineByDistance(dist)); lastPoint = new ControlPoint(localPos); BezierCurve curve = spline.GetCurveFromDistance(dist, out t); spline.InsertControlPoint(lastPoint, curve); } } Event.current.Use(); } if ((addPointMode || insertPointMode) && lastPoint != null && Event.current.type == EventType.MouseDrag && Event.current.button == 0) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); Plane plane = new Plane(-Camera.current.transform.forward, lastPoint); float enter = 0.0f; if (plane.Raycast(ray, out enter)) { Vector3 hitPoint = handleTransform.InverseTransformPoint(ray.GetPoint(enter)); lastPoint.tangentForward = new CurveHandle(hitPoint - lastPoint); lastPoint.tangentBackward = new CurveHandle(lastPoint - hitPoint); } Event.current.Use(); } if ((addPointMode || insertPointMode) && Event.current.type == EventType.MouseUp && Event.current.button == 0) { Undo.RecordObject(spline, "Move Tangent"); EditorUtility.SetDirty(spline); lastPoint = null; Event.current.Use(); } #endregion spline.RenderCurvesInSceneView(!deletePointMode); RenderHandles(); }