예제 #1
0
    //Not meant for real-time use
    public void ConstructGraph()
    {
        if (meshGraph == null)
        {
            Debug.Log("No mesh to operate on! Please set meshGraph before calling this function");
            return;
        }
        //Create a sampler Gameobject to perform raycasts to neighboring nodes
        Sampler = new GameObject("Sampler");
        List <int>      neighbors;
        List <int>      DeadVertices = new List <int>();
        List <pathNode> DeadNodes    = new List <pathNode>();

        simpleGraph = new GraphSimple();
        simpleGraph.AddNodes(meshGraph.vertexCount);

        float dist = 0;

        for (int i = 0; i < meshGraph.vertexCount; i++)
        {
            //if(DeadVertices.Contains(i))
            //continue;

            neighbors = GetNeighbors(i);

            pathNode currentNode = simpleGraph.graph[i];
            currentNode.position = transform.TransformPoint(meshGraph.vertices[i]);


            for (int j = 0; j < neighbors.Count; j++)
            {
                dist = Vector3.Distance(transform.TransformPoint(meshGraph.vertices[i]), transform.TransformPoint(meshGraph.vertices[neighbors[j]]));
                currentNode.neighbors.Add(simpleGraph.graph[neighbors[j]]);
                currentNode.weight.Add(dist);
                Sampler.transform.position = transform.TransformPoint(meshGraph.vertices[i]);
                if (Physics.Raycast(Sampler.transform.position, Vector3.Normalize(meshGraph.vertices[neighbors[j]] - meshGraph.vertices[i]), dist))
                {
                    if (!DeadVertices.Contains(neighbors[j]))
                    {
                        DeadVertices.Add(neighbors[j]); DeadNodes.Add(simpleGraph.graph[neighbors[j]]); break;
                    }
                }
            }
            //Debug.Log(i);
        }

        foreach (pathNode node in DeadNodes)
        {
            simpleGraph.DeleteNode(node.ID);
        }

        //Rebuild mesh
        NavMeshGenerator.RemoveTriangles(meshGraph, DeadVertices);
    }
예제 #2
0
 //Call delete function for graph as well as reorganize the nodes in the editor net
 public void DeleteNode(int A)
 {
     Graph.DeleteNode(A);
     Debug.Log("Deleting!");
     pathNodeContainer [] nodeObjs = gameObject.GetComponentsInChildren <pathNodeContainer>();
     Debug.Log(nodeObjs.Length);
     for (int i = A; i < nodeObjs.Length; i++)
     {
         nodeObjs[i].Node = Graph.GetNodeList()[i];
         nodeObjs[i].GenerateName();
     }
 }
예제 #3
0
    //Faster Method
    public void BuildPlaneGraph(float width, float height, int segments)
    {
        this.width  = width;
        this.height = height;
        simpleGraph = new GraphSimple();
        List <int>   Neighbors   = new List <int>();
        List <float> Weights     = new List <float>();
        float        deltaHeight = height / segments;
        float        deltaWidth  = width / segments;

        //transform.TransformPoint(new Vector3(j*(width/segments)-width/2, 0, i*(height/segments)-height/2));
        simpleGraph.AddNodes((segments + 1) * (segments + 1));
        List <pathNode> DeadNodes = new List <pathNode>();
        List <int>      DeadVerts = new List <int>();

        pathNode currentNode;

        for (int i = 0; i <= segments; i++)
        {
            for (int j = 0; j <= segments; j++)
            {
                currentNode = simpleGraph.GetNodeList()[i * (segments + 1) + j];

                currentNode.position = transform.TransformPoint(new Vector3(j * (deltaWidth) - width / 2, 0, i * (deltaHeight) - height / 2));
                //RaycastHit hit;
                //if (Physics.Raycast(currentNode.position, -Vector3.up, out hit))
                //{
                //	currentNode.position=transform.TransformPoint(new Vector3(j*(deltaWidth)-width/2, hit.point.y, i*(deltaHeight)-height/2));
                //}

                Neighbors.Clear();
                Weights.Clear();

                //Debug.Log ("Node #"+(i*(segments+1)+j));

                //Up and Down
                if (i > 0)
                {
                    Neighbors.Add(((i - 1) * (segments + 1) + (j)));
                    Weights.Add(deltaHeight);
                    //Debug.Log ("Down");
                }
                if (i < segments)
                {
                    Neighbors.Add(((i + 1) * (segments + 1) + (j)));
                    Weights.Add(deltaHeight);
                    //Debug.Log ("Up");
                }

                //Left and Right
                if (j > 0)
                {
                    Neighbors.Add(((i) * (segments + 1) + (j - 1)));
                    Weights.Add(deltaWidth);
                    //Debug.Log ("Left");
                }
                if (j < segments)
                {
                    Neighbors.Add(((i) * (segments + 1) + (j + 1)));
                    Weights.Add(deltaWidth);
                    //Debug.Log ("Right");
                }
                //Top-left to Bottom-right Diagonal
                if (i > 0 && j > 0)
                {
                    Neighbors.Add((i - 1) * (segments + 1) + (j - 1));
                    Weights.Add(Mathf.Sqrt(deltaWidth * deltaWidth + deltaHeight * deltaHeight));
                    //Debug.Log ("Bottom Left");
                }
                if (i < segments && j < segments)
                {
                    Neighbors.Add((i + 1) * (segments + 1) + (j + 1));
                    Weights.Add(Mathf.Sqrt(deltaWidth * deltaWidth + deltaHeight * deltaHeight));
                    //Debug.Log ("Top right");
                }

                //Top-right to Bottom-left Diagonal
                if ((i < segments) && j > 0)
                {
                    Neighbors.Add(((i + 1) * (segments + 1) + (j - 1)));
                    Weights.Add(Mathf.Sqrt(deltaWidth * deltaWidth + deltaHeight * deltaHeight));
                    //Debug.Log ("Top left");
                }
                if (i > 0 && j < segments)
                {
                    Neighbors.Add((i - 1) * (segments + 1) + (j + 1));
                    Weights.Add(Mathf.Sqrt(deltaWidth * deltaWidth + deltaHeight * deltaHeight));
                    //Debug.Log ("Bottom Right");
                }

                int index = 0;
                foreach (int Neighbor in Neighbors)
                {
                    //Debug.Log (Neighbor);
                    pathNode neighbor = simpleGraph.GetNodeList()[Neighbor];
                    currentNode.neighbors.Add(neighbor);
                    currentNode.weight.Add(Weights[index]);
                    index++;
                }
                //Debug.Log(i);
            }
        }

        foreach (pathNode node in simpleGraph.GetNodeList())
        {
            node.dist = 0;
        }

        //Scan physics graph
        foreach (pathNode node in simpleGraph.GetNodeList())
        {
            //Debug.Log (node.neighbors.Count);
            for (int i = 0; i < node.neighbors.Count; i++)
            {
                pathNode Neighbor = node.neighbors[i];
                //Debug.Log ("Ray cast from "+node.position+" to "+Neighbor.position+" with a distance of "+Vector3.Distance(Neighbor.position,node.position));
                //Debug.Log ("Node #"+node.ID+" Hit toward: "+Neighbor.ID);
                if (Physics.Raycast(node.position, Vector3.Normalize(Neighbor.position - node.position), Vector3.Distance(Neighbor.position, node.position)))
                {
                    //Debug.DrawLine(Neighbor.position,node.position);
                    if (!Physics.Raycast(node.position, Vector3.Normalize(node.position - Neighbor.position), Vector3.Distance(Neighbor.position, node.position)))
                    {
                        if (DeadVerts.Contains(Neighbor.ID))
                        {
                            DeadNodes.Add(Neighbor); DeadVerts.Add(Neighbor.ID);
                        }
                    }
                    //removeCount++;
                    node.neighbors.RemoveAt(i);
                    node.weight.RemoveAt(i);
                    i--;
                    Neighbor.dist += 1;
                }
            }
        }

        //Dead Node Removal
        for (int i = 0; i < DeadNodes.Count; i++)
        {
            //Debug.Log (DeadNodes[i]);
            simpleGraph.DeleteNode(DeadNodes[i].ID);
        }


        //Filter nodes Remove count
        for (int i = 0; i < simpleGraph.NodeCount; i++)
        {
            pathNode node = simpleGraph.GetNodeList()[i];
            //Debug.Log("Hit count: "+node.dist);
            if (node.dist >= 3)
            {
                simpleGraph.DeleteNode(node.ID);
                i--;
            }
        }

        for (int i = 0; i < simpleGraph.NodeCount; i++)
        {
            pathNode node = simpleGraph.GetNodeList()[i];
            if (node.neighbors.Count < 3)
            {
                simpleGraph.DeleteNode(node.ID);
            }
        }
    }
예제 #4
0
    public List <pathNode> ShortestPath(int SourceGraphIndex, int SourceNode, int DestGraphIndex, int DestNode)
    {
        List <pathNode> shortestPath = new List <pathNode>();



        if (SourceGraphIndex == DestGraphIndex)
        {
            if (SourceNode == DestNode)
            {
                return(shortestPath);
            }

            return(Dijkstra.ShortestPath(Graphs[SourceGraphIndex], SourceNode, DestNode));
        }

        //Set node = to position of Source Node in Source graph
        pathNode sparseSourceNode = sparseGraph.GetNodeList()[0];

        sparseSourceNode.neighbors.Clear();
        sparseSourceNode.weight.Clear();
        sparseSourceNode.position = Graphs[SourceGraphIndex].GetNodeList()[SourceNode].position;
        int NumSourceNeigbors = Graphs[SourceGraphIndex].Links.Count;

        //Calculate weights/connections for Source Node
        foreach (pathNode node in Graphs[SourceGraphIndex].Links)
        {
            //Get distance to each door
            sparseSourceNode.neighbors.Add(node);
            node.neighbors.Add(sparseSourceNode);
            float dist = Vector3.Distance(sparseSourceNode.position, node.position);
            sparseSourceNode.weight.Add(dist);
            node.weight.Add(dist);
        }



        //Set last node = to position of Destination Node in Source graph
        sparseGraph.AddNodes(1);
        pathNode sparseDestNode = sparseGraph.GetNodeList()[sparseGraph.NodeCount - 1];

        sparseDestNode.neighbors.Clear();
        sparseDestNode.weight.Clear();
        sparseDestNode.position = Graphs[DestGraphIndex].GetNodeList()[DestNode].position;
        int NumDestNeigbors = Graphs[DestGraphIndex].Links.Count;

        //Calculate weights/connections for Source Node
        foreach (pathNode node in Graphs[DestGraphIndex].Links)
        {
            //Get distance to each door
            sparseDestNode.neighbors.Add(node);
            node.neighbors.Add(sparseDestNode);
            float dist = Vector3.Distance(sparseDestNode.position, node.position);
            sparseDestNode.weight.Add(dist);
            node.weight.Add(dist);
        }
        //Pathfinding on sparse graph
        //Debug.Log ("Calculating shortest Sparse Graph");
        List <pathNode> sparsePath = Dijkstra.ShortestPath(sparseGraph, 0, sparseGraph.GetNodeList().Count - 1);

        //Debug.Log ("sparsePath Calculated");
        //Debug.Log ("Path will travel through these transitions");
        //Debug.Log("Start at Graph "+SourceGraphIndex+" Node " + SourceNode);
        foreach (pathNode node in sparsePath)
        {
            if (node.ID == 0)
            {
                //Debug.Log("Node 0 is the starting point at graph node "+SourceNode);
                continue;
            }

            if (node.ID == sparsePath.Count)
            {
                //Debug.Log("Node "+node.ID+" is the ending point at graph node "+DestNode);
                continue;
            }

            //Debug.Log ("Node: "+node.ID);
        }

        //Debug.Log("End at Graph "+DestGraphIndex+" Node " + DestNode);

        //Clean up so that there are no leftover neighbors/weights
        foreach (pathNode node in Graphs[SourceGraphIndex].Links)
        {
            node.neighbors.RemoveAt(node.neighbors.Count - 1);
            node.weight.RemoveAt(node.weight.Count - 1);
        }

        foreach (pathNode node in Graphs[DestGraphIndex].Links)
        {
            node.neighbors.RemoveAt(node.neighbors.Count - 1);
            node.weight.RemoveAt(node.weight.Count - 1);
        }

        GraphSimple SourceGraph = Graphs[SourceGraphIndex];
        GraphSimple DestGraph   = Graphs[DestGraphIndex];

        int LinkIndex = SourceGraph.Links.IndexOf(sparsePath[1]);

        //SUCCESS!
        //Debug.Log ("Moving from "+SourceNode+" to "+SourceGraph.TransitionNodes[LinkIndex]);
        //Begin search with path toward door labeled by sparsePath #1
        shortestPath.AddRange(Dijkstra.ShortestPath(SourceGraph, SourceNode, SourceGraph.TransitionNodes[LinkIndex]));
        //Debug.Log ("Initial Path to transition Node: ");
        foreach (pathNode node in shortestPath)
        {
            //Debug.Log("Node "+node.ID);
        }
        //Debug.Log ("End first segments");

        GraphSimple CurrentGraph = SourceGraph.NeighborGraphs[LinkIndex];
        int         Index        = 0;

        for (int i = 1; i < sparsePath.Count - 2; i++)
        {
            Index = shortestPath.Count;
            //Debug.Log ("In Graph # "+CurrentGraph.GraphID+" :");
            //Debug.Log ("New Segment from transition " +sparsePath[i].ID+ " to "+sparsePath[i+1].ID);
            //int StartIndex=CurrentGraph.Links.IndexOf(sparsePath[i]);
            int EndIndex = CurrentGraph.Links.IndexOf(sparsePath[i + 1]);
            //Remove the last node so that there isn't doubled up vector3s during transition
            //Results in smoother transtions
            shortestPath.RemoveAt(shortestPath.Count - 1);
            //shortestPath.AddRange(Dijkstra.ShortestPath(CurrentGraph,CurrentGraph.TransitionNodes[StartIndex],SourceGraph.TransitionNodes[EndIndex]));
            //Debug.Log(
            shortestPath.AddRange(CurrentGraph.GetBakedPath(sparsePath[i].ID, sparsePath[i + 1].ID));
            foreach (pathNode node in shortestPath.GetRange(Index, shortestPath.Count - Index))
            {
                //Debug.Log("Node "+node.ID);
            }
            CurrentGraph = CurrentGraph.NeighborGraphs[EndIndex];
        }
        shortestPath.RemoveAt(shortestPath.Count - 1);
        LinkIndex = DestGraph.Links.IndexOf(sparsePath[sparsePath.Count - 2]);
        //Debug.Log ("Moving from "+DestGraph.TransitionNodes[LinkIndex]+" to "+DestNode);
        //End search with path toward point labeled by sparsePath #1
        shortestPath.AddRange(Dijkstra.ShortestPath(DestGraph, DestGraph.TransitionNodes[LinkIndex], DestNode));
        sparseGraph.DeleteNode(sparseGraph.NodeCount - 1);
        return(shortestPath);
    }