예제 #1
0
        protected override void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            //TODO: Implement this method for the GoalBoundingPathfinding to Work. If you implemented the NodeArrayAStar properly, you wont need to change the search method.
            //Fetching index of GoalBoundingTable
            NodeRecord     childNodeRecord = NodeRecordArray.GetNodeRecord(connectionEdge.ToNode);
            int            index           = childNodeRecord.node.NodeIndex;
            NodeGoalBounds nodeBounds      = GoalBoundingTable.table[index];

            if (nodeBounds == null) //Special check for some nodes that have null nodeBounds??? is NodeIndex correct or is the table malformed?
            {
                base.ProcessChildNode(parentNode, connectionEdge, edgeIndex);
            }

            //TODO: needs fix

            /* Check if the box of parent node in the direction of the childnode has goal within. Not working due to arrayIndexExceptions:
             *
             * DataStructures.GoalBounding.Bounds b = nodeBounds.connectionBounds[edgeIndex];
             * if (!b.PositionInsideBounds(GoalPosition))
             * {
             *  this.DiscardedEdges++;
             *  return;
             * }
             */
            base.ProcessChildNode(parentNode, connectionEdge, edgeIndex);
        }
예제 #2
0
        public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds)
        {
            //TODO: Implement the algorithm that calculates the goal bounds using a dijkstra
            //Given that the nodes in the graph correspond to the edges of a polygon, we won't be able to use the vertices of the polygon to update the bounding boxes
            this.Open.Initialize();
            this.Closed.Initialize();


            NodeRecord StartNode = NodeRecordArray.GetNodeRecord(startNode);

            StartNode.StartNodeOutConnectionIndex = -1;
            Open.AddToOpen(StartNode);
            int OpenSize = Open.All().Count;

            while (OpenSize > 0)
            {
                NodeRecord currentNode = Open.GetBestAndRemove();
                Open.RemoveFromOpen(currentNode);
                Closed.AddToClosed(currentNode);
                if (currentNode.StartNodeOutConnectionIndex != -1)
                {
                    nodeGoalBounds.connectionBounds[currentNode.StartNodeOutConnectionIndex].UpdateBounds(currentNode.node.Position);
                }

                //Initialize start node edge colors:
                var outConnections = currentNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i);
                }
                OpenSize = Open.All().Count;
            }
        }
        protected void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge, int connectionIndex)
        {
            float g;

            var childNode       = connectionEdge.ToNode;
            var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);

            //custo da sol ate agora (valor do no anterior mais a aresta do bestNode ate ao childnode)
            g = parent.gValue + connectionEdge.Cost;

            if (childNodeRecord.status == NodeStatus.Unvisited)
            {
                childNodeRecord.gValue = g;
                childNodeRecord.parent = parent;
                NodeRecordArray.AddToOpen(childNodeRecord);
                childNodeRecord.StartNodeOutConnectionIndex = connectionIndex;   //das cor
            }
            else if (childNodeRecord.status == NodeStatus.Open && (childNodeRecord.gValue > g))
            {
                childNodeRecord.gValue = g;
                childNodeRecord.parent = parent;
                NodeRecordArray.Replace(childNodeRecord, childNodeRecord);
                childNodeRecord.StartNodeOutConnectionIndex = connectionIndex;    //trocas cor
            }
        }
        public NodeArrayAStarPathFinding(NavMeshPathGraph graph, IHeuristic heuristic) : base(graph, null, null, heuristic)
        {
            //do not change this
            var nodes = this.GetNodesHack(graph);

            this.NodeRecordArray = new NodeRecordArray(nodes);
            this.Open            = this.NodeRecordArray;
            this.Closed          = this.NodeRecordArray;
        }
예제 #5
0
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge, int connectionIndex, NodeGoalBounds nodeGoalBounds)
        {
            //TODO: Implement this method that processes a child node. Then you can use it in the Search method above.
            var        childNode       = connectionEdge.ToNode;
            NodeRecord childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);

            if (childNodeRecord.startNodeIndex != startNodeIndex)
            {
                childNodeRecord.status = NodeStatus.Unvisited;
            }

            if (childNodeRecord == null)
            {
                //this piece of code is used just because of the special start nodes and goal nodes added to the RAIN Navigation graph when a new search is performed.
                //Since these special goals were not in the original navigation graph, they will not be stored in the NodeRecordArray and we will have to add them
                //to a special structure
                //it's ok if you don't understand this, this is a hack and not part of the NodeArrayA* algorithm, just do NOT CHANGE THIS, or your algorithm will not work
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            if (childNodeRecord.status == NodeStatus.Closed)
            {
                return;
            }

            float g = bestNode.gValue + connectionEdge.Cost;
            float f = g;

            if (childNodeRecord.status == NodeStatus.Unvisited)
            {
                ChangeNodeValues(childNodeRecord, 0, g, f, bestNode, connectionIndex);
                NodeRecordArray.AddToOpen(childNodeRecord);
                return;
            }
            if (childNodeRecord.status == NodeStatus.Open && childNodeRecord.fValue > f)
            {
                ChangeNodeValues(childNodeRecord, 0, g, f, bestNode, connectionIndex);
                this.NodeRecordArray.Replace(childNodeRecord, childNodeRecord);
                return;
            }
        }
예제 #6
0
        public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds)
        {
            //TODO: Implement the algorithm that calculates the goal bounds using a dijkstra
            //Given that the nodes in the graph correspond to the edges of a polygon, we won't be able to use the vertices of the polygon to update the bounding boxes
            this.Open.Initialize();
            this.Closed.Initialize();

            //Initialize starting node for Dijkstra
            NodeRecord StartNode = NodeRecordArray.GetNodeRecord(startNode);

            StartNode.gValue = 0;
            StartNode.StartNodeOutConnectionIndex = -1; // -1 corresponds to not having a "color". Valid indices will start at 0
            Open.AddToOpen(StartNode);

            //Dijkstra
            while (Open.CountOpen() > 0)
            {
                NodeRecord currentNode = Open.GetBestAndRemove();

                Open.RemoveFromOpen(currentNode);
                Closed.AddToClosed(currentNode);

                //We don't fill out the starting position as it is colorless
                if (currentNode.StartNodeOutConnectionIndex != -1)
                {
                    var outFillConnections = currentNode.node.OutEdgeCount;

                    Vector3 edgePosition;
                    //Update the bounding box with all positions of EdgeOuts of the current Node
                    for (int i = 0; i < outFillConnections; i++)
                    {
                        edgePosition = currentNode.node.EdgeOut(i).ToNode.Position;
                        nodeGoalBounds.connectionBounds[currentNode.StartNodeOutConnectionIndex].UpdateBounds(edgePosition); //update only the bound corresponding to the ConnectionIndex
                    }
                }

                //Process Child Nodes
                var outConnections = currentNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i);
                }
            }
        }
        //cria rectangulos
        public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds)
        {
            //TODO: Implement the algorithm that calculates the goal bounds using a dijkstra
            //Given that the nodes in the graph correspond to the edges of a polygon, we won't be able to use the vertices of the polygon to update the bounding boxes


            // mete os vizinhos do no inicial. Inicializacao da lista
            var outConnections = startNode.OutEdgeCount;

            for (int i = 0; i < outConnections; i++)
            {
                NavigationGraphEdge edge = startNode.EdgeOut(i);

                var childNode       = edge.ToNode;
                var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);
                //adicionar ao open
                NodeRecordArray.AddToOpen(childNodeRecord);

                //transformar em vector3 para inicializar cada rectangulo
                childNodeRecord.StartNodeOutConnectionIndex = i;
            }

            //giro:  var startTime = Time.realtimeSinceStartup;

            //enquanto houver nos no conj open
            while (this.Open.CountOpen() > 0)
            {
                NodeRecord bestNode = this.Open.GetBestAndRemove();

                //aumentar o rectangulo
                nodeGoalBounds.connectionBounds[bestNode.StartNodeOutConnectionIndex].UpdateBounds(bestNode.node.LocalPosition); //isto e a cor do rectangulo. falta updateBounds

                this.Closed.AddToClosed(bestNode);

                //para ver as ligacoes do no que acabamos de ver
                var outConnections2 = bestNode.node.OutEdgeCount;
                for (int j = 0; j < outConnections2; j++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(j), bestNode.StartNodeOutConnectionIndex);
                }
                // giro: this.MaxOpenNodes = Mathf.Max(this.Open.CountOpen(), this.MaxOpenNodes);
            }
        }
        private void ApplayDijkstraAll()
        {
            if (navMesh != null)
            {
                nodes = GetNodesHack(navMesh);

                if (useNodeRecordArray)
                {
                    Debug.Log("UsingNodeRecordArray");
                    recordArray = new NodeRecordArray<NavigationGraphNode, GoalBoundingRecord>(nodes);

                    Open = recordArray;
                    Closed = recordArray;
                }
                else
                {
                    Debug.Log("NotUsingNodeRecordArray");
                    Open = new LeftPriorityList<GoalBoundingRecord>();
                    Closed = new ClosedDictionary<NavigationGraphNode, GoalBoundingRecord>();
                }

                DummyRecord = new GoalBoundingRecord();

                float runningTime = Time.realtimeSinceStartup;

                boundingBoxes = new List<List<BoundingBox>>(new List<BoundingBox>[nodes.Count]);

                for (int i = 0; i < nodes.Count; i++)
                {
                    nodes[i].NodeIndex = i;
                }

                for (int k = 0; k < nodes.Count; k++)
                {
                    if (useNodeRecordArray)
                    {
                        ApplyDijkstraNodeArray(nodes[k]);
                    }
                    else
                    {
                        ApplyDijkstra(nodes[k]);
                    }

                    ICollection<GoalBoundingRecord> closed = Closed.All();
                    foreach (GoalBoundingRecord record in closed)
                    {
                        if (record.OriginBoundingBox != null)
                        {
                            record.OriginBoundingBox.Update(record.Location.Position);
                        }
                    }
                    if (boundingBoxes[k] != null)
                    {
                        foreach (BoundingBox boundingBox in boundingBoxes[k])
                        {
                            boundingBox.Update(nodes[k].Position);
                        }
                    }

                    PrintTimeFunc(k, Time.realtimeSinceStartup - runningTime);
                }

                //last print
                Debug.Log("Nodes: " + nodes.Count + " Processing time: " + (Time.realtimeSinceStartup - runningTime) + " s");
            }
        }
예제 #9
0
        //protected override void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        protected override void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge)
        {
            //TODO: Implement this method for the GoalBoundingPathfinding to Work. If you implemented the NodeArrayAStar properly, you wont need to change the search method.
            float f;
            float g;
            float h;

            var childNode       = connectionEdge.ToNode;
            var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);

            if (childNodeRecord == null)
            {
                //this piece of code is used just because of the special start nodes and goal nodes added to the RAIN Navigation graph when a new search is performed.
                //Since these special goals were not in the original navigation graph, they will not be stored in the NodeRecordArray and we will have to add them
                //to a special structure
                //it's ok if you don't understand this, this is a hack and not part of the NodeArrayA* algorithm, just do NOT CHANGE THIS, or your algorithm will not work
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = parentNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            //TODO: implement the rest of your code here

            //custo da sol ate agora (valor do no anterior mais a aresta do bestNode ate ao childnode)
            g = parentNode.gValue + connectionEdge.Cost;
            //funcao heuristica: melhor custo estimado de n ate a solucao (como AStarPathFinding)
            h = this.Heuristic.H(childNode, this.GoalNode);
            f = F(g, h);

            //indice da cor do rectangulo
            var color = childNodeRecord.StartNodeOutConnectionIndex;

            //indice startNode
            var startNode = childNodeRecord.node.NodeIndex;

            //entrada da tabela dos rectangulos
            //var bbox = this.goalBoundingTable.table[color].connectionBounds[startNode];
            bool inBounds;

            if (this.goalBoundingTable.table[startNode] != null)
            {
                var bbox = this.goalBoundingTable.table[startNode].connectionBounds[color];
                inBounds = bbox.PositionInsideBounds(childNodeRecord.node.Position);
            }
            else
            {
                inBounds = true;
            }


            if (childNodeRecord.status == NodeStatus.Unvisited && inBounds)
            {
                childNodeRecord.fValue = f;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.parent = parentNode;
                NodeRecordArray.AddToOpen(childNodeRecord);
            }
            else if (childNodeRecord.status == NodeStatus.Open && (childNodeRecord.fValue > f || (f == childNodeRecord.fValue && childNodeRecord.hValue > h)))
            {
                childNodeRecord.fValue = f;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.parent = parentNode;
                NodeRecordArray.Replace(childNodeRecord, childNodeRecord);
            }
            else if (childNodeRecord.status == NodeStatus.Closed && f < childNodeRecord.fValue)
            {
                childNodeRecord.fValue = f;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.parent = parentNode;
                NodeRecordArray.RemoveFromClosed(childNodeRecord);
                NodeRecordArray.AddToOpen(childNodeRecord);
            }
        }