예제 #1
0
    void HighlightHoveringLine()
    {
        if (lastHoverLine != null && lastHoverLine != selectedLine)
        {
            lastHoverLine.SetSelectState(InteractiveLine.SelectState.NONE);
        }

        Ray             ray           = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
        Vector3         worldMousePos = ray.origin;
        InteractiveLine closestLine   = ApproximateBinarySearch(horizontalLinesByY, worldMousePos.y);

        if (closestLine == null)
        {
            closestLine = ApproximateBinarySearch(verticalLinesByX, worldMousePos.x);
        }
        if (closestLine != null && closestLine.selectState == InteractiveLine.SelectState.IMMOBILE)
        {
            closestLine = null;
        }
        if (closestLine != null && closestLine != selectedLine)
        {
            closestLine.SetSelectState(InteractiveLine.SelectState.HOVER);
        }
        lastHoverLine = closestLine;
    }
예제 #2
0
 public void NotifyLineDeleting(InteractiveLine line)
 {
     if (line.orientation == InteractiveLine.Orientation.HORIZONTAL)
     {
         horizontalLinesByY.Remove(line.point1.y);
     }
     else
     {
         verticalLinesByX.Remove(line.point1.x);
     }
 }
예제 #3
0
    public void OnSceneGUI()
    {
        if (drawGrid)
        {
            int controlID = EditorGUIUtility.GetControlID(FocusType.Passive);
            switch (Event.current.GetTypeForControl(controlID))
            {
            // On Layout event (the first event for initialization) record grid as being 0 units away if mouse within grid bounds
            //  else declare infinity away to steal clicks and avoid deselection
            case EventType.Layout:
                if (selectedLine == null)
                {
                    Vector3 worldMousePos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
                    if (worldMousePos.x >= minX && worldMousePos.x <= maxX && worldMousePos.y >= minY && worldMousePos.y <= maxY)
                    {
                        HandleUtility.AddControl(controlID, 0f);
                    }
                    else
                    {
                        HandleUtility.AddControl(controlID, Mathf.Infinity);
                    }
                }
                else
                {
                    HandleUtility.AddDefaultControl(controlID);
                }
                break;

            // All other events perform logic and draw like normal
            default:
                HighlightHoveringLine();
                if (Event.current.type == EventType.MouseUp)
                {
                    if (selectedLine != null)
                    {
                        selectedLine.SetSelectState(InteractiveLine.SelectState.NONE);
                    }
                    selectedLine = lastHoverLine;
                    if (selectedLine != null)
                    {
                        selectedLine.SetSelectState(InteractiveLine.SelectState.SELECTED);
                        Event.current.Use();
                    }
                }
                if (selectedLine == null)
                {
                    ShowAddLineButtons();
                }
                break;
            }
        }
    }
예제 #4
0
 // Intended for loading grid from text file, doesn't normalize lines or check if dictionary already contains
 public void AddExistingLine(InteractiveLine line)
 {
     line.SetContainingGrid(this);
     if (line.orientation == InteractiveLine.Orientation.HORIZONTAL)
     {
         horizontalLinesByY.Add(line.point1.y, line);
         ++numRowsOfCells;
     }
     else
     {
         verticalLinesByX.Add(line.point1.x, line);
         ++numColsOfCells;
     }
     UpdateMinMaxs(line);
 }
예제 #5
0
    // Adds a line to the grid, computing if it's horizontal or vertical, and scales all lines to the same length
    InteractiveLine AddLine(Vector3 point1, Vector3 point2)
    {
        InteractiveLine line = ScriptableObject.CreateInstance <InteractiveLine>();

        InteractiveLine.Orientation orientation;
        if (point1.x == point2.x)
        {
            orientation = InteractiveLine.Orientation.VERTICAL;
            ++numColsOfCells;
        }
        else if (point1.y == point2.y)
        {
            orientation = InteractiveLine.Orientation.HORIZONTAL;
            ++numRowsOfCells;
        }
        else
        {
            Debug.LogError("XYGrid AddLine: Line isn't horizontal or vertical");
            DestroyImmediate(line);
            return(null);
        }

        line.Init(point1, point2, this, orientation);
        if (orientation == InteractiveLine.Orientation.HORIZONTAL)
        {
            if (horizontalLinesByY.ContainsKey(point1.y))
            {
                DestroyImmediate(horizontalLinesByY[point1.y]);
                horizontalLinesByY.Remove(point1.y);
            }
            horizontalLinesByY.Add(point1.y, line);
        }
        else
        {
            if (verticalLinesByX.ContainsKey(point1.x))
            {
                DestroyImmediate(verticalLinesByX[point1.x]);
                verticalLinesByX.Remove(point1.x);
            }
            verticalLinesByX.Add(point1.x, line);
        }
        UpdateMinMaxs(line);
        RescaleLines();
        return(line);
    }
예제 #6
0
    public bool LoadGrid(string fireManagerID)
    {
        TextAsset gridText = AssetDatabase.LoadAssetAtPath("Assets/Editor/FireGrids/" + fireManagerID + ".txt", typeof(TextAsset)) as TextAsset;

        if (gridText)
        {
            string   allLines = gridText.text;
            string[] eachLine = allLines.Split('|');
            foreach (string line in eachLine)
            {
                InteractiveLine interactiveLine = CreateInstance <InteractiveLine>();
                JsonUtility.FromJsonOverwrite(line, interactiveLine);
                AddExistingLine(interactiveLine);
            }
            return(true);
        }
        else
        {
            return(false);
        }
    }
예제 #7
0
    // Adds a cell to the grid where other lines cannot pass inside of
    // Paramter cellCorners is array of 4 Vector3 representing corners of cell in order bottom left, top left, top right, bottom right
    public void AddIsolatedCell(Vector3[] cellCorners)
    {
        isolatedCellMinMaxs.Add(new Vector4(cellCorners[0].x, cellCorners[2].x, cellCorners[0].y, cellCorners[2].y));

        // Remove any non-immobile lines inside the new isolated cell area
        float[] xCoordinates = verticalLinesByX.Keys.ToArray();
        float[] yCoordinates = horizontalLinesByY.Keys.ToArray();
        bool    exactMatchFound;
        int     lowerXBoundIndex = InterpretArrayBinarySearchIndex(Array.BinarySearch(xCoordinates, cellCorners[0].x), out exactMatchFound);
        int     upperXBoundIndex = InterpretArrayBinarySearchIndex(Array.BinarySearch(xCoordinates, cellCorners[2].x), out exactMatchFound);
        int     lowerYBoundIndex = InterpretArrayBinarySearchIndex(Array.BinarySearch(yCoordinates, cellCorners[0].y), out exactMatchFound);
        int     upperYBoundIndex = InterpretArrayBinarySearchIndex(Array.BinarySearch(yCoordinates, cellCorners[2].y), out exactMatchFound);

        for (; lowerXBoundIndex < upperXBoundIndex; ++lowerXBoundIndex)
        {
            if (lowerXBoundIndex < xCoordinates.Length && verticalLinesByX[xCoordinates[lowerXBoundIndex]].selectState != InteractiveLine.SelectState.IMMOBILE)
            {
                DestroyImmediate(verticalLinesByX[xCoordinates[lowerXBoundIndex]]);
                verticalLinesByX.Remove(xCoordinates[lowerXBoundIndex]);
            }
        }
        for (; lowerYBoundIndex < upperYBoundIndex; ++lowerYBoundIndex)
        {
            if (lowerYBoundIndex < yCoordinates.Length && horizontalLinesByY[yCoordinates[lowerYBoundIndex]].selectState != InteractiveLine.SelectState.IMMOBILE)
            {
                DestroyImmediate(horizontalLinesByY[yCoordinates[lowerYBoundIndex]]);
                horizontalLinesByY.Remove(yCoordinates[lowerYBoundIndex]);
            }
        }

        InteractiveLine line = AddLine(cellCorners[0], cellCorners[1]);

        line.SetSelectState(InteractiveLine.SelectState.IMMOBILE);
        line = AddLine(cellCorners[1], cellCorners[2]);
        line.SetSelectState(InteractiveLine.SelectState.IMMOBILE);
        line = AddLine(cellCorners[3], cellCorners[2]);
        line.SetSelectState(InteractiveLine.SelectState.IMMOBILE);
        line = AddLine(cellCorners[0], cellCorners[3]);
        line.SetSelectState(InteractiveLine.SelectState.IMMOBILE);
    }
예제 #8
0
    public void NotifyLineMoved(InteractiveLine line, float oldCoordinate)
    {
        if (line.orientation == InteractiveLine.Orientation.HORIZONTAL)
        {
            horizontalLinesByY.Remove(oldCoordinate);
            --numRowsOfCells;
        }
        else
        {
            verticalLinesByX.Remove(oldCoordinate);
            --numColsOfCells;
        }

        // Destroy lines that move into isolated cells
        foreach (Vector4 minMaxs in isolatedCellMinMaxs)
        {
            if (line.orientation == InteractiveLine.Orientation.HORIZONTAL)
            {
                if (line.point1.y >= minMaxs.z && line.point1.y <= minMaxs.w)
                {
                    DestroyImmediate(line);
                    return;
                }
            }
            else
            {
                if (line.point1.x >= minMaxs.x && line.point1.x <= minMaxs.y)
                {
                    DestroyImmediate(line);
                    return;
                }
            }
        }

        AddExistingLine(line);
        RescaleLines();
    }
예제 #9
0
    // Updates variables tracking min and max in X and Y and rescales lines to be same length
    void UpdateMinMaxs(InteractiveLine line)
    {
        float minLineX = Mathf.Min(line.point1.x, line.point2.x);
        float minLineY = Mathf.Min(line.point1.y, line.point2.y);
        float maxLineX = Mathf.Max(line.point1.x, line.point2.x);
        float maxLineY = Mathf.Max(line.point1.y, line.point2.y);

        if (minLineX < minX)
        {
            minX = minLineX;
        }
        if (maxLineX > maxX)
        {
            maxX = maxLineX;
        }
        if (minLineY < minY)
        {
            minY = minLineY;
        }
        if (maxLineY > maxY)
        {
            maxY = maxLineY;
        }
    }