public LocationRecord SearchInOpen(LocationRecord nodeRecord) { //here I cannot use the == comparer because the nodeRecord will likely be a different computational object //and therefore pointer comparison will not work, we need to use Equals //LINQ with a lambda expression return(this.NodeRecords.FirstOrDefault(n => n.Equals(nodeRecord))); }
public LocationRecord SearchInOpen(LocationRecord nodeRecord) { //here I cannot use the == comparer because the nodeRecord will likely be a different computational object //and therefore pointer comparison will not work, we need to use Equals //LINQ with a lambda expression return this.NodeRecords.FirstOrDefault(n => n.Equals(nodeRecord)); }
public void Replace(LocationRecord nodeToBeReplaced, LocationRecord nodeToReplace) { //since the list is not ordered we do not need to remove the node and add the new one, just copy the different values //remember that if NodeRecord is a struct, for this to work we need to receive a reference nodeToBeReplaced.Parent = nodeToReplace.Parent; nodeToBeReplaced.Influence = nodeToReplace.Influence; nodeToBeReplaced.StrongestInfluenceUnit = nodeToReplace.StrongestInfluenceUnit; }
public LocationRecord SearchInClosed(LocationRecord nodeRecord) { if (this.Closed.ContainsKey(nodeRecord.Location)) { return this.Closed[nodeRecord.Location]; } else return null; }
public void Replace(LocationRecord nodeToBeReplaced, LocationRecord nodeToReplace) { //since the list is not ordered we do not need to remove the node and add the new one, just copy the different values //remember that if NodeRecord is a struct, for this to work we need to receive a reference nodeToBeReplaced.Parent = nodeToReplace.Parent; nodeToBeReplaced.Influence = nodeToReplace.Influence; nodeToBeReplaced.StrongestInfluenceUnit = nodeToReplace.StrongestInfluenceUnit; }
public LocationRecord SearchInClosed(LocationRecord nodeRecord) { LocationRecord record; if (Closed.TryGetValue(nodeRecord.Location, out record)) { return(record); } return(null); }
public LocationRecord SearchInClosed(LocationRecord nodeRecord) { if (this.Closed.ContainsKey(nodeRecord.Location)) { return(this.Closed[nodeRecord.Location]); } else { return(null); } }
public override bool CanExecute() { if(this.Target == null) return false; NavigationGraphNode targetNode = this.Character.navMesh.QuantizeToNode(this.Target.transform.position, 10.0f); LocationRecord rec = new LocationRecord(){ Location = targetNode }; float security = 0.0f; if (this.Character.SecurityMap.ContainsKey(rec)) { security = this.Character.SecurityMap[rec]; } if (security >= 0.0f) return true; return false; }
public void AddToOpen(LocationRecord nodeRecord) { this.OpenHeap.Enqueue(nodeRecord); }
public LocationRecord SearchInOpen(LocationRecord nodeRecord) { return(this.OpenHeap.SearchForEqual(nodeRecord)); }
public void RemoveFromOpen(LocationRecord nodeRecord) { this.NodeRecords.Remove(nodeRecord); }
public void AddToOpen(LocationRecord nodeRecord) { this.NodeRecords.Add(nodeRecord); }
public void Initialize(List<IInfluenceUnit> units) { this.Open.Initialize(); this.Closed.Initialize(); this.Units = units; foreach (var unit in units) { //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)unit.Location).AddConnectedPoly(unit.Location.Position); var locationRecord = new LocationRecord { Influence = unit.DirectInfluence, StrongestInfluenceUnit = unit, Location = unit.Location }; Open.AddToOpen(locationRecord); } this.InProgress = true; }
public void AddToClosed(LocationRecord nodeRecord) { this.Closed.Add(nodeRecord.Location,nodeRecord); }
public void RemoveFromClosed(LocationRecord nodeRecord) { this.Closed.Remove(nodeRecord.Location); }
//this method should return true if it finished processing, and false if it still needs to continue public bool MapFloodDijkstra() { var processedNodes = 0; while (processedNodes < this.NodesPerFlood) { while (this.Open.CountOpen() > 0) { var currentRecord = this.Open.GetBestAndRemove(); this.Closed.AddToClosed(currentRecord); processedNodes++; var outConnections = currentRecord.Location.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var childNode = new LocationRecord { Location = currentRecord.Location.EdgeOut(i).ToNode }; var influence = InfluenceFunction.DetermineInfluence(currentRecord.StrongestInfluenceUnit, childNode.Location.Position); if (influence < InfluenceThreshold) continue; var neighborRecord = this.Closed.SearchInClosed(childNode); if (neighborRecord != null) { if (neighborRecord.Influence >= influence) continue; else this.Closed.RemoveFromClosed(neighborRecord); } else { neighborRecord = this.Open.SearchInOpen(childNode); if (neighborRecord != null) { if (neighborRecord.Influence < influence) { neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; } continue; } else { neighborRecord = new LocationRecord(); neighborRecord = childNode; } } neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; this.Open.AddToOpen(neighborRecord); } } this.InProgress = false; return true; } return false; }
public void AddToOpen(LocationRecord nodeRecord) { this.NodeRecords.Add(nodeRecord); }
//this method should return true if it finished processing, and false if it still needs to continue public bool MapFloodDijkstra() { var processedNodes = 0; while (processedNodes < 50) { if (Open.CountOpen() <= 0) { this.InProgress = false; this.CleanUp(); return true; } processedNodes++; var currentRecord = Open.GetBestAndRemove(); Closed.AddToClosed(currentRecord); //needs a function to get adjacent nodes // NavMeshNode int outConnections = currentRecord.Location.OutEdgeCount; for (int i = 0; i < outConnections; i++) { NavigationGraphNode location = currentRecord.Location.EdgeOut(i).ToNode; DummyRecord.Location = location; var influence = InfluenceFunction.DetermineInfluence(currentRecord.StrongestInfluenceUnit, location.Position); if (influence < InfluenceThreshold) continue; var neighborRecord = Closed.SearchInClosed(DummyRecord); if (neighborRecord != null) { if (neighborRecord.Influence >= influence) continue; else Closed.RemoveFromClosed(neighborRecord); } else { neighborRecord = Open.SearchInOpen(DummyRecord); if (neighborRecord != null) { if (neighborRecord.Influence < influence) { neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; } continue; } else { neighborRecord = new LocationRecord(); neighborRecord.Location = location; } } neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; Open.AddToOpen(neighborRecord); } } return false; }
//this method should return true if it finished processing, and false if it still needs to continue public bool MapFloodDijkstra() { var processedNodes = 0; foreach (var unit in Units) { var locationRecord = new LocationRecord(); locationRecord.Location = unit.Location; locationRecord.StrongestInfluenceUnit = unit; locationRecord.Influence = unit.DirectInfluence; this.Open.AddToOpen(locationRecord); } while (this.Open.CountOpen() > 0) { var currentRecord = this.Open.GetBestAndRemove(); this.Closed.AddToClosed(currentRecord); foreach (var location in NavMeshGraph.Vertices) { var influence = InfluenceFunction.DetermineInfluence(currentRecord.StrongestInfluenceUnit, currentRecord.Location.LocalPosition); if (influence < InfluenceThreshold) continue; var neighborRecord = this.Closed.SearchInClosed(location); if (neighborRecord != null) { if (neighborRecord.Influence >= influence) continue; else this.Closed.RemoveFromClosed(neighborRecord); } else { neighborRecord = this.Open.SearchInOpen(location); if (neighborRecord != null) { if (neighborRecord.Influence < influence) { neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; } continue; } else { neighborRecord = new LocationRecord(); neighborRecord.Location = location; } } neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; this.Open.AddToOpen(neighborRecord); } } this.InProgress = false; this.CleanUp(); return true; }
public int CompareTo(LocationRecord other) { return(other.Influence.CompareTo(this.Influence)); }
protected virtual LocationRecord GenerateChildNodeRecord(LocationRecord parent, NavigationGraphEdge connectionEdge) { var childNodeRecord = new LocationRecord { Location = connectionEdge.ToNode }; return childNodeRecord; }
public void Replace(LocationRecord nodeToBeReplaced, LocationRecord nodeToReplace) { this.OpenHeap.Remove(nodeToBeReplaced); this.OpenHeap.Enqueue(nodeToReplace); }
public void AddToClosed(LocationRecord nodeRecord) { this.Closed.Add(nodeRecord.Location, nodeRecord); }
protected void ProcessChildNode(LocationRecord bestRecord, LocationRecord child) { float influence = this.InfluenceFunction.DetermineInfluence(bestRecord.StrongestInfluenceUnit, child.Location.Position); if (influence < this.InfluenceThreshold) return; LocationRecord neighborRecord = this.Closed.SearchInClosed(child); if (neighborRecord != null) { if (neighborRecord.Influence >= influence) return; else this.Closed.RemoveFromClosed(neighborRecord); } else { neighborRecord = this.Open.SearchInOpen(child); if (neighborRecord != null) { if (neighborRecord.Influence < influence) { neighborRecord.StrongestInfluenceUnit = bestRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; } return; } else { neighborRecord = child; } } neighborRecord.StrongestInfluenceUnit = bestRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; this.Open.AddToOpen(neighborRecord); }
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); } }
public void RemoveFromClosed(LocationRecord nodeRecord) { this.Closed.Remove(nodeRecord.Location); }
public void RemoveFromOpen(LocationRecord nodeRecord) { this.NodeRecords.Remove(nodeRecord); }
public int CompareTo(LocationRecord other) { return other.Influence.CompareTo(this.Influence); }
//this method should return true if it finished processing, and false if it still needs to continue public bool MapFloodDijkstra() { var processedNodes = 0; while (this.Open.CountOpen() > 0) { if (processedNodes < this.NodesPerFlood) { this.InProgress = true; return false; } LocationRecord currentRecord = this.Open.GetBestAndRemove(); this.Closed.AddToClosed(currentRecord); processedNodes++; var outConnections = currentRecord.Location.OutEdgeCount; for (int i = 0; i < outConnections; i++) { LocationRecord child = new LocationRecord(); child.Location = currentRecord.Location.EdgeOut(i).ToNode; this.ProcessChildNode(currentRecord, child); } } this.InProgress = false; // this.CleanUp(); return true; }
//this method should return true if it finished processing, and false if it still needs to continue public bool MapFloodDijkstra() { this.Open.Initialize(); this.Closed.Initialize(); var processedNodes = 0; foreach(var unit in Units){ //initialize the open list var locationRecord = new LocationRecord(); locationRecord.Location = unit.Location; locationRecord.StrongestInfluenceUnit = unit; locationRecord.Influence = unit.DirectInfluence; Open.AddToOpen(locationRecord); } while(Open.CountOpen() > 0){ var currentRecord = Open.GetBestAndRemove(); if (processedNodes > 30) { this.InProgress = false; return true; } Closed.AddToClosed(currentRecord); processedNodes++; List<NavigationGraphNode> adjacentNodes = new List<NavigationGraphNode>(); for(int i=0; i<currentRecord.Location.OutEdgeCount;i++){ NavigationGraphNode node = currentRecord.Location.EdgeOut(i).ToNode; adjacentNodes.Add(node); } foreach (NavigationGraphNode adjacentNode in adjacentNodes) { LocationRecord adjacent = new LocationRecord(); adjacent.Location = adjacentNode; var influence = InfluenceFunction.DetermineInfluence(currentRecord.StrongestInfluenceUnit, adjacentNode.Position); if(influence < InfluenceThreshold) continue; var neighborRecord = Closed.SearchInClosed(adjacent); if(neighborRecord != null){ if(neighborRecord.Influence >= influence){ continue; } else{ Closed.RemoveFromClosed(neighborRecord); processedNodes--; } } else{ neighborRecord = Open.SearchInOpen(adjacent); if(neighborRecord != null){ if(neighborRecord.Influence < influence){ neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; } continue; } else{ //we found a new record not in open or closed neighborRecord = new LocationRecord(); neighborRecord.Location = adjacent.Location; } } neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; Open.AddToOpen(neighborRecord); } processedNodes = 0; } this.InProgress = false; //this.CleanUp(); return true; }