GenerateGraph.GenerateGraph C# (CSharp) Method

GenerateGraph() public method

public GenerateGraph ( ) : System.Collections
return System.Collections
    public GenerateGraph()
    {
        //get nav mesh characteristics from pre-made nav mesh. Will write script later that generates
        //a nav-mesh for any map.
        NavMeshTriangulation navmesh = NavMesh.CalculateTriangulation();
        //initialize triangles array
        Triangle[] meshTriangles = new Triangle[navmesh.indices.Length/3];

        //will contain mapping from a string containing the Vector3 pair side and the lane type of a node(ex: (1,2,3) and (4,5,6)
        //in "middle" will be respresented as "1,2,3 - 4,5,6 middle" with the smaller Vector3 coming first) to the node on that
        //side with that lane type.
        Dictionary<string, Node> sideToNode = new Dictionary<string, Node>();
        //will contain mapping from a Node to the list of Triangles that contain that Node on a side
        Dictionary<Node, List<Triangle>> nodeToTriangles = new Dictionary<Node, List<Triangle>>();
        nodes = new List<Node>();
        //will contain a mapping from Vector3 coordinates (ex: (1,2,3) will be represented as "1,2,3") to
        //a Node
        Dictionary<string, Node> coordinatesToNode = new Dictionary<string, Node>();

        //Made sure nav mesh indices is a multiple of 3
        for (int i = 0; i < navmesh.indices.Length / 3; i++) {
            Vector3[] currentVectors = new Vector3[3];
            Vector3 v1 = navmesh.vertices[navmesh.indices[i*3]];
            Vector3 v2 = navmesh.vertices[navmesh.indices[i*3 + 1]];
            Vector3 v3 = navmesh.vertices[navmesh.indices[i*3 + 2]];
            meshTriangles[i] = new Triangle(v1, v2, v3, NavMesh.GetAreaCost(navmesh.areas[i]));

            List<Vector3Pair> trianglePairs = new List<Vector3Pair>();
            //Add the pair v1, v2 to trianglePairs
            trianglePairs.Add(new Vector3Pair(v1, v2));
            //Add the pair v2, v3 trianglePairs
            trianglePairs.Add(new Vector3Pair(v2, v3));
            //Add the pair v1, v3
            trianglePairs.Add(new Vector3Pair(v1, v3));
            //Calculate bisections. Needed to generate smoother paths
            foreach (Vector3Pair currentVector3Pair in trianglePairs) {
                Vector3 currentFirst = currentVector3Pair.first;
                Vector3 currentSecond = currentVector3Pair.second;
                Vector3 bisect1 = new Vector3((currentFirst.x + currentSecond.x)/2, (currentFirst.y + currentSecond.y)/2,
                                              (currentFirst.z + currentSecond.z)/2);
                Vector3 bisect2 = new Vector3((bisect1.x + currentFirst.x)/2, (bisect1.y + currentFirst.y)/2,
                                              (bisect1.z + currentFirst.z)/2);
                Vector3 bisect3 = new Vector3((bisect1.x + currentSecond.x)/2, (bisect1.y + currentSecond.y)/2,
                                              (bisect1.z + currentSecond.z)/2);
                Node bisect1Node = getNodeWithVectorCoordinates(ref coordinatesToNode, bisect1);
                Node bisect2Node = getNodeWithVectorCoordinates(ref coordinatesToNode, bisect2);
                Node bisect3Node = getNodeWithVectorCoordinates(ref coordinatesToNode, bisect3);
                AddToDictionary(ref nodeToTriangles, bisect1Node, meshTriangles[i]);
                AddToDictionary(ref nodeToTriangles, bisect2Node, meshTriangles[i]);
                AddToDictionary(ref nodeToTriangles, bisect3Node, meshTriangles[i]);
                sideToNode[GetPairString(currentFirst, currentSecond) + " middle"] = bisect1Node;
                sideToNode[GetPairString(currentFirst, currentSecond) + " outer1"] = bisect2Node;
                sideToNode[GetPairString(currentFirst, currentSecond) + " outer2"] = bisect3Node;
            }
            Vector3 currentCentroid = meshTriangles[i].Centroid ();
            Node centroidNode = getNodeWithVectorCoordinates(ref coordinatesToNode, currentCentroid);
            AddToDictionary(ref nodeToTriangles, centroidNode, meshTriangles[i]);
            sideToNode[GetPairString (currentCentroid, currentCentroid) + " middle"] = centroidNode;

        }

        //create list of item nodes
        List<Node> itemNodes = new List<Node>();
        foreach (GameObject item in ItemsAI.itemList) {
            Node currentItemNode = new Node (ItemsAI.objectToPosition [item]);
            itemNodes.Add(currentItemNode);
            PathPlanningDataStructures.nodeToCount[currentItemNode.position] = 0;
        }

        //set neighbors of each node
        foreach (var item in nodeToTriangles) {
            Node currentNode = item.Key;
            //iterate through all triangles that contain the currentNode on a side
            foreach (Triangle t in item.Value) {
                //centroid of the triangle
                Vector3 currentCentroid = t.Centroid();
                //list of sides of the triangle
                List<Vector3Pair> triangleSides = new List<Vector3Pair>();
                triangleSides.Add(new Vector3Pair(t.vertex1, t.vertex2));
                triangleSides.Add(new Vector3Pair(t.vertex2, t.vertex3));
                triangleSides.Add(new Vector3Pair(t.vertex1, t.vertex3));
                //iterate through each item node to check if it is contained within the current triangle; if so,
                //make the centroid of the triangle, currentNode, and the item neighbors of each other
                //bool[] nodeInTriangle = new bool[itemNodes.Count];
                for(int i = 0; i < itemNodes.Count; i++) {
                    Node currentItemNode = itemNodes [i];
                    if (t.PointInTriangle (currentItemNode.position)) {
                        addNodeNeighbor(sideToNode, ref currentItemNode, currentCentroid, currentCentroid, "middle");
                        itemNodes[i].neighbors.Add (currentNode);
                        currentNode.neighbors.Add (itemNodes [i]);
                    }
                }
                foreach (Vector3Pair triangleSide in triangleSides) {
                    Vector3 currentFirst = triangleSide.first;
                    Vector3 currentSecond = triangleSide.second;
                    addNodeNeighbor(sideToNode, ref currentNode, currentFirst, currentSecond, "middle");
                    addNodeNeighbor(sideToNode, ref currentNode, currentFirst, currentSecond, "outer1");
                    addNodeNeighbor(sideToNode, ref currentNode, currentFirst, currentSecond, "outer2");
                    for (int i = 0; i < itemNodes.Count; i++) {
                        Node currentItemNode = itemNodes [i];
                        if (t.PointInTriangle (currentItemNode.position)) {
                            addNodeNeighbor(sideToNode, ref currentItemNode, currentFirst, currentSecond, "middle");
                            addNodeNeighbor(sideToNode, ref currentItemNode, currentFirst, currentSecond, "outer1");
                            addNodeNeighbor(sideToNode, ref currentItemNode, currentFirst, currentSecond, "outer2");
                        }
                    }
                }
                addNodeNeighbor(sideToNode, ref currentNode, currentCentroid, currentCentroid, "middle");
            }
            nodes.Add(currentNode);
            PathPlanningDataStructures.nodeToCount[currentNode.position] = 0;
        }
        //set end node of the cars
        endNode = getClosestNode (GameObject.Find("FinishLine").transform.position);
    }