public PathThreadInfo(int index, AstarPath astar, NodeRunData runData) { this.threadIndex = index; this.astar = astar; this.runData = runData; _lock = new object(); }
//public override int GetHashCode () { return GetNodeIndex (); } public NodeRun GetNodeRun (NodeRunData data) { #if ASTAR_SINGLE_THREAD_OPTIMIZE return (NodeRun)this; #else return data.nodes[nodeIndex]; #endif }
public NodeRun GetNodeRun (NodeRunData data) { #if SingleCoreOptimize return (NodeRun)this; #else return data.nodes[nodeIndex]; #endif }
public void UpdateG(NodeRun nodeR, NodeRunData nodeRunData) { nodeR.g = nodeR.parent.g + nodeR.cost + penalty #if !ASTAR_NoTagPenalty + nodeRunData.path.GetTagPenalty(tags) #endif ; }
//public override int GetHashCode () { return GetNodeIndex (); } public NodeRun GetNodeRun(NodeRunData data) { #if ASTAR_SINGLE_THREAD_OPTIMIZE return((NodeRun)this); #else return(data.nodes[nodeIndex]); #endif }
public NodeRun GetNodeRun(NodeRunData data) { #if SingleCoreOptimize return((NodeRun)this); #else return(data.nodes[nodeIndex]); #endif }
/** Reset all values to their default values. * * \note All inheriting path types (e.g ConstantPath, RandomPath, etc.) which declare their own variables need to * override this function, resetting ALL their variables to enable recycling of paths. * If this is not done, trying to use that path type for pooling might result in weird behaviour. * The best way is to reset to default values the variables declared in the extended path type and then * call this base function in inheriting types with base.Reset (). * * \warning This function should not be called manually. */ public virtual void Reset() { #if ASTAR_POOL_DEBUG pathTraceInfo = "This path was got from the pool or created from here (stacktrace):\n"; pathTraceInfo += System.Environment.StackTrace; #endif if (AstarPath.active == null) { throw new System.NullReferenceException("No AstarPath object found in the scene. " + "Make sure there is one or do not create paths in Awake"); } hasBeenReset = true; state = (int)PathState.Created; releasedNotSilent = false; runData = null; callback = null; _errorLog = ""; pathCompleteState = PathCompleteState.NotCalculated; path = Pathfinding.Util.ListPool <Node> .Claim(); vectorPath = Pathfinding.Util.ListPool <Vector3> .Claim(); currentR = null; duration = 0; searchIterations = 0; searchedNodes = 0; //calltime nnConstraint = PathNNConstraint.Default; next = null; radius = 0; walkabilityMask = -1; height = 0; turnRadius = 0; speed = 0; //heuristic = (Heuristic)0; //heuristicScale = 1F; heuristic = AstarPath.active.heuristic; heuristicScale = AstarPath.active.heuristicScale; pathID = 0; enabledTags = -1; tagPenalties = null; callTime = System.DateTime.UtcNow; pathID = AstarPath.active.GetNextPathID(); }
/** Prepares low level path variables for calculation. * Called before a path search will take place. * Always called before the Prepare, Initialize and CalculateStep functions */ public void PrepareBase(NodeRunData runData) { //Path IDs have overflowed 65K, cleanup is needed //Since pathIDs are handed out sequentially, we can do this if (runData.pathID > pathID) { runData.ClearPathIDs(); } //Make sure the path has a reference to the runData this.runData = runData; //Assign relevant path data to the runData runData.Initialize(this); try { ErrorCheck(); } catch (System.Exception e) { ForceLogError("Exception in path " + pathID + "\n" + e.ToString()); } }
protected void BaseUpdateAllG(NodeRun nodeR, NodeRunData nodeRunData) { UpdateG(nodeR, nodeRunData); nodeRunData.open.Add(nodeR); if (connections == null) { return; } //Loop through the connections of this node and call UpdateALlG on nodes which have this node set as #parent and has been searched by the pathfinder for this path */ for (int i = 0; i < connections.Length; i++) { NodeRun otherR = connections[i].GetNodeRun(nodeRunData); if (otherR.parent == nodeR && otherR.pathID == nodeRunData.pathID) { connections[i].UpdateAllG(otherR, nodeRunData); } } }
public NodeRun GetNodeRun(NodeRunData data) { return (NodeRun)this; }
public void UpdateG (NodeRun nodeR, NodeRunData nodeRunData) { nodeR.g = nodeR.parent.g+nodeR.cost+penalty #if !ASTAR_NoTagPenalty + nodeRunData.path.GetTagPenalty(tags) #endif ; }
public override void UpdateAllG (NodeRun nodeR, NodeRunData nodeRunData) { BaseUpdateAllG (nodeR, nodeRunData); int index = GetIndex (); int[] neighbourOffsets = gridGraphs[indices >> 24].neighbourOffsets; Node[] nodes = gridGraphs[indices >> 24].nodes; for (int i=0;i<8;i++) { if (GetConnection (i)) { //if (((flags >> i) & 1) == 1) { Node node = nodes[index+neighbourOffsets[i]]; NodeRun nodeR2 = node.GetNodeRun (nodeRunData); if (nodeR2.parent == nodeR && nodeR2.pathID == nodeRunData.pathID) { node.UpdateAllG (nodeR2,nodeRunData); } } } }
public override void Open (NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { BaseOpen (nodeRunData, nodeR, targetPosition, path); GridGraph graph = gridGraphs[indices >> 24]; int[] neighbourOffsets = graph.neighbourOffsets; int[] neighbourCosts = graph.neighbourCosts; Node[] nodes = graph.nodes; int index = GetIndex ();//indices & 0xFFFFFF; for (int i=0;i<8;i++) { if (GetConnection (i)) { //if (((flags >> i) & 1) == 1) { Node node = nodes[index+neighbourOffsets[i]]; if (!path.CanTraverse (node)) continue; NodeRun nodeR2 = node.GetNodeRun (nodeRunData); if (nodeR2.pathID != nodeRunData.pathID) { nodeR2.parent = nodeR; nodeR2.pathID = nodeRunData.pathID; nodeR2.cost = (uint)neighbourCosts[i]; node.UpdateH (targetPosition,path.heuristic,path.heuristicScale, nodeR2); node.UpdateG (nodeR2,nodeRunData); nodeRunData.open.Add (nodeR2); } else { //If not we can test if the path from the current node to this one is a better one then the one already used uint tmpCost = (uint)neighbourCosts[i];//(current.costs == null || current.costs.Length == 0 ? costs[current.neighboursKeys[i]] : current.costs[current.neighboursKeys[i]]); if (nodeR.g+tmpCost+node.penalty + path.GetTagPenalty(node.tags) < nodeR2.g) { nodeR2.cost = tmpCost; nodeR2.parent = nodeR; node.UpdateAllG (nodeR2,nodeRunData); } else if (nodeR2.g+tmpCost+penalty + path.GetTagPenalty(tags) < nodeR.g) {//Or if the path from this node ("node") to the current ("current") is better /*bool contains = false; //[Edit, no one-way links between nodes in a single grid] Make sure we don't travel along the wrong direction of a one way link now, make sure the Current node can be accesed from the Node. /*for (int y=0;y<node.connections.Length;y++) { if (node.connections[y].endNode == this) { contains = true; break; } } if (!contains) { continue; }*/ nodeR.parent = nodeR2; nodeR.cost = tmpCost; UpdateAllG (nodeR,nodeRunData); } } } } }
/** Prepares low level path variables for calculation. * Called before a path search will take place. * Always called before the Prepare, Initialize and CalculateStep functions */ public void PrepareBase(NodeRunData runData) { //Path IDs have overflowed 65K, cleanup is needed //Since pathIDs are handed out sequentially, we can do this if (runData.pathID > pathID) { runData.ClearPathIDs (); } //Make sure the path has a reference to the runData this.runData = runData; //Assign relevant path data to the runData runData.Initialize (this); try { ErrorCheck (); } catch (System.Exception e) { ForceLogError ("Exception in path "+pathID+"\n"+e.ToString()); } }
/** Reset all values to their default values. * * \note All inheriting path types (e.g ConstantPath, RandomPath, etc.) which declare their own variables need to * override this function, resetting ALL their variables to enable recycling of paths. * If this is not done, trying to use that path type for pooling might result in weird behaviour. * The best way is to reset to default values the variables declared in the extended path type and then * call this base function in inheriting types with base.Reset (). * * \warning This function should not be called manually. */ public virtual void Reset() { if (AstarPath.active == null) throw new System.NullReferenceException ("No AstarPath object found in the scene. " + "Make sure there is one or do not create paths in Awake"); hasBeenReset = true; state = (int)PathState.Created; releasedNotSilent = false; runData = null; callback = null; _errorLog = ""; pathCompleteState = PathCompleteState.NotCalculated; path = Pathfinding.Util.ListPool<Node>.Claim(); vectorPath = Pathfinding.Util.ListPool<Vector3>.Claim(); currentR = null; duration = 0; searchIterations = 0; searchedNodes = 0; //calltime nnConstraint = PathNNConstraint.Default; next = null; radius = 0; walkabilityMask = -1; height = 0; turnRadius = 0; speed = 0; //heuristic = (Heuristic)0; //heuristicScale = 1F; heuristic = AstarPath.active.heuristic; heuristicScale = AstarPath.active.heuristicScale; pathID = 0; enabledTags = -1; tagPenalties = null; callTime = System.DateTime.UtcNow; pathID = AstarPath.active.GetNextPathID (); }
public new override void UpdateAllG(NodeRun nodeR, NodeRunData nodeRunData) { BaseUpdateAllG (nodeR, nodeRunData); //Called in the base function //open.Add (this); int index = GetIndex ();//indices & 0xFFFFFF; LayerGridGraph graph = gridGraphs[indices >> 24]; int[] neighbourOffsets = graph.neighbourOffsets; Node[] nodes = graph.nodes; //int[] nodeCellIndices = gridGraphs[indices >> 24].nodeCellIndices; for (int i=0;i<4;i++) { int conn = GetConnectionValue(i);//(gridConnections >> i*4) & 0xF; if (conn != LevelGridNode.NoConnection) { Node node = nodes[index+neighbourOffsets[i] + graph.width*graph.depth*conn]; //nodes[nodeCellIndices[index+neighbourOffsets[i]]+conn]; //nodes[index+neighbourOffsets[i]+conn]; NodeRun nodeR2 = node.GetNodeRun(nodeRunData); if (nodeR2.parent == nodeR && nodeR2.pathID == nodeRunData.pathID) { node.UpdateAllG (nodeR2,nodeRunData); } } } }
//public override int GetHashCode () { return GetNodeIndex (); } public NodeRun GetNodeRun(NodeRunData data) { return((NodeRun)this); }
/// <summary> /// Returns a color to be used for the specified node with the current debug settings (editor only) /// </summary> /// <param name="node"> /// A <see cref="Node"/> /// </param> /// <returns> /// A <see cref="Color"/> /// </returns> public virtual Color NodeColor(Node node, NodeRunData data) { #if !PhotonImplementation Color c = AstarColor.NodeConnection; bool colSet = false; if (node == null) { return(AstarColor.NodeConnection); } switch (AstarPath.active.debugMode) { case GraphDebugMode.Areas: c = AstarColor.GetAreaColor(node.area); colSet = true; break; case GraphDebugMode.Penalty: c = Color.Lerp(AstarColor.ConnectionLowLerp, AstarColor.ConnectionHighLerp, (float)node.penalty / (float)AstarPath.active.debugRoof); colSet = true; break; case GraphDebugMode.Tags: c = Mathfx.IntToColor(node.tags, 0.5F); colSet = true; break; /* Wasn't really usefull * case GraphDebugMode.Position: * float r = Mathf.PingPong (node.position.x/10000F,1F) + Mathf.PingPong (node.position.x/300000F,1F); * float g = Mathf.PingPong (node.position.y/10000F,1F) + Mathf.PingPong (node.position.y/200000F,1F); * float b = Mathf.PingPong (node.position.z/10000F,1F) + Mathf.PingPong (node.position.z/100000F,1F); * * * c = new Color (r,g,b); * break; */ } if (!colSet) { if (data == null) { return(AstarColor.NodeConnection); } NodeRun nodeR = node.GetNodeRun(data); if (nodeR == null) { return(AstarColor.NodeConnection); } switch (AstarPath.active.debugMode) { case GraphDebugMode.G: //c = Mathfx.IntToColor (node.g,0.5F); c = Color.Lerp(AstarColor.ConnectionLowLerp, AstarColor.ConnectionHighLerp, (float)nodeR.g / (float)AstarPath.active.debugRoof); break; case GraphDebugMode.H: c = Color.Lerp(AstarColor.ConnectionLowLerp, AstarColor.ConnectionHighLerp, (float)nodeR.h / (float)AstarPath.active.debugRoof); break; case GraphDebugMode.F: c = Color.Lerp(AstarColor.ConnectionLowLerp, AstarColor.ConnectionHighLerp, (float)nodeR.f / (float)AstarPath.active.debugRoof); break; } } c.a *= 0.5F; return(c); #else return(new Color(1, 1, 1)); #endif }
public virtual void Open (NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { BaseOpen (nodeRunData,nodeR, targetPosition,path); }
protected void BaseUpdateAllG (NodeRun nodeR, NodeRunData nodeRunData) { UpdateG (nodeR, nodeRunData); nodeRunData.open.Add (nodeR); if (connections == null) { return; } //Loop through the connections of this node and call UpdateALlG on nodes which have this node set as #parent and has been searched by the pathfinder for this path */ for (int i=0;i<connections.Length;i++) { NodeRun otherR = connections[i].GetNodeRun (nodeRunData); if (otherR.parent == nodeR && otherR.pathID == nodeRunData.pathID) { connections[i].UpdateAllG (otherR, nodeRunData); } } }
public void UpdateG(NodeRun nodeR, NodeRunData nodeRunData) { nodeR.g = nodeR.parent.g + nodeR.cost + penalty + nodeRunData.path.GetTagPenalty(tags); }
public void UpdateG (NodeRun nodeR, NodeRunData nodeRunData) { nodeR.g = nodeR.parent.g+nodeR.cost+penalty + nodeRunData.path.GetTagPenalty(tags); }
public virtual void UpdateAllG (NodeRun nodeR, NodeRunData nodeRunData) { BaseUpdateAllG (nodeR, nodeRunData); }
public virtual void UpdateAllG(NodeRun nodeR, NodeRunData nodeRunData) { BaseUpdateAllG(nodeR, nodeRunData); }
/** Opens the nodes connected to this node. This is a base call and can be called by node classes overriding the Open function to open all connections in the #connections array. * \see #connections * \see Open */ public void BaseOpen (NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { if (connections == null) return; for (int i=0;i<connections.Length;i++) { Node conNode = connections[i]; if (!path.CanTraverse (conNode)) { continue; } NodeRun nodeR2 = conNode.GetNodeRun (nodeRunData); if (nodeR2.pathID != nodeRunData.pathID) { nodeR2.parent = nodeR; nodeR2.pathID = nodeRunData.pathID; nodeR2.cost = (uint)connectionCosts[i]; conNode.UpdateH (targetPosition, path.heuristic, path.heuristicScale, nodeR2); conNode.UpdateG (nodeR2, nodeRunData); nodeRunData.open.Add (nodeR2); //Debug.DrawLine (position,node.position,Color.cyan); //Debug.Log ("Opening Node "+node.position.ToString ()+" "+g+" "+node.cost+" "+node.g+" "+node.f); } else { //If not we can test if the path from the current node to this one is a better one then the one already used uint tmpCost = (uint)connectionCosts[i]; if (nodeR.g+tmpCost+conNode.penalty #if !ASTAR_NoTagPenalty + path.GetTagPenalty(conNode.tags) #endif < nodeR2.g) { nodeR2.cost = tmpCost; nodeR2.parent = nodeR; conNode.UpdateAllG (nodeR2,nodeRunData); nodeRunData.open.Add (nodeR2); } else if (nodeR2.g+tmpCost+penalty #if !ASTAR_NoTagPenalty + path.GetTagPenalty(tags) #endif < nodeR.g) {//Or if the path from this node ("node") to the current ("current") is better bool contains = conNode.ContainsConnection (this); //Make sure we don't travel along the wrong direction of a one way link now, make sure the Current node can be moved to from the other Node. /*if (node.connections != null) { for (int y=0;y<node.connections.Length;y++) { if (node.connections[y] == this) { contains = true; break; } } }*/ if (!contains) { continue; } nodeR.parent = nodeR2; nodeR.cost = tmpCost; UpdateAllG (nodeR,nodeRunData); nodeRunData.open.Add (nodeR); } } } }
public virtual void Open(NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { BaseOpen(nodeRunData, nodeR, targetPosition, path); }
public new override void Open(NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { BaseOpen (nodeRunData, nodeR, targetPosition, path); LayerGridGraph graph = gridGraphs[indices >> 24]; int[] neighbourOffsets = graph.neighbourOffsets; int[] neighbourCosts = graph.neighbourCosts; Node[] nodes = graph.nodes; int index = GetIndex();//indices & 0xFFFFFF; for (int i=0;i<4;i++) { int conn = GetConnectionValue(i);//(gridConnections >> i*4) & 0xF; if (conn != LevelGridNode.NoConnection) { Node node = nodes[index+neighbourOffsets[i] + graph.width*graph.depth*conn]; if (!path.CanTraverse (node)) { continue; } NodeRun nodeR2 = node.GetNodeRun (nodeRunData); if (nodeR2.pathID != nodeRunData.pathID) { nodeR2.parent = nodeR; nodeR2.pathID = nodeRunData.pathID; nodeR2.cost = (uint)neighbourCosts[i]; node.UpdateH (targetPosition, path.heuristic, path.heuristicScale, nodeR2); node.UpdateG (nodeR2, nodeRunData); nodeRunData.open.Add (nodeR2); } else { //If not we can test if the path from the current node to this one is a better one then the one already used uint tmpCost = (uint)neighbourCosts[i]; if (nodeR.g+tmpCost+node.penalty #if !NoTagPenalty + path.GetTagPenalty(node.tags) #endif < nodeR2.g) { nodeR2.cost = tmpCost; nodeR2.parent = nodeR; //TODO!!!!! ?? node.UpdateAllG (nodeR2,nodeRunData); nodeRunData.open.Add (nodeR2); } else if (nodeR2.g+tmpCost+penalty #if !NoTagPenalty + path.GetTagPenalty(tags) #endif < nodeR.g) {//Or if the path from this node ("node") to the current ("current") is better bool contains = node.ContainsConnection (this); //Make sure we don't travel along the wrong direction of a one way link now, make sure the Current node can be moved to from the other Node. /*if (node.connections != null) { for (int y=0;y<node.connections.Length;y++) { if (node.connections[y] == this) { contains = true; break; } } }*/ if (!contains) { continue; } nodeR.parent = nodeR2; nodeR.cost = tmpCost; //TODO!!!!!!! ?? UpdateAllG (nodeR,nodeRunData); nodeRunData.open.Add (nodeR); } } } } }
/// <summary> /// Returns a color to be used for the specified node with the current debug settings (editor only) /// </summary> /// <param name="node"> /// A <see cref="Node"/> /// </param> /// <returns> /// A <see cref="Color"/> /// </returns> public virtual Color NodeColor(Node node, NodeRunData data) { Color c = AstarColor.NodeConnection; bool colSet = false; if (node == null) return AstarColor.NodeConnection; switch (AstarPath.active.debugMode) { case GraphDebugMode.Areas: c = AstarColor.GetAreaColor (node.area); colSet = true; break; case GraphDebugMode.Penalty: c = Color.Lerp (AstarColor.ConnectionLowLerp,AstarColor.ConnectionHighLerp, (float)node.penalty / (float)AstarPath.active.debugRoof); colSet = true; break; case GraphDebugMode.Tags: c = Mathfx.IntToColor (node.tags,0.5F); colSet = true; break; /* Wasn't really usefull case GraphDebugMode.Position: float r = Mathf.PingPong (node.position.x/10000F,1F) + Mathf.PingPong (node.position.x/300000F,1F); float g = Mathf.PingPong (node.position.y/10000F,1F) + Mathf.PingPong (node.position.y/200000F,1F); float b = Mathf.PingPong (node.position.z/10000F,1F) + Mathf.PingPong (node.position.z/100000F,1F); c = new Color (r,g,b); break; */ } if (!colSet) { if (data == null) return AstarColor.NodeConnection; NodeRun nodeR = node.GetNodeRun (data); if (nodeR == null) return AstarColor.NodeConnection; switch (AstarPath.active.debugMode) { case GraphDebugMode.G: //c = Mathfx.IntToColor (node.g,0.5F); c = Color.Lerp (AstarColor.ConnectionLowLerp,AstarColor.ConnectionHighLerp, (float)nodeR.g / (float)AstarPath.active.debugRoof); break; case GraphDebugMode.H: c = Color.Lerp (AstarColor.ConnectionLowLerp,AstarColor.ConnectionHighLerp, (float)nodeR.h / (float)AstarPath.active.debugRoof); break; case GraphDebugMode.F: c = Color.Lerp (AstarColor.ConnectionLowLerp,AstarColor.ConnectionHighLerp, (float)nodeR.f / (float)AstarPath.active.debugRoof); break; } } c.a *= 0.5F; return c; }
/** Opens the nodes connected to this node. This is a base call and can be called by node classes overriding the Open function to open all connections in the #connections array. * \see #connections * \see Open */ public void BaseOpen(NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path) { if (connections == null) { return; } for (int i = 0; i < connections.Length; i++) { Node node = connections[i]; if (!path.CanTraverse(node)) { continue; } NodeRun nodeR2 = node.GetNodeRun(nodeRunData); if (nodeR2.pathID != nodeRunData.pathID) { nodeR2.parent = nodeR; nodeR2.pathID = nodeRunData.pathID; nodeR2.cost = (uint)connectionCosts[i]; node.UpdateH(targetPosition, path.heuristic, path.heuristicScale, nodeR2); node.UpdateG(nodeR2, nodeRunData); nodeRunData.open.Add(nodeR2); //Debug.DrawLine (position,node.position,Color.cyan); //Debug.Log ("Opening Node "+node.position.ToString ()+" "+g+" "+node.cost+" "+node.g+" "+node.f); } else { //If not we can test if the path from the current node to this one is a better one then the one already used uint tmpCost = (uint)connectionCosts[i]; if (nodeR.g + tmpCost + node.penalty #if !NoTagPenalty + path.GetTagPenalty(node.tags) #endif < nodeR2.g) { nodeR2.cost = tmpCost; nodeR2.parent = nodeR; //TODO!!!!! ?? node.UpdateAllG(nodeR2, nodeRunData); nodeRunData.open.Add(nodeR2); } else if (nodeR2.g + tmpCost + penalty #if !NoTagPenalty + path.GetTagPenalty(tags) #endif < nodeR.g) //Or if the path from this node ("node") to the current ("current") is better { bool contains = node.ContainsConnection(this); //Make sure we don't travel along the wrong direction of a one way link now, make sure the Current node can be moved to from the other Node. /*if (node.connections != null) { * for (int y=0;y<node.connections.Length;y++) { * if (node.connections[y] == this) { * contains = true; * break; * } * } * }*/ if (!contains) { continue; } nodeR.parent = nodeR2; nodeR.cost = tmpCost; //TODO!!!!!!! ?? UpdateAllG(nodeR, nodeRunData); nodeRunData.open.Add(nodeR); } } } }
public static FsmNodeRunData SetNodeRunData(NodeRunData gameObject) { return new FsmNodeRunData() { Value = gameObject }; }