public static List <PathPart> SplitIntoParts(Path path) { var nodes = path.path; var result = ListPool <PathPart> .Claim(); if (nodes == null || nodes.Count == 0) { return(result); } // Loop through the path and split it into // parts joined by links for (int i = 0; i < nodes.Count; i++) { if (nodes[i] is TriangleMeshNode || nodes[i] is GridNodeBase) { var part = new PathPart(); part.startIndex = i; uint currentGraphIndex = nodes[i].GraphIndex; // Loop up until we find a node in another graph // Ignore NodeLink3 nodes for (; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node)) { break; } } i--; part.endIndex = i; // If this is the first part in the path, use the exact start point // otherwise use the position of the node right before the start of this // part which is likely the end of the link to this part if (part.startIndex == 0) { part.startPoint = path.vectorPath[0]; } else { part.startPoint = (Vector3)nodes[part.startIndex - 1].position; } if (part.endIndex == nodes.Count - 1) { part.endPoint = path.vectorPath[path.vectorPath.Count - 1]; } else { part.endPoint = (Vector3)nodes[part.endIndex + 1].position; } result.Add(part); } else if (NodeLink2.GetNodeLink(nodes[i]) != null) { var part = new PathPart(); part.startIndex = i; var currentGraphIndex = nodes[i].GraphIndex; for (i++; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex) { break; } } i--; if (i - part.startIndex == 0) { // Just ignore it, it might be the case that a NodeLink was the closest node continue; } else if (i - part.startIndex != 1) { throw new System.Exception("NodeLink2 link length greater than two (2) nodes. " + (i - part.startIndex + 1)); } part.endIndex = i; part.isLink = true; part.startPoint = (Vector3)nodes[part.startIndex].position; part.endPoint = (Vector3)nodes[part.endIndex].position; result.Add(part); } else { throw new System.Exception("Unsupported node type or null node"); } } return(result); }
/** Use this for initialization. * * \param s Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\ * \param p Path to follow * \param mergePartEndpoints If true, then adjacent parts that the path is split up in will * try to use the same start/end points. For example when using a link on a navmesh graph * Instead of first following the path to the center of the node where the link is and then * follow the link, the path will be adjusted to go to the exact point where the link starts * which usually makes more sense. * \param simplificationMode The path can optionally be simplified. This can be a bit expensive for long paths. */ public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode) { if (p.error) { throw new System.ArgumentException("Path has an error"); } List <GraphNode> nodes = p.path; if (nodes.Count == 0) { throw new System.ArgumentException("Path traverses no nodes"); } seeker = s; // Release objects back to object pool // Yeah, I know, it's casting... but this won't be called much for (int i = 0; i < parts.Count; i++) { if (parts[i] is RichFunnel) { ObjectPool <RichFunnel> .Release(parts[i] as RichFunnel); } else if (parts[i] is RichSpecial) { ObjectPool <RichSpecial> .Release(parts[i] as RichSpecial); } } parts.Clear(); currentPart = 0; // Initialize new //Break path into parts for (int i = 0; i < nodes.Count; i++) { if (nodes[i] is TriangleMeshNode) { var graph = AstarData.GetGraph(nodes[i]); RichFunnel f = ObjectPool <RichFunnel> .Claim().Initialize(this, graph); f.funnelSimplificationMode = simplificationMode; int sIndex = i; uint currentGraphIndex = nodes[sIndex].GraphIndex; for (; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node)) { break; } } i--; if (sIndex == 0) { f.exactStart = p.vectorPath[0]; } else { f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex - 1 : sIndex].position; } if (i == nodes.Count - 1) { f.exactEnd = p.vectorPath[p.vectorPath.Count - 1]; } else { f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i + 1 : i].position; } f.BuildFunnelCorridor(nodes, sIndex, i); parts.Add(f); } else if (NodeLink2.GetNodeLink(nodes[i]) != null) { NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]); int sIndex = i; uint currentGraphIndex = nodes[sIndex].GraphIndex; for (i++; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex) { break; } } i--; if (i - sIndex > 1) { throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex)); } else if (i - sIndex == 0) { //Just continue, it might be the case that a NodeLink was the closest node continue; } RichSpecial rps = ObjectPool <RichSpecial> .Claim().Initialize(nl, nodes[sIndex]); parts.Add(rps); } } }
public static List <Funnel.PathPart> SplitIntoParts(Path path) { List <GraphNode> path2 = path.path; List <Funnel.PathPart> list = ListPool <Funnel.PathPart> .Claim(); if (path2 == null || path2.Count == 0) { return(list); } for (int i = 0; i < path2.Count; i++) { if (path2[i] is TriangleMeshNode || path2[i] is GridNodeBase) { Funnel.PathPart pathPart = default(Funnel.PathPart); pathPart.startIndex = i; uint graphIndex = path2[i].GraphIndex; while (i < path2.Count && (path2[i].GraphIndex == graphIndex || path2[i] is NodeLink3Node)) { i++; } i--; pathPart.endIndex = i; if (pathPart.startIndex == 0) { pathPart.startPoint = path.vectorPath[0]; } else { pathPart.startPoint = (Vector3)path2[pathPart.startIndex - 1].position; } if (pathPart.endIndex == path2.Count - 1) { pathPart.endPoint = path.vectorPath[path.vectorPath.Count - 1]; } else { pathPart.endPoint = (Vector3)path2[pathPart.endIndex + 1].position; } list.Add(pathPart); } else { if (!(NodeLink2.GetNodeLink(path2[i]) != null)) { throw new Exception("Unsupported node type or null node"); } Funnel.PathPart pathPart2 = default(Funnel.PathPart); pathPart2.startIndex = i; uint graphIndex2 = path2[i].GraphIndex; i++; while (i < path2.Count && path2[i].GraphIndex == graphIndex2) { i++; } i--; if (i - pathPart2.startIndex != 0) { if (i - pathPart2.startIndex != 1) { throw new Exception("NodeLink2 link length greater than two (2) nodes. " + (i - pathPart2.startIndex + 1)); } pathPart2.endIndex = i; pathPart2.isLink = true; pathPart2.startPoint = (Vector3)path2[pathPart2.startIndex].position; pathPart2.endPoint = (Vector3)path2[pathPart2.endIndex].position; list.Add(pathPart2); } } } return(list); }
// Token: 0x06002140 RID: 8512 RVA: 0x001890A0 File Offset: 0x001872A0 public void Initialize(Seeker seeker, Path path, bool mergePartEndpoints, bool simplificationMode) { if (path.error) { throw new ArgumentException("Path has an error"); } List <GraphNode> path2 = path.path; if (path2.Count == 0) { throw new ArgumentException("Path traverses no nodes"); } this.seeker = seeker; for (int i = 0; i < this.parts.Count; i++) { RichFunnel richFunnel = this.parts[i] as RichFunnel; RichSpecial richSpecial = this.parts[i] as RichSpecial; if (richFunnel != null) { ObjectPool <RichFunnel> .Release(ref richFunnel); } else if (richSpecial != null) { ObjectPool <RichSpecial> .Release(ref richSpecial); } } this.Clear(); this.Endpoint = path.vectorPath[path.vectorPath.Count - 1]; for (int j = 0; j < path2.Count; j++) { if (path2[j] is TriangleMeshNode) { NavmeshBase navmeshBase = AstarData.GetGraph(path2[j]) as NavmeshBase; if (navmeshBase == null) { throw new Exception("Found a TriangleMeshNode that was not in a NavmeshBase graph"); } RichFunnel richFunnel2 = ObjectPool <RichFunnel> .Claim().Initialize(this, navmeshBase); richFunnel2.funnelSimplification = simplificationMode; int num = j; uint graphIndex = path2[num].GraphIndex; while (j < path2.Count && (path2[j].GraphIndex == graphIndex || path2[j] is NodeLink3Node)) { j++; } j--; if (num == 0) { richFunnel2.exactStart = path.vectorPath[0]; } else { richFunnel2.exactStart = (Vector3)path2[mergePartEndpoints ? (num - 1) : num].position; } if (j == path2.Count - 1) { richFunnel2.exactEnd = path.vectorPath[path.vectorPath.Count - 1]; } else { richFunnel2.exactEnd = (Vector3)path2[mergePartEndpoints ? (j + 1) : j].position; } richFunnel2.BuildFunnelCorridor(path2, num, j); this.parts.Add(richFunnel2); } else if (NodeLink2.GetNodeLink(path2[j]) != null) { NodeLink2 nodeLink = NodeLink2.GetNodeLink(path2[j]); int num2 = j; uint graphIndex2 = path2[num2].GraphIndex; j++; while (j < path2.Count && path2[j].GraphIndex == graphIndex2) { j++; } j--; if (j - num2 > 1) { throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num2)); } if (j - num2 != 0) { RichSpecial item = ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path2[num2]); this.parts.Add(item); } } } }
// Token: 0x06000033 RID: 51 RVA: 0x0000417C File Offset: 0x0000257C public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode) { if (p.error) { throw new ArgumentException("Path has an error"); } List <GraphNode> path = p.path; if (path.Count == 0) { throw new ArgumentException("Path traverses no nodes"); } this.seeker = s; for (int i = 0; i < this.parts.Count; i++) { if (this.parts[i] is RichFunnel) { ObjectPool <RichFunnel> .Release(this.parts[i] as RichFunnel); } else if (this.parts[i] is RichSpecial) { ObjectPool <RichSpecial> .Release(this.parts[i] as RichSpecial); } } this.parts.Clear(); this.currentPart = 0; for (int j = 0; j < path.Count; j++) { if (path[j] is TriangleMeshNode) { IFunnelGraph graph = AstarData.GetGraph(path[j]) as IFunnelGraph; RichFunnel richFunnel = ObjectPool <RichFunnel> .Claim().Initialize(this, graph); richFunnel.funnelSimplificationMode = simplificationMode; int num = j; uint graphIndex = path[num].GraphIndex; while (j < path.Count) { if (path[j].GraphIndex != graphIndex && !(path[j] is NodeLink3Node)) { break; } j++; } j--; if (num == 0) { richFunnel.exactStart = p.vectorPath[0]; } else if (mergePartEndpoints) { richFunnel.exactStart = (Vector3)path[num - 1].position; } else { richFunnel.exactStart = (Vector3)path[num].position; } if (j == path.Count - 1) { richFunnel.exactEnd = p.vectorPath[p.vectorPath.Count - 1]; } else if (mergePartEndpoints) { richFunnel.exactEnd = (Vector3)path[j + 1].position; } else { richFunnel.exactEnd = (Vector3)path[j].position; } richFunnel.BuildFunnelCorridor(path, num, j); this.parts.Add(richFunnel); } else if (path[j] != null && NodeLink2.GetNodeLink(path[j]) != null) { NodeLink2 nodeLink = NodeLink2.GetNodeLink(path[j]); int num2 = j; uint graphIndex2 = path[num2].GraphIndex; for (j++; j < path.Count; j++) { if (path[j].GraphIndex != graphIndex2) { break; } } j--; if (j - num2 > 1) { throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num2)); } if (j - num2 != 0) { RichSpecial item = ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path[num2]); this.parts.Add(item); } } } }
/// <summary>Use this for initialization.</summary> /// <param name="seeker">Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\</param> /// <param name="path">Path to follow</param> /// <param name="mergePartEndpoints">If true, then adjacent parts that the path is split up in will /// try to use the same start/end points. For example when using a link on a navmesh graph /// Instead of first following the path to the center of the node where the link is and then /// follow the link, the path will be adjusted to go to the exact point where the link starts /// which usually makes more sense.</param> /// <param name="simplificationMode">The path can optionally be simplified. This can be a bit expensive for long paths.</param> public void Initialize(Seeker seeker, Path path, bool mergePartEndpoints, bool simplificationMode) { if (path.error) { throw new System.ArgumentException("Path has an error"); } List <GraphNode> nodes = path.path; if (nodes.Count == 0) { throw new System.ArgumentException("Path traverses no nodes"); } this.seeker = seeker; // Release objects back to object pool // Yeah, I know, it's casting... but this won't be called much for (int i = 0; i < parts.Count; i++) { var funnelPart = parts[i] as RichFunnel; var specialPart = parts[i] as RichSpecial; if (funnelPart != null) { ObjectPool <RichFunnel> .Release(ref funnelPart); } else if (specialPart != null) { ObjectPool <RichSpecial> .Release(ref specialPart); } } Clear(); // Initialize new Endpoint = path.vectorPath[path.vectorPath.Count - 1]; //Break path into parts for (int i = 0; i < nodes.Count; i++) { if (nodes[i] is TriangleMeshNode) { var graph = AstarData.GetGraph(nodes[i]) as NavmeshBase; if (graph == null) { throw new System.Exception("Found a TriangleMeshNode that was not in a NavmeshBase graph"); } RichFunnel f = ObjectPool <RichFunnel> .Claim().Initialize(this, graph); f.funnelSimplification = simplificationMode; int sIndex = i; uint currentGraphIndex = nodes[sIndex].GraphIndex; for (; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node)) { break; } } i--; if (sIndex == 0) { f.exactStart = path.vectorPath[0]; } else { f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex - 1 : sIndex].position; } if (i == nodes.Count - 1) { f.exactEnd = path.vectorPath[path.vectorPath.Count - 1]; } else { f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i + 1 : i].position; } f.BuildFunnelCorridor(nodes, sIndex, i); parts.Add(f); } else if (NodeLink2.GetNodeLink(nodes[i]) != null) { NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]); int sIndex = i; uint currentGraphIndex = nodes[sIndex].GraphIndex; for (i++; i < nodes.Count; i++) { if (nodes[i].GraphIndex != currentGraphIndex) { break; } } i--; if (i - sIndex > 1) { throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex)); } else if (i - sIndex == 0) { //Just continue, it might be the case that a NodeLink was the closest node continue; } RichSpecial rps = ObjectPool <RichSpecial> .Claim().Initialize(nl, nodes[sIndex]); parts.Add(rps); } else if (!(nodes[i] is PointNode)) { // Some other graph type which we do not have support for throw new System.InvalidOperationException("The RichAI movment script can only be used on recast/navmesh graphs. A node of type " + nodes[i].GetType().Name + " was in the path."); } } }
public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode) { if (p.error) { throw new ArgumentException("Path has an error"); } List <GraphNode> path = p.path; if (path.Count == 0) { throw new ArgumentException("Path traverses no nodes"); } this.seeker = s; for (int i = 0; i < this.parts.Count; i++) { RichFunnel funnel = this.parts[i] as RichFunnel; RichSpecial special = this.parts[i] as RichSpecial; if (funnel != null) { Pathfinding.Util.ObjectPool <RichFunnel> .Release(ref funnel); } else if (special != null) { Pathfinding.Util.ObjectPool <RichSpecial> .Release(ref special); } } this.parts.Clear(); this.currentPart = 0; for (int j = 0; j < path.Count; j++) { if (path[j] is TriangleMeshNode) { NavGraph graph = AstarData.GetGraph(path[j]); RichFunnel item = Pathfinding.Util.ObjectPool <RichFunnel> .Claim().Initialize(this, graph); item.funnelSimplificationMode = simplificationMode; int start = j; uint graphIndex = path[start].GraphIndex; while (j < path.Count) { if ((path[j].GraphIndex != graphIndex) && !(path[j] is NodeLink3Node)) { break; } j++; } j--; if (start == 0) { item.exactStart = p.vectorPath[0]; } else { item.exactStart = (Vector3)path[!mergePartEndpoints ? start : (start - 1)].position; } if (j == (path.Count - 1)) { item.exactEnd = p.vectorPath[p.vectorPath.Count - 1]; } else { item.exactEnd = (Vector3)path[!mergePartEndpoints ? j : (j + 1)].position; } item.BuildFunnelCorridor(path, start, j); this.parts.Add(item); continue; } if (NodeLink2.GetNodeLink(path[j]) != null) { NodeLink2 nodeLink = NodeLink2.GetNodeLink(path[j]); int num5 = j; uint num6 = path[num5].GraphIndex; j++; while (j < path.Count) { if (path[j].GraphIndex != num6) { break; } j++; } j--; if ((j - num5) > 1) { throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num5)); } if ((j - num5) != 0) { RichSpecial special2 = Pathfinding.Util.ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path[num5]); this.parts.Add(special2); } } } }