예제 #1
0
 //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++;
     }
 }
예제 #2
0
 // Use this for initialization
 void Start()
 {
     if (Graph == null)
     {
         Graph = new GraphSimple();
     }
     RefreshReferences();
     //List<pathNode> path=Dijkstra.ShortestPath(Graph,0,2);
 }
예제 #3
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);
    }
예제 #4
0
    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);
    }
예제 #5
0
    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);
                }
            }
        }
    }
예제 #6
0
    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);
    }
예제 #7
0
 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;
     }
 }
예제 #8
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);
            }
        }
    }
예제 #9
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);
    }
예제 #10
0
 public MultiGraph()
 {
     sparseGraph = new GraphSimple(1);
     Graphs      = new List <GraphSimple>();
 }
예제 #11
0
 public static List <float> AllDistancesFromNode(GraphSimple graphIn, int SourceIndex)
 {
     ShortestPath(graphIn, SourceIndex, graphIn.NodeCount);
     return(GetDistances(graphIn));
 }
예제 #12
0
    //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);
    }
예제 #13
0
    // Use this for initialization

    void OnEnable()
    {
        _target        = (pathNodeContainer)target;
        GraphContainer = _target.transform.parent.GetComponent(typeof(SimpleAIGraphContainer)) as SimpleAIGraphContainer;
        Graph          = GraphContainer.GetGraph();
    }
예제 #14
0
 public void ChangeGraph(GraphSimple graph)
 {
     NodePath = graph;
 }