Ejemplo n.º 1
0
        // Adds this boundary to a graph as a series of nodes and edges
        public void AddToGraph(BoundaryGraph graph)
        {
            List <Vector2>           corners = Get2DBounds();
            List <BoundaryGraphNode> nodes   = new List <BoundaryGraphNode>();
            int i = 0;

            // Convert each point into a node
            for (i = 0; i < corners.Count; i++)
            {
                BoundaryGraphNode node = new BoundaryGraphNode(corners[i]);
                nodes.Add(node);
            }
            // Link each node to the next one (note linking is reciprical so I don't have to link the reverse)
            for (i = 0; i < nodes.Count; i++)
            {
                int nextInd = (i + 1) % nodes.Count;
                nodes[i].AddNeighbor(nodes[nextInd]);
            }
            // Add the nodes to the graph
            foreach (BoundaryGraphNode node in nodes)
            {
                node.AddParentBoundary(this);
                graph.AddNode(node);
            }
        }
Ejemplo n.º 2
0
        // Compiles the level recovering interior geometry
        // Output is saved as a scriptable object instance in assets
        public void CompileLevel()
        {
            // Build a list of boundaries and a shape graph
            List <Boundary> boundaries = new List <Boundary>();
            BoundaryGraph   graph      = new BoundaryGraph();

            foreach (Transform trans in transform)
            {
                Boundary temp = trans.gameObject.GetComponent <Boundary>();
                if (temp != null)
                {
                    boundaries.Add(temp);
                    temp.AddToGraph(graph);
                }
            }

            // Unify the graph and make sure any intersections have a vertex
            graph.Unify();

            // Remove any verticies interior to another boundary
            // This does not account for exterior - exterior edges that cross the shape
            List <BoundaryGraphNode> deleteList = new List <BoundaryGraphNode>();

            foreach (BoundaryGraphNode node in graph)
            {
                foreach (Boundary bound in boundaries)
                {
                    // Ignore its parent boundaries
                    //if (node.IsParent(bound))
                    //continue;
                    // If position is interior, remove this node
                    if (bound.Interior(node.position))
                    {
                        deleteList.Add(node);
                        break;
                    }
                }
            }

            // Cleanup deleted nodes
            foreach (BoundaryGraphNode node in deleteList)
            {
                graph.DeleteNode(node);
            }

            // Now we will delete any edges who's midpoint is interior to another boundary
            // These edges can remain when there's an exterior-exterior edge crossing polygons
            // Consider a T shape made of 2 boundaries. Right at the cross section
            foreach (UnorderedPair <BoundaryGraphNode, BoundaryGraphNode> edge in graph.getEdgesAsUniquePairs())
            {
                // Find the midpoint
                Vector3 midpoint = new Vector3((edge.item1.position.x + edge.item2.position.x) / 2, (edge.item1.position.y + edge.item2.position.y) / 2, 0);
                foreach (Boundary bound in boundaries)
                {
                    // Ignore its parent boundaries
                    //if (edge.item1.IsParent(bound) || edge.item2.IsParent(bound))
                    //continue;
                    // If position is interior, remove this node
                    if (bound.Interior(midpoint))
                    {
                        edge.item1.RemoveNeighbor(edge.item2); // Edge removal is reciprical
                        break;
                    }
                }
            }

            // NOTE: work still needed. Needs to handle multiple islands and error cases.
            // right now it only works for the trivial case

            // While the graph has nodes remaining
            while (!graph.IsEmpty())
            {
                // Pick an extrema node. This will belong to the exterior most cycle in the graph
                BoundaryGraphNode extrema = graph.GetExtrema();

                // Clean up any exterior - exterior edges that could connect two seperate layers
                // These are left over after deleting the interior nodes
                // To do this, we track whether we are currently in an exterior

                // Remove that node and all nodes connected. This will give you the loop.
                List <BoundaryGraphNode> loop = graph.RemoveConnectedComponent(extrema);

                // Convert loop into a list of vector2
                List <Vector2> vertexList = new List <Vector2>();
                foreach (BoundaryGraphNode node in loop)
                {
                    vertexList.Add(node.position);
                }
                vertexList.RemoveAt(vertexList.Count - 1); // There is a bug causing duplicate nodes and instead of fixing it I did this... f**k me :(

                Polygon poly = Undo.AddComponent <Polygon>(gameObject);
                poly.SetVerticies(vertexList);
            }

            return;
        }
Ejemplo n.º 3
0
 // Remove a neighbor from the node. Also removes the reciprical relation
 public void RemoveNeighbor(BoundaryGraphNode node)
 {
     neighbors.Remove(node);
     node.neighbors.Remove(this);
 }
Ejemplo n.º 4
0
 // Checks if this node has other node as a neighbor
 public bool HasNeighbor(BoundaryGraphNode other)
 {
     return(neighbors.Contains(other));
 }
Ejemplo n.º 5
0
 // Add a neighbor to the node. Also adds the reciprical relation
 public void AddNeighbor(BoundaryGraphNode node)
 {
     neighbors.Add(node);
     node.neighbors.Add(this);
 }