Example #1
0
    void OnSceneGUI()
    {
        #region - GUI Handles and vert manipulation
        GUIHandleSizeModifier = Mathf.Abs(SceneView.currentDrawingSceneView.camera.transform.position.z)/100f;
        meshPosition = generatedMesh.transform.position;

        //Draw the vert handles
        for(int i = 0; i < generatedMesh.verts.Length; i++)
        {
            Vector3 oldPoint = generatedMesh.verts[i];

            Handles.color = vertHandleColour;
            Vector3 newPoint = Handles.FreeMoveHandle(generatedMesh.verts[i] + meshPosition,
                                                      Quaternion.identity,
                                                      0.4f * GUIHandleSizeModifier, Vector3.one,
                                                      Handles.DotCap);

            //if the handle has changed the position of any vert, update that position
            if(oldPoint != newPoint)
            {
                generatedMesh.verts[i] = newPoint - meshPosition;
            }
        }

        //Draw the handle at the centre point of all verts
        Handles.color = centerPointColour;
        Vector3 centreOffset = Handles.FreeMoveHandle(generatedMesh.verts.GetCenterPointFromCollection() + meshPosition,
                                                      Quaternion.identity, 0.6f * GUIHandleSizeModifier, Vector3.one, Handles.DotCap);

        //Update the positions of the verts if the centre point has been changed
        Vector3 centreOffSetDist =  (generatedMesh.verts.GetCenterPointFromCollection() + meshPosition) - centreOffset;
        if(centreOffSetDist != Vector3.zero)
        {
            generatedMesh.transform.position = generatedMesh.transform.position - centreOffSetDist;
        }

        //Display the delete position of individual verts if selected
        Handles.color = deletePositionColour;
        if(vertDeletionIndex != -1)
            Handles.DrawSolidDisc(generatedMesh.verts[vertDeletionIndex] + meshPosition,
                                  Vector3.forward, 0.6f * GUIHandleSizeModifier);

        //Draw the selection rectangle
        if(drawSelectionRectangle)
        {
            Handles.color = Color.green;
            Handles.DrawSolidRectangleWithOutline(selectionRectangleVerts,
                                                  selectionRectangleFillColour,
                                                  selectionRectangleLineColour);
        }

        //Draw discs on selection of multiple verts
        if(indexesOfVertsWithinSelectionRectangle.Count > 0)
        {
            Handles.color = vertSelectedColour;
            for(int i = 0; i < indexesOfVertsWithinSelectionRectangle.Count; i++)
            {
                Handles.DrawSolidDisc(generatedMesh.verts[indexesOfVertsWithinSelectionRectangle[i]] + meshPosition,
                                      Vector3.forward, 0.7f * GUIHandleSizeModifier);
            }

            //Draw centre point of selected verts

            Handles.color = Color.red;
            Vector3 offSet = Handles.FreeMoveHandle(selectedVertsCentrePoint, Quaternion.identity,
                                                    0.7f * GUIHandleSizeModifier, Vector3.one, Handles.DotCap);

            //if the central handle of the selected points has been moved, move all the individual selected verts
            if(offSet != selectedVertsCentrePoint)
            {
                Vector3 offSetDist = (selectedVertsCentrePoint - offSet);
                for(int i = 0; i < indexesOfVertsWithinSelectionRectangle.Count; i++)
                {
                    generatedMesh.verts[indexesOfVertsWithinSelectionRectangle[i]] =
                        generatedMesh.verts[indexesOfVertsWithinSelectionRectangle[i]] -
                            new Vector3(offSetDist.x, offSetDist.y, 0);
                }
                selectedVertsCentrePoint = offSet.RoundVector3To(generatedMesh.deltaLimiter);
            }
        }

        generatedMesh.CalculateVerts();

        #endregion

        #region - MOUSE AND INPUT EVENTS

        int controlID = GUIUtility.GetControlID(FocusType.Passive);
        switch(Event.current.GetTypeForControl(controlID))
        {

        case EventType.MouseDown:
            GUIUtility.hotControl = controlID;

            //Get the delete position
            if (Event.current.button == 1 && Event.current.clickCount == 1)
            {
                //Destruction of a point. Get the closest point from mouse click using vector2.distance
                Ray worldRay = HandleUtility.GUIPointToWorldRay (Event.current.mousePosition);
                Vector3 mouseClickPos2D = new Vector3(worldRay.origin.x, worldRay.origin.y, 0f) - meshPosition;
                mouseDragRectStartPos = -mouseClickPos2D;
                vertDeletionIndex = mouseClickPos2D.IndexOfClosestPointInArray(generatedMesh.verts);
            }

            //delete the position on double click
            if (Event.current.button == 1 && Event.current.clickCount == 2)
            {
                if(vertDeletionIndex != -1)
                {
                    generatedMesh.DeleteVertPosition(vertDeletionIndex);
                    vertDeletionIndex = -1;
                }
            }
            //reset the delete position
            if (Event.current.button == 0 && Event.current.clickCount == 1)
            {
                Ray worldRay = HandleUtility.GUIPointToWorldRay (Event.current.mousePosition);
                mouseDragRectStartPos = new Vector2(worldRay.origin.x, worldRay.origin.y);

                if(vertDeletionIndex != -1)
                    vertDeletionIndex = -1;
            }

            //Creation of a new vert postion
            if (Event.current.button == 0 && Event.current.clickCount == 2)
            {
                Ray worldRay = HandleUtility.GUIPointToWorldRay (Event.current.mousePosition);
                Vector3 mouseClickPos2D = new Vector3(worldRay.origin.x, worldRay.origin.y, 0f) - meshPosition;

                if(!mouseClickPos2D.Equals(Vector3.zero))
                    if(!generatedMesh.isVertPositionTaken(mouseClickPos2D))
                        generatedMesh.AddNewVertPosition(mouseClickPos2D);

                generatedMesh.ReOrganiseVertIndexes();
                generatedMesh.CalculateVerts();
                Repaint();
            }

            //Scroll wheel button is pushed down
            if(Event.current.button == 2)
            {
                GUIUtility.hotControl = 0;
                Selection.activeGameObject = null;
            }

            Event.current.Use();
            break;

        case EventType.MouseDrag:

            if(Event.current.button == 0)
            {
                //draw the dragwindow
                if(GUIUtility.hotControl == controlID)
                {
                    Ray worldRay = HandleUtility.GUIPointToWorldRay (Event.current.mousePosition);
                    mouseDragRectEndPos =  new Vector2(worldRay.origin.x, worldRay.origin.y);

                    float selectionRectangleWidth = mouseDragRectEndPos.x - mouseDragRectStartPos.x;
                    float selectionRectangleHeight = mouseDragRectEndPos.y - mouseDragRectStartPos.y;

                    if(!drawSelectionRectangle)
                        drawSelectionRectangle = true;

                    selectionRectangleVerts[0] = new Vector3(mouseDragRectStartPos.x,
                                                             mouseDragRectStartPos.y,
                                                             0f);
                    selectionRectangleVerts[1] = new Vector3(mouseDragRectStartPos.x + selectionRectangleWidth,
                                                             mouseDragRectStartPos.y,
                                                             0f);
                    selectionRectangleVerts[2] = new Vector3(mouseDragRectStartPos.x + selectionRectangleWidth,
                                                             (mouseDragRectStartPos.y + selectionRectangleHeight),
                                                             0f);
                    selectionRectangleVerts[3] = new Vector3(mouseDragRectStartPos.x,
                                                             (mouseDragRectStartPos.y + selectionRectangleHeight),
                                                             0f);
                }
            }

            Event.current.Use();
            break;

        case EventType.MouseUp:

            if(GUIUtility.hotControl == controlID)
            {
                GUIUtility.hotControl = 0;

                //Selection Rectangle Position
                List<Vector2> selectionPositions = new List<Vector2>();

                if(drawSelectionRectangle)
                {
                    //Get a collection of all the vert indexes that are within the rectangle valume just drawn
                    List <int> indexesOfVertsWithinSelectionRectangleNew = new List<int>();
                    for(int i = 0; i < generatedMesh.verts.Length; i++)
                    {
                        if(generatedMesh.verts[i].ToVector2().isPositionWithinRectangleVolume(mouseDragRectStartPos - meshPosition,
                                                                                                      mouseDragRectEndPos - meshPosition))
                        {
                            indexesOfVertsWithinSelectionRectangleNew.Add(i);
                            selectionPositions.Add(generatedMesh.verts[i].ToVector2());
                        }
                    }

                    if(indexesOfVertsWithinSelectionRectangle.Count > 0)
                        indexesOfVertsWithinSelectionRectangle.Clear();

                    indexesOfVertsWithinSelectionRectangle = indexesOfVertsWithinSelectionRectangleNew;

                    selectedVertsCentrePoint = selectionPositions.GetCenterPointFromCollection() + meshPosition.ToVector2();

                    drawSelectionRectangle = false;
                }
                else
                    if(indexesOfVertsWithinSelectionRectangle.Count > 0)
                        indexesOfVertsWithinSelectionRectangle.Clear();
            }

            Event.current.Use();
            break;

            //Exit the selection of this gameobject
        case EventType.KeyDown:

            Event e = Event.current;
            if(e.keyCode == KeyCode.Escape)
                Selection.activeGameObject = null;

            //If multiple verts are currently selected, delete them
            if(e.keyCode == KeyCode.Delete)
            {
                if(indexesOfVertsWithinSelectionRectangle.Count > 0)
                {
                    generatedMesh.DeleteVertPositions(indexesOfVertsWithinSelectionRectangle.ToArray());
                    indexesOfVertsWithinSelectionRectangle.Clear();
                    generatedMesh.CalculateVerts();
                }
            }

            GUIUtility.hotControl = 0;
            Event.current.Use();
            break;
        }

        #endregion

        if(GUI.changed)
            EditorUtility.SetDirty(target);
    }