//Add graph to masterlist and assign an ID to the graph public void AddGraph(GraphSimple Graph) { if (!Graphs.Contains(Graph)) { Graph.GraphID = Graphs.Count; Graphs.Add(Graph); GraphCount++; } }
// Use this for initialization void Start() { if (Graph == null) { Graph = new GraphSimple(); } RefreshReferences(); //List<pathNode> path=Dijkstra.ShortestPath(Graph,0,2); }
//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); }
private static List <float> GetDistances(GraphSimple graphIn) { List <float> distances = new List <float>(); List <pathNode> graph = graphIn.GetNodeList(); for (int i = 0; i < graph.Count; i++) { distances.Add(graph[i].dist); } return(distances); }
void Update() { if (start) { if (NodePath == null) { (GraphContainer.GetComponent(typeof(SimpleAIGraphContainer)) as SimpleAIGraphContainer).RefreshReferences(); NodePath = (GraphContainer.GetComponent(typeof(SimpleAIGraphContainer)) as SimpleAIGraphContainer).GetGraph(); } if (SimpleAIState == MoveState.RandomWalk) { currentNode = Random.Range(0, NodePath.NodeCount); destinationNode = currentNode; } TeleportToNode(currentNode); arrow = Resources.Load <GameObject>("Prefabs/Arrows/Arrow_Simple"); start = false; } if (currentNode == destinationNode && SimpleAIState != MoveState.Halt) { if (SimpleAIState == MoveState.RandomWalk) { TravelToNode(Random.Range(0, NodePath.NodeCount), speed); } else if (SimpleAIState == MoveState.Patrol) { if (currentNode == patrolStart) { TravelToNode(patrolEnd, speed); } else { TravelToNode(patrolStart, speed); } } else if (currentNode != destinationNode && !traveling) { if (SimpleAIState == MoveState.Teleport) { TeleportToNode(destinationNode); destinationNode = currentNode; } else if (SimpleAIState == MoveState.Manual) { TravelToNode(destinationNode, speed); } } } }
public void LinkGraph(GraphSimple linkedGraph, int NodePos, pathNode Link) { foreach (GraphSimple link in NeighborGraphs) { if (link == linkedGraph) { return; } } NeighborGraphs.Add(linkedGraph); TransitionNodes.Add(NodePos); Links.Add(Link); }
void OnEnable() { _target = (SimpleAIGraphContainer)target; Graph = _target.GetGraph(); if (Graph == null) { Graph = new GraphSimple(); } //Ensure that the root node is part of the path if (Graph.NodeCount < 1) { Graph.AddNodes(1); Graph.GetNodeList()[0].position = _target.transform.position; } }
//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); } } }
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); }
public MultiGraph() { sparseGraph = new GraphSimple(1); Graphs = new List <GraphSimple>(); }
public static List <float> AllDistancesFromNode(GraphSimple graphIn, int SourceIndex) { ShortestPath(graphIn, SourceIndex, graphIn.NodeCount); return(GetDistances(graphIn)); }
//public List<pathNode> shortestPath = new List<pathNode>(); public static List <pathNode> ShortestPath(GraphSimple graphIn, int SourceIndex, int DestinationIndex) { //Create temp list for shortest path List <pathNode> shortestPath = new List <pathNode>(); List <pathNode> graph = graphIn.GetNodeList(); if (SourceIndex == DestinationIndex) { shortestPath.Add(graph[SourceIndex]); Debug.Log("Indices the same!"); return(shortestPath); } //Reset distances //Find source and destination nodes for (int i = 0; i < graph.Count; i++) { graph[i].dist = Mathf.Infinity; graph[i].previous = null; graph[i].Removed = false; } //Set the initial node as a distance of 0 graph[SourceIndex].dist = 0; //While nodes are not empty int nodesLeft = graph.Count; while (nodesLeft > 0) { pathNode min = new pathNode(); //Grab shortest distance point. Accounts for ALL nodes for (int i = 0; i < graph.Count; i++) { if ((graph[i].dist < min.dist) && !graph[i].Removed) { min = graph[i]; } } //Re-reference min to a new name. Combine them? pathNode smallestpathNode = min; //Remove node graph[smallestpathNode.ID].Removed = true; nodesLeft--; //Exit condition. Destination Reached! if ((smallestpathNode.ID == DestinationIndex)) { //Debug.Log ("Found!"); return(getPath(smallestpathNode)); } //We can't reach the node! else if (smallestpathNode.dist == Mathf.Infinity) { //Debug.Log("No connection!"); return(shortestPath); } //List<pathNode> neighbors = smallestpathNode.neighbors; for (int i = 0; i < smallestpathNode.neighbors.Count; i++) { float alt = smallestpathNode.dist + smallestpathNode.weight[i]; if (alt < smallestpathNode.neighbors[i].dist) { smallestpathNode.neighbors[i].dist = alt; smallestpathNode.neighbors[i].previous = smallestpathNode; } } } Debug.Log("All Nodes Ventured"); return(shortestPath); }
// Use this for initialization void OnEnable() { _target = (pathNodeContainer)target; GraphContainer = _target.transform.parent.GetComponent(typeof(SimpleAIGraphContainer)) as SimpleAIGraphContainer; Graph = GraphContainer.GetGraph(); }
public void ChangeGraph(GraphSimple graph) { NodePath = graph; }