void OnSceneGUI() { // Event e = Event.current; if (e.type == EventType.MouseDown) { Undo.RegisterCompleteObjectUndo(spline, "change spline topography"); // if alt key pressed, we will have to create a new node if node position is changed if (e.alt) { mustCreateNewNode = true; } } if (e.type == EventType.MouseUp) { mustCreateNewNode = false; } // disable game object transform gizmo // if the spline script is active if (Selection.activeGameObject == spline.gameObject) { if (isEditingSpline == true) { Tools.current = Tool.None; } else { Selection.SetActiveObjectWithContext(spline.gameObject, spline); Tools.current = Tool.Move; } if (selection == null && spline.nodes.Count > 0) { selection = spline.nodes[0]; } } if (!spline.enabled) { return; } if (isEditingSpline == true) { // draw the selection handles // place a handle on the node and manage position change float HandleSizeMult = 0.1f; var HandlePos = Vector3.zero; var HandleSize = 0.0f; Color defaultColor = Handles.color; Vector3 sceneCamPos = SceneView.currentDrawingSceneView.camera.transform.position; Vector3 newPosition; Vector3 discNormal = sceneCamPos - spline.transform.TransformPoint(selection.Position); if (selectionType == SelectionType.Node) { HandlePos = spline.transform.TransformPoint(selection.Position); HandleSize = HandleUtility.GetHandleSize(HandlePos) * HandleSizeMult; newPosition = spline.transform.InverseTransformPoint(Handles.PositionHandle(HandlePos, Quaternion.identity)); if (newPosition != selection.Position) { // position handle has been moved if (mustCreateNewNode) { mustCreateNewNode = false; selection = AddClonedNode(selection); selection.Direction += newPosition - selection.Position; selection.Position = newPosition; } else { selection.Direction += newPosition - selection.Position; selection.Position = newPosition; } } } Handles.color = new Color(1.0f, .65f, .26f, 1.0f); HandlePos = spline.transform.TransformPoint(selection.Direction); HandleSize = HandleUtility.GetHandleSize(HandlePos) * HandleSizeMult; var Dirresult = Handles.FreeMoveHandle(HandlePos, Quaternion.identity, HandleSize, Vector3.zero, Handles.RectangleHandleCap); if (e.type == EventType.Repaint) { Handles.DrawSolidDisc(HandlePos, discNormal, HandleSize); } selection.Direction = spline.transform.InverseTransformPoint(Dirresult); HandlePos = 2 * spline.transform.TransformPoint(selection.Position) - spline.transform.TransformPoint(selection.Direction); HandleSize = HandleUtility.GetHandleSize(HandlePos) * HandleSizeMult; var Invresult = Handles.FreeMoveHandle(HandlePos, Quaternion.identity, HandleSize, Vector3.zero, Handles.RectangleHandleCap); if (e.type == EventType.Repaint) { Handles.DrawSolidDisc(HandlePos, discNormal, HandleSize); } selection.Direction = 2 * selection.Position - spline.transform.InverseTransformPoint(Invresult); if (showUpVector) { Handles.color = new Color(0.15f, 0.87f, 0.24f, 1f); HandlePos = spline.transform.TransformPoint(selection.Position + selection.Up); HandleSize = HandleUtility.GetHandleSize(HandlePos) * HandleSizeMult; if (e.type == EventType.Repaint) { Handles.DrawSolidDisc(HandlePos, discNormal, HandleSize); } if (selectionType == SelectionType.Up) { var Upresult = Handles.FreeMoveHandle(HandlePos, Quaternion.LookRotation(selection.Direction - selection.Position), HandleSize, Vector3.zero, Handles.RectangleHandleCap); selection.Up = (spline.transform.InverseTransformPoint(Upresult) - selection.Position).normalized; } } // draw the handles of all nodes, and manage selection motion Handles.BeginGUI(); foreach (SplineNode n in spline.nodes) { var dir = spline.transform.TransformPoint(n.Direction); var pos = spline.transform.TransformPoint(n.Position); var invDir = spline.transform.TransformPoint(2 * n.Position - n.Direction); var up = spline.transform.TransformPoint(n.Position + n.Up); // first we check if at least one thing is in the camera field of view if (!(CameraUtility.IsOnScreen(pos) || CameraUtility.IsOnScreen(dir) || CameraUtility.IsOnScreen(invDir) || (showUpVector && CameraUtility.IsOnScreen(up)))) { continue; } Vector3 guiPos = HandleUtility.WorldToGUIPoint(pos); Color defaultCol = GUI.color; if (n == selection) { Vector3 guiDir = HandleUtility.WorldToGUIPoint(dir); Vector3 guiInvDir = HandleUtility.WorldToGUIPoint(invDir); Vector3 guiUp = HandleUtility.WorldToGUIPoint(up); // for the selected node, we also draw a line and place two buttons for directions Handles.color = Color.red; //Handles.DrawLine(guiDir, guiInvDir); Handles.DrawBezier( guiDir, guiInvDir, guiDir, guiInvDir, Color.red, null, 3 ); if (showUpVector) { Handles.color = Color.green; Handles.DrawLine(guiPos, guiUp); if (selectionType != SelectionType.Up) { if (Button(guiUp, upButtonStyle)) { selectionType = SelectionType.Up; } } } } // GUI.color = CURVE_BUTTON_COLOR; GUI.backgroundColor = new Color(75f / 255f, 200f / 255f, 245 / 255f, 1.0f); if (Button(guiPos, nodeButtonStyle)) { selection = n; selectionType = SelectionType.Node; } GUI.backgroundColor = Color.white; } } Handles.EndGUI(); // Don't allow clicking over empty space to deselect the object if (isEditingSpline == true) { if (e.type == EventType.Layout) { HandleUtility.AddDefaultControl(0); } } if (GUI.changed) { EditorUtility.SetDirty(target); } }
void OnSceneGUI() { Event e = Event.current; if (e.type == EventType.MouseDown) { Undo.RegisterCompleteObjectUndo(spline, "change spline topography"); // if alt key pressed, we will have to create a new node if node position is changed if (e.alt) { mustCreateNewNode = true; } } if (e.type == EventType.MouseUp) { mustCreateNewNode = false; } // disable game object transform gyzmo if (Selection.activeGameObject == spline.gameObject) { Tools.current = Tool.None; if (selection == null && spline.nodes.Count > 0) { selection = spline.nodes[0]; } } // draw a bezier curve for each curve in the spline foreach (CubicBezierCurve curve in spline.GetCurves()) { Handles.DrawBezier(spline.transform.TransformPoint(curve.n1.Position), spline.transform.TransformPoint(curve.n2.Position), spline.transform.TransformPoint(curve.n1.Direction), spline.transform.TransformPoint(curve.GetInverseDirection()), CURVE_COLOR, null, 3); } // draw the selection handles switch (selectionType) { case SelectionType.Node: // place a handle on the node and manage position change Vector3 newPosition = spline.transform.InverseTransformPoint(Handles.PositionHandle(spline.transform.TransformPoint(selection.Position), Quaternion.identity)); if (newPosition != selection.Position) { // position handle has been moved if (mustCreateNewNode) { mustCreateNewNode = false; selection = AddClonedNode(selection); selection.Direction += newPosition - selection.Position; selection.Position = newPosition; } else { selection.Direction += newPosition - selection.Position; selection.Position = newPosition; } } break; case SelectionType.Direction: var result = Handles.PositionHandle(spline.transform.TransformPoint(selection.Direction), Quaternion.identity); selection.Direction = spline.transform.InverseTransformPoint(result); break; case SelectionType.InverseDirection: result = Handles.PositionHandle(2 * spline.transform.TransformPoint(selection.Position) - spline.transform.TransformPoint(selection.Direction), Quaternion.identity); selection.Direction = 2 * selection.Position - spline.transform.InverseTransformPoint(result); break; case SelectionType.Up: result = Handles.PositionHandle(spline.transform.TransformPoint(selection.Position + selection.Up), Quaternion.LookRotation(selection.Direction - selection.Position)); selection.Up = (spline.transform.InverseTransformPoint(result) - selection.Position).normalized; break; } // draw the handles of all nodes, and manage selection motion Handles.BeginGUI(); foreach (SplineNode n in spline.nodes) { var dir = spline.transform.TransformPoint(n.Direction); var pos = spline.transform.TransformPoint(n.Position); var invDir = spline.transform.TransformPoint(2 * n.Position - n.Direction); var up = spline.transform.TransformPoint(n.Position + n.Up); // first we check if at least one thing is in the camera field of view if (!(CameraUtility.IsOnScreen(pos) || CameraUtility.IsOnScreen(dir) || CameraUtility.IsOnScreen(invDir) || (showUpVector && CameraUtility.IsOnScreen(up)))) { continue; } Vector3 guiPos = HandleUtility.WorldToGUIPoint(pos); if (n == selection) { Vector3 guiDir = HandleUtility.WorldToGUIPoint(dir); Vector3 guiInvDir = HandleUtility.WorldToGUIPoint(invDir); Vector3 guiUp = HandleUtility.WorldToGUIPoint(up); // for the selected node, we also draw a line and place two buttons for directions Handles.color = DIRECTION_COLOR; Handles.DrawLine(guiDir, guiInvDir); // draw quads direction and inverse direction if they are not selected if (selectionType != SelectionType.Node) { if (Button(guiPos, directionButtonStyle)) { selectionType = SelectionType.Node; } } if (selectionType != SelectionType.Direction) { if (Button(guiDir, directionButtonStyle)) { selectionType = SelectionType.Direction; } } if (selectionType != SelectionType.InverseDirection) { if (Button(guiInvDir, directionButtonStyle)) { selectionType = SelectionType.InverseDirection; } } if (showUpVector) { Handles.color = Color.green; Handles.DrawLine(guiPos, guiUp); if (selectionType != SelectionType.Up) { if (Button(guiUp, upButtonStyle)) { selectionType = SelectionType.Up; } } } } else { if (Button(guiPos, nodeButtonStyle)) { selection = n; selectionType = SelectionType.Node; } } } Handles.EndGUI(); if (GUI.changed) { EditorUtility.SetDirty(target); } }
void OnSceneGUI() { Event e = Event.current; if (e.type == EventType.MouseDown) { Undo.RegisterCompleteObjectUndo(se, "change extruded shape"); // if control key pressed, we will have to create a new vertex if position is changed if (e.control) { mustCreateNewNode = true; } } if (e.type == EventType.MouseUp) { mustCreateNewNode = false; } var spline = se.GetComponentInParent <Spline>(); if (spline == null) { return; } CurveSample startSample = spline.GetSample(0); Quaternion q = startSample.Rotation; foreach (ExtrusionSegment.Vertex v in se.shapeVertices) { // we create point and normal relative to the spline start where the shape is drawn Vector3 point = se.transform.TransformPoint(q * v.point + startSample.location); Vector3 normal = se.transform.TransformPoint(q * (v.point + v.normal) + startSample.location); // first we check if at least one thing is in the camera field of view if (!CameraUtility.IsOnScreen(point) && !CameraUtility.IsOnScreen(normal)) { continue; } if (v == selection) { // draw the handles for selected vertex position and normal float size = HandleUtility.GetHandleSize(point) * 0.3f; float snap = 0.1f; // create a handle for the vertex position Vector3 movedPoint = Handles.Slider2D(0, point, startSample.tangent, Vector3.right, Vector3.up, size, Handles.CircleHandleCap, new Vector2(snap, snap)); if (movedPoint != point) { // position has been moved Vector2 newVertexPoint = Quaternion.Inverse(q) * (se.transform.InverseTransformPoint(movedPoint) - startSample.location); if (mustCreateNewNode) { // We must create a new node mustCreateNewNode = false; ExtrusionSegment.Vertex newVertex = new ExtrusionSegment.Vertex(newVertexPoint, v.normal, v.uCoord); int i = se.shapeVertices.IndexOf(v); if (i == se.shapeVertices.Count - 1) { se.shapeVertices.Add(newVertex); } else { se.shapeVertices.Insert(i + 1, newVertex); } selection = newVertex; } else { v.point = newVertexPoint; // normal must be updated if point has been moved normal = se.transform.TransformPoint(q * (v.point + v.normal) + startSample.location); } se.SetToUpdate(); } else { // vertex position handle hasn't been moved // create a handle for normal Vector3 movedNormal = Handles.Slider2D(normal, startSample.tangent, Vector3.right, Vector3.up, size, Handles.CircleHandleCap, snap); if (movedNormal != normal) { // normal has been moved v.normal = (Vector2)(Quaternion.Inverse(q) * (se.transform.InverseTransformPoint(movedNormal) - startSample.location)) - v.point; se.SetToUpdate(); } } Handles.BeginGUI(); DrawQuad(HandleUtility.WorldToGUIPoint(point), CURVE_COLOR); DrawQuad(HandleUtility.WorldToGUIPoint(normal), Color.red); Handles.EndGUI(); } else { // we draw a button to allow selection of the vertex Handles.BeginGUI(); Vector2 p = HandleUtility.WorldToGUIPoint(point); if (GUI.Button(new Rect(p - new Vector2(QUAD_SIZE / 2, QUAD_SIZE / 2), new Vector2(QUAD_SIZE, QUAD_SIZE)), GUIContent.none)) { selection = v; } Handles.EndGUI(); } // draw an arrow from the vertex location to the normal Handles.color = Color.red; Handles.DrawLine(point, normal); // draw a line between that vertex and the next one int index = se.shapeVertices.IndexOf(v); int nextIndex = index == se.shapeVertices.Count - 1 ? 0 : index + 1; if (se.loopAround || nextIndex > 0) { ExtrusionSegment.Vertex next = se.shapeVertices[nextIndex]; Handles.color = CURVE_COLOR; Vector3 vAtSplineEnd = se.transform.TransformPoint(q * next.point + startSample.location); Handles.DrawLine(point, vAtSplineEnd); } } }