Пример #1
0
        //don't forget to add the override keyword here if you define a ProcessChildNode method in the base class
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            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 you algorithm wont work
                childNodeRecord = new NodeRecord
                {
                    node = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            g = bestNode.gValue + connectionEdge.Cost;
            h = this.Heuristic.H(childNode, this.GoalNode);
            f = g + h;

            var oldChildNodeOpen = Open.SearchInOpen(childNodeRecord);
            var oldChildNodeClosed = Closed.SearchInClosed(childNodeRecord);

            if ((oldChildNodeClosed == null) && (oldChildNodeOpen == null))
            {

                childNodeRecord.parent = bestNode;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;

                Open.AddToOpen(childNodeRecord);
            }
            else if ((oldChildNodeOpen != null) && f < childNodeRecord.fValue)
            {
                childNodeRecord.parent = bestNode;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;

                Open.Replace(oldChildNodeOpen, childNodeRecord);

            }
            else if ((oldChildNodeClosed != null) && f < childNodeRecord.fValue)
            {
                childNodeRecord.parent = bestNode;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;

                Open.AddToOpen(childNodeRecord);
            }
        }
        public void InitializePathfindingSearch(Vector3 startPosition, Vector3 goalPosition)
        {
            
            this.StartPosition = startPosition;
            this.GoalPosition = goalPosition;
            this.StartNode = this.Quantize(this.StartPosition);
            this.GoalNode = this.Quantize(this.GoalPosition);

            //if it is not possible to quantize the positions and find the corresponding nodes, then we cannot proceed
            if (this.StartNode == null || this.GoalNode == null) return;

            //I need to do this because in Recast NavMesh graph, the edges of polygons are considered to be nodes and not the connections.
            //Theoretically the Quantize method should then return the appropriate edge, but instead it returns a polygon
            //Therefore, we need to create one explicit connection between the polygon and each edge of the corresponding polygon for the search algorithm to work
            ((NavMeshPoly)this.StartNode).AddConnectedPoly(this.StartPosition);
            ((NavMeshPoly)this.GoalNode).AddConnectedPoly(this.GoalPosition);

            this.InProgress = true;
            this.TotalProcessedNodes = 0;
            this.TotalProcessingTime = 0.0f;
            this.MaxOpenNodes = 0;

            var initialNode = new NodeRecord
            {
                gValue = 0,
                hValue = this.Heuristic.H(this.StartNode, this.GoalNode),
                node = this.StartNode
            };

            initialNode.fValue = AStarPathfinding.F(initialNode);

            this.Open.Initialize(); 
            this.Open.AddToOpen(initialNode.node, initialNode);
            this.Closed.Initialize();
        }
 protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
 {
     if (CheckNode(bestNode, connectionEdge))
     {
         base.ProcessChildNode(bestNode, connectionEdge);
     }
 }
        //don't forget to add the override keyword here if you define a ProcessChildNode method in the base class
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            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 you algorithm wont work
                childNodeRecord = new NodeRecord
                {
                    node = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            float securityValue = 0;
            this.character.SecurityInfluence.TryGetValue(childNode.Position, out securityValue);

            if(securityValue < 0)
            {

                this.NodeRecordArray.AddToClosed(childNodeRecord);
                return;
            }

            float g = bestNode.gValue + connectionEdge.Cost;
            float h = this.Heuristic.H(childNode, this.GoalNode);
            float f = F(g, h);

            // if child state is not in open or in closed then insert in open
            if (childNodeRecord.status == NodeStatus.Unvisited)
            {
                UpdateNodeRecord(childNodeRecord, bestNode, g, h);
                this.NodeRecordArray.AddToOpen(childNodeRecord);
            } else
            {
                // if child state is in open with higher F-value replace old one
                if (childNodeRecord.status == NodeStatus.Open && childNodeRecord.fValue > f)
                {
                    UpdateNodeRecord(childNodeRecord, bestNode, g, h);
                    this.NodeRecordArray.Replace(childNodeRecord, childNodeRecord);
                } else
                {
                    // if child state is in close with higher F-value then delete old and add new to open
                    if (childNodeRecord.status == NodeStatus.Closed && childNodeRecord.fValue > f)
                    {
                        UpdateNodeRecord(childNodeRecord, bestNode, g, h);
                        NodeRecordArray.RemoveFromClosed(childNodeRecord);
                        NodeRecordArray.AddToOpen(childNodeRecord);
                    }
                }
            }
        }
        //don't forget to add the override keyword here if you define a ProcessChildNode method in the base class
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            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 you algorithm wont work
                childNodeRecord = new NodeRecord
                {
                    node = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            childNodeRecord.gValue = bestNode.gValue + connectionEdge.Cost;
            childNodeRecord.hValue = this.Heuristic.H(childNode, this.GoalNode);
            childNodeRecord.fValue = F(childNodeRecord);

            NodeRecord openNode = Open.SearchInOpen(childNodeRecord);
            NodeRecord closedNode = Closed.SearchInClosed(childNodeRecord);

            if (openNode == null && closedNode == null)
                Open.AddToOpen(childNodeRecord);
            else if (openNode != null && openNode.fValue > childNodeRecord.fValue)
                Open.Replace(openNode, childNodeRecord);
            else if (closedNode != null && closedNode.fValue > childNodeRecord.fValue)
            {
                Closed.RemoveFromClosed(closedNode);
                Open.AddToOpen(childNodeRecord);
            }
        }
Пример #6
0
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            float f;
            float g;
            float h;

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

            #region do not look into this
            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);
            }
            #endregion

            h = this.Heuristic.H(childNode, this.GoalNode);
            g = bestNode.gValue + connectionEdge.Cost;
            f = g + h;

            NodeRecord nodeOpen   = this.Open.SearchInOpen(childNodeRecord);
            NodeRecord closedNode = this.Closed.SearchInClosed(childNodeRecord);

            if (nodeOpen != null)
            {
                if (nodeOpen.fValue >= f)
                {
                    Open.RemoveFromOpen(nodeOpen);
                    childNodeRecord.parent = bestNode;
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    Open.AddToOpen(childNodeRecord);
                }
                return;
            }
            else if (closedNode != null)
            {
                if (closedNode.fValue > f)
                {
                    Closed.RemoveFromClosed(closedNode);
                    childNodeRecord.parent = bestNode;
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    Open.AddToOpen(childNodeRecord);
                }
                return;
            }
            childNodeRecord.parent = bestNode;
            childNodeRecord.gValue = g;
            childNodeRecord.hValue = h;
            childNodeRecord.fValue = f;
            Open.AddToOpen(childNodeRecord);
        }
 protected virtual bool CheckNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
 {
     return GoalBoundingManager.Instance.WithinBounds(bestNode.node, connectionEdge.ToNode, GoalPosition);
 }
        protected virtual void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge)
        {
            var childNode = connectionEdge.ToNode;
            var childNodeRecord = new NodeRecord
            {
                node = childNode,
                parent = parent,
                gValue = parent.gValue + connectionEdge.Cost,
                hValue = this.Heuristic.H(childNode, this.GoalNode)
            };

            childNodeRecord.fValue = F(childNodeRecord);
            NodeRecord openNode = Open.SearchInOpen(childNodeRecord);
            NodeRecord closedNode = Closed.SearchInClosed(childNodeRecord);

            if (openNode == null && closedNode == null)
                Open.AddToOpen(childNodeRecord);
            else if (openNode != null && openNode.fValue > childNodeRecord.fValue)
                Open.Replace(openNode, childNodeRecord);
            else if (closedNode != null && closedNode.fValue > childNodeRecord.fValue)
            {
                Closed.RemoveFromClosed(closedNode);
                Open.AddToOpen(childNodeRecord);
            }
        }
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            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
                childNodeRecord = new NodeRecord
                {
                    node = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            // implement the rest of your code here

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

            LocationRecord edgeFromLocRec = new LocationRecord(){
                Location = connectionEdge.FromNode
            };
            LocationRecord edgeToLocRec = new LocationRecord(){
                Location = connectionEdge.ToNode
            };
            float securityAverage = 0.0f;
            if (autonomousCharacter.SecurityMap.ContainsKey(edgeToLocRec) && autonomousCharacter.SecurityMap.ContainsKey(edgeFromLocRec))
            {
                securityAverage = (autonomousCharacter.SecurityMap[edgeFromLocRec] + autonomousCharacter.SecurityMap[edgeToLocRec]) * 0.5f;
            }

            g = bestNode.gValue +  connectionEdge.Cost/(1.5f + securityAverage);
            h = this.Heuristic.H(childNode, this.GoalNode);
            f = F(g,h);

            if (childNodeRecord.status == NodeStatus.Open)
            {
                if (f <= childNodeRecord.fValue)
                {
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    childNodeRecord.parent = bestNode;
                    this.NodeRecordArray.Replace(childNodeRecord,childNodeRecord);
                }
            }
            else
            {
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                childNodeRecord.status = NodeStatus.Open;
                childNodeRecord.parent = bestNode;
                this.NodeRecordArray.AddToOpen(childNodeRecord);
            }
        }
        protected virtual void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            var childNode = GenerateChildNodeRecord(bestNode, connectionEdge);

            NodeRecord nodeInOpen = Open.SearchInOpen(childNode);
            NodeRecord nodeInClosed = Closed.SearchInClosed(childNode);
            // if child state is not in open or in closed then insert in open
            if (nodeInOpen == null && nodeInClosed == null)
            {
                Open.AddToOpen(childNode);
            }
            else
            {
                // if child state is in open with higher F-value replace old one
                if (nodeInOpen != null && nodeInOpen.fValue > childNode.fValue)
                {
                    Open.Replace(nodeInOpen, childNode);
                }
                else
                {
                    // if child state is in close with higher F-value then delete old and add new to open
                    if (nodeInClosed != null && nodeInClosed.fValue > childNode.fValue)
                    {
                        Closed.RemoveFromClosed(nodeInClosed);
                        Open.AddToOpen(childNode);
                    }
                }
            }
        }
Пример #11
0
        protected GlobalPath CalculateSolution(NodeRecord node, bool partial)
        {
            var path = new GlobalPath
            {
                IsPartial = partial
            };
            var currentNode = node;

            path.PathPositions.Add(this.GoalPosition);

            //I need to remove the first Node and the last Node because they correspond to the dummy first and last Polygons that were created by the initialization.
            //And for instance I don't want to be forced to go to the center of the initial polygon before starting to move towards my destination.

            //skip the last node, but only if the solution is not partial (if the solution is partial, the last node does not correspond to the dummy goal polygon)
            if (!partial && currentNode.parent != null)
            {
                currentNode = currentNode.parent;
            }

            while (currentNode.parent != null)
            {
                path.PathNodes.Add(currentNode.node); //we need to reverse the list because this operator add elements to the end of the list
                path.PathPositions.Add(currentNode.node.LocalPosition);

                if (currentNode.parent.parent == null) break; //this skips the first node
                currentNode = currentNode.parent;
            }

            path.PathNodes.Reverse();
            path.PathPositions.Reverse();
            return path;
        }
Пример #12
0
 private static float F(NodeRecord node)
 {
     return(node.gValue + node.hValue);
 }
        //don't forget to add the override keyword here if you define a ProcessChildNode method in the base class
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {

            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 you algorithm wont work
                childNodeRecord = new NodeRecord
                {
                    node = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            var nodeInOpen = NodeRecordArray.SearchInOpen(childNode, childNodeRecord);

            float g = bestNode.gValue + connectionEdge.Cost;
            float h = this.Heuristic.H(childNode, this.GoalNode);
            float f = g + h;

            if (childNodeRecord.status == NodeStatus.Unvisited || childNodeRecord.fValue > f)
            {
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                childNodeRecord.parent = bestNode;

                if (childNodeRecord.status == NodeStatus.Unvisited)
                {
                    this.NodeRecordArray.AddToOpen(childNode, childNodeRecord);
                    partialMaxOpenNodes++;
                }
                else if (childNodeRecord.status == NodeStatus.Open)
                {
                    this.NodeRecordArray.Replace(nodeInOpen, childNodeRecord);
                }
                else if (childNodeRecord.status == NodeStatus.Closed)
                {
                    this.NodeRecordArray.RemoveFromClosed(childNode, childNodeRecord);
                    this.NodeRecordArray.AddToOpen(childNode, childNodeRecord);
                }

            }

        }
 private void UpdateNodeRecord(NodeRecord childNodeRecord, NodeRecord parent, float g, float h)
 {
     childNodeRecord.parent = parent;
     childNodeRecord.gValue = g;
     childNodeRecord.hValue = h;
     childNodeRecord.fValue = F(childNodeRecord);
 }
Пример #15
0
        protected virtual void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            var childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge);
            var oldChildNodeOpen = Open.SearchInOpen(childNodeRecord);
            var oldChildNodeClosed = Closed.SearchInClosed(childNodeRecord);

            if ((oldChildNodeClosed == null) && (oldChildNodeOpen == null))
            {
                Open.AddToOpen(childNodeRecord);
            }
            else if ((oldChildNodeOpen != null) && oldChildNodeOpen.fValue > childNodeRecord.fValue)
            {
                Open.Replace(oldChildNodeOpen, childNodeRecord);

            }
            else if ((oldChildNodeClosed != null) && oldChildNodeClosed.fValue > childNodeRecord.fValue)
            {
                Closed.RemoveFromClosed(oldChildNodeClosed);
                Open.AddToOpen(childNodeRecord);
            }
        }
Пример #16
0
 protected virtual void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex)
 {
     //this is where you process a child node
     var childNode = GenerateChildNodeRecord(parentNode, connectionEdge);
     //TODO: implement the rest of the code here
 }
        //devolve true se acabou (porque encontrou sol ou nao ha nenhuma) ou false se ainda nao acabou
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            //TODO: implement this
            //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut  list
            //something like this
            //var outConnections = bestNode.node.OutEdgeCount;
            //for (int i = 0; i < outConnections; i++)
            //{
            //this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
            var startTime      = Time.realtimeSinceStartup;
            var processedNodes = 0;

            while (processedNodes < this.NodesPerFrame)
            {
                //se houver nos no conj open
                if (this.Open.CountOpen() > 0)
                {
                    NodeRecord bestNode = this.Open.GetBestAndRemove();
                    if (bestNode.node == this.GoalNode)
                    {
                        //encontrou a sol
                        this.InProgress          = false;
                        solution                 = this.CalculateSolution(bestNode, returnPartialSolution);
                        this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
                        return(true);
                    }
                    //se nao passa ao proximo no
                    this.Closed.AddToClosed(bestNode);
                    this.TotalExploredNodes++;
                    processedNodes++;

                    //para ver as ligacoes do no que acabamos de ver
                    var outConnections = bestNode.node.OutEdgeCount;
                    for (int i = 0; i < outConnections; i++)
                    {
                        this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
                    }
                    this.MaxOpenNodes = Mathf.Max(this.Open.CountOpen(), this.MaxOpenNodes);
                }
                else
                {
                    //se nao ha solucao retorna null e true
                    this.InProgress          = false;
                    solution                 = null;
                    this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
                    return(true);
                }
            }

            //se ja corremos o metodo ate ao numero de nos estabelecido e ainda nao encontrou o no
            if (returnPartialSolution)
            {
                //vai devolver o melhor ate agora
                solution = this.CalculateSolution(this.Open.PeekBest(), returnPartialSolution);
            }
            else
            {
                solution = null;
            }

            this.TotalProcessingTime = Time.realtimeSinceStartup - startTime;
            return(false);
        }
Пример #18
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            //TODO put the code from the previous LAB here
            //you will get compiler errors, because I change the method names in the IOpenSet and IClosedSet interfaces
            //sorry but I had to do it because if not, Unity profiler would consider the Search method in Open and Closed to be the same
            //and you would not be able to see the difference in performance searching the Open Set and in searching the closed set

            //so just replace this.Open.Search(...) by this.Open.SearchInOpen(...) and all other methods where you get the compilation errors

            var   CurrentSearchNodes = 0;
            var   NodesProcessed     = 0;
            var   MaxOpenSize        = 0;
            float StartTime          = Time.realtimeSinceStartup;

            while (true)
            {
                if (Open.CountOpen() > MaxOpenSize)
                {
                    MaxOpenSize = Open.CountOpen();
                }

                if (Open.CountOpen() == 0)
                {
                    solution            = null;
                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    this.InProgress     = false;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    return(true);
                }


                if (NodesPerSearch < CurrentSearchNodes)
                {
                    if (returnPartialSolution)
                    {
                        solution = CalculateSolution(this.Open.PeekBest(), returnPartialSolution);
                    }
                    else
                    {
                        solution = null;
                    }

                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    return(false);
                }

                NodeRecord CurrentNode = Open.GetBestAndRemove();

                if (CurrentNode.node == GoalNode)
                {
                    InProgress          = false;
                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    solution            = CalculateSolution(CurrentNode, false);
                    return(true);
                }

                Closed.AddToClosed(CurrentNode);
                CurrentSearchNodes++;
                NodesProcessed++;
                var NodeActions = CurrentNode.node.OutEdgeCount;

                for (int i = 0; i < NodeActions; i++)
                {
                    ProcessChildNode(CurrentNode, CurrentNode.node.EdgeOut(i));
                }
            }
        }
        private bool withinGoalBounds(NodeRecord currentNode, int edgeIndex)
        {
            var currentEdgeBounds = currentNode.edgeBounds[edgeIndex];

            if (  GoalNode.Position.x < currentEdgeBounds.maxX &&
                  GoalNode.Position.x > currentEdgeBounds.minX &&
                  GoalNode.Position.z < currentEdgeBounds.maxZ &&
                  GoalNode.Position.z > currentEdgeBounds.minZ)
            {
                
                return true;
            }

            return false;
        }
Пример #20
0
 private static float F(NodeRecord node)
 {
     return node.gValue + node.hValue;
 }
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            float f;
            float g;
            float h;
            float s = 0.0f;

            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
                childNodeRecord = new NodeRecord
                {
                    node = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            // implement the rest of your code here

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

            g = bestNode.gValue + connectionEdge.Cost;
            h = this.Heuristic.H(childNode, this.GoalNode);
            if (this.Character.SecurityInfluence.ContainsKey(childNode.Position))
            {
                s = this.Character.SecurityInfluence[childNode.Position];

               // s *= 100.0f;
            }
            f = F(g,h,s);

            if (childNodeRecord.status == NodeStatus.Open)
            {
                if (f <= childNodeRecord.fValue)
                {
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    childNodeRecord.parent = bestNode;
                    this.NodeRecordArray.Replace(childNodeRecord,childNodeRecord);
                }
            }
            else
            {
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                childNodeRecord.status = NodeStatus.Open;
                childNodeRecord.parent = bestNode;
                this.NodeRecordArray.AddToOpen(childNodeRecord);
            }
        }
Пример #22
0
        private NodeRecord GenerateChildNodeRecord(NodeRecord parent, NavigationGraphEdge connectionEdge)
        {
            var childNode = connectionEdge.ToNode;
            var childNodeRecord = new NodeRecord
            {
                node = childNode,
                parent = parent,
                gValue = parent.gValue + connectionEdge.Cost,
                hValue = this.Heuristic.H(childNode, this.GoalNode)
            };

            childNodeRecord.fValue = F(childNodeRecord);

            return childNodeRecord;
        }
Пример #23
0
 public static float F(NodeRecord node)
 {
     return F(node.gValue,node.hValue);
 }
Пример #24
0
 public static float F(NodeRecord node)
 {
     return(F(node.gValue, node.hValue));
 }
Пример #25
0
        protected virtual NodeRecord GenerateChildNodeRecord(NodeRecord parent, NavigationGraphEdge connectionEdge)
        {
            var childNode = connectionEdge.ToNode;
            var childNodeRecord = new NodeRecord
            {
                node = childNode,
                parent = parent,
                gValue = parent.gValue + (childNode.LocalPosition-parent.node.LocalPosition).magnitude,
                hValue = this.Heuristic.H(childNode, this.GoalNode)
            };

            childNodeRecord.fValue = F(childNodeRecord);

            return childNodeRecord;
        }
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            float f;
            float g;
            float h;

            var childNode = connectionEdge.ToNode;
            var fromNode  = connectionEdge.FromNode;

            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
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            // implement the rest of your code here

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

            g = bestNode.gValue + connectionEdge.Cost;
            h = this.Heuristic.H(childNode, this.GoalNode);

            LocationRecord dummyRecord = new LocationRecord()
            {
                Location = childNode
            };

            float redInfluence = 0f, greenInfluence = 0f;

            // gets the influences for the child node
            LocationRecord redRecord = AutonomousCharacter.RedInfluenceMap.Closed.SearchInClosed(dummyRecord);

            if (redRecord != null)
            {
                redInfluence = redRecord.Influence;
            }

            LocationRecord greenRecord = AutonomousCharacter.GreenInfluenceMap.Closed.SearchInClosed(dummyRecord);

            if (greenRecord != null)
            {
                greenInfluence = greenRecord.Influence;
            }

            dummyRecord = new LocationRecord()
            {
                Location = fromNode
            };

            // gets the influences for the origin node
            redRecord = AutonomousCharacter.RedInfluenceMap.Closed.SearchInClosed(dummyRecord);
            if (redRecord != null)
            {
                redInfluence += redRecord.Influence;
            }

            greenRecord = AutonomousCharacter.GreenInfluenceMap.Closed.SearchInClosed(dummyRecord);
            if (greenRecord != null)
            {
                greenInfluence += greenRecord.Influence;
            }

            // calculates the average value of the path
            greenInfluence /= 2;
            redInfluence   /= 2;

            // add the impact of the map's influence
            h += (greenInfluence - redInfluence) * AvoidanceMargin;

            f = F(g, h);

            if (childNodeRecord.status == NodeStatus.Open)
            {
                if (f <= childNodeRecord.fValue)
                {
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    childNodeRecord.parent = bestNode;
                    this.NodeRecordArray.Replace(childNodeRecord, childNodeRecord);
                }
            }
            else
            {
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                childNodeRecord.status = NodeStatus.Open;
                childNodeRecord.parent = bestNode;
                this.NodeRecordArray.AddToOpen(childNodeRecord);
            }
        }