public override void Apply(Path p) { if (p.path == null || p.path.Count == 0 || p.vectorPath == null || p.vectorPath.Count == 0) { return; } List <Vector3> funnelPath = ListPool <Vector3> .Claim(); var parts = Funnel.SplitIntoParts(p); for (int i = 0; i < parts.Count; i++) { var part = parts[i]; if (!part.isLink) { var portals = Funnel.ConstructFunnelPortals(p.path, part); var result = Funnel.Calculate(portals, unwrap, splitAtEveryPortal); funnelPath.AddRange(result); ListPool <Vector3> .Release(result); } } ListPool <Funnel.PathPart> .Release(parts); ListPool <Vector3> .Release(p.vectorPath); p.vectorPath = funnelPath; }
public static void Unwrap(Funnel.FunnelPortals funnel, Vector2[] left, Vector2[] right) { Vector3 fromDirection = Vector3.Cross(funnel.right[1] - funnel.left[0], funnel.left[1] - funnel.left[0]); left[0] = (right[0] = Vector2.zero); Vector3 vector = funnel.left[1]; Vector3 vector2 = funnel.right[1]; Vector3 prevPoint = funnel.left[0]; Quaternion rotation = Quaternion.FromToRotation(fromDirection, Vector3.forward); Vector3 b = rotation * -funnel.right[0]; for (int i = 1; i < funnel.left.Count; i++) { if (Funnel.UnwrapHelper(vector, vector2, prevPoint, funnel.left[i], ref rotation, ref b)) { prevPoint = vector; vector = funnel.left[i]; } left[i] = rotation * funnel.left[i] + b; if (Funnel.UnwrapHelper(vector, vector2, prevPoint, funnel.right[i], ref rotation, ref b)) { prevPoint = vector2; vector2 = funnel.right[i]; } right[i] = rotation * funnel.right[i] + b; } }
public override void Apply(Path p) { if (p.path == null || p.path.Count == 0 || p.vectorPath == null || p.vectorPath.Count == 0) { return; } List <Vector3> list = ListPool <Vector3> .Claim(); List <Funnel.PathPart> list2 = Funnel.SplitIntoParts(p); for (int i = 0; i < list2.Count; i++) { Funnel.PathPart pathPart = list2[i]; if (!pathPart.isLink) { List <Vector3> list3 = Funnel.Calculate(Funnel.ConstructFunnelPortals(p.path, pathPart), this.unwrap, this.splitAtEveryPortal); list.AddRange(list3); ListPool <Vector3> .Release(list3); } } ListPool <Funnel.PathPart> .Release(list2); ListPool <Vector3> .Release(p.vectorPath); p.vectorPath = list; }
public override void Apply(Path p) { if (p.path == null || p.path.Count == 0 || p.vectorPath == null || p.vectorPath.Count == 0) { return; } List <Vector3> funnelPath = ListPool <Vector3> .Claim(); // Split the path into different parts (separated by custom links) // and run the funnel algorithm on each of them in turn var parts = Funnel.SplitIntoParts(p); for (int i = 0; i < parts.Count; i++) { var part = parts[i]; if (!part.isLink) { var portals = Funnel.ConstructFunnelPortals(p.path, part); var result = Funnel.Calculate(portals, unwrap, splitAtEveryPortal); funnelPath.AddRange(result); ListPool <Vector3> .Release(result); } } ListPool <Funnel.PathPart> .Release(parts); // Pool the previous vectorPath ListPool <Vector3> .Release(p.vectorPath); p.vectorPath = funnelPath; }
// Token: 0x06002648 RID: 9800 RVA: 0x001A5D98 File Offset: 0x001A3F98 public override void Apply(Path p) { if (p.path == null || p.path.Count == 0 || p.vectorPath == null || p.vectorPath.Count == 0) { return; } List <Vector3> list = ListPool <Vector3> .Claim(); List <Funnel.PathPart> list2 = Funnel.SplitIntoParts(p); if (list2.Count == 0) { return; } for (int i = 0; i < list2.Count; i++) { Funnel.PathPart pathPart = list2[i]; if (!pathPart.isLink) { Funnel.FunnelPortals funnel = Funnel.ConstructFunnelPortals(p.path, pathPart); List <Vector3> collection = Funnel.Calculate(funnel, this.unwrap, this.splitAtEveryPortal); list.AddRange(collection); ListPool <Vector3> .Release(ref funnel.left); ListPool <Vector3> .Release(ref funnel.right); ListPool <Vector3> .Release(ref collection); } else { if (i == 0 || list2[i - 1].isLink) { list.Add(pathPart.startPoint); } if (i == list2.Count - 1 || list2[i + 1].isLink) { list.Add(pathPart.endPoint); } } } ListPool <Funnel.PathPart> .Release(ref list2); ListPool <Vector3> .Release(ref p.vectorPath); p.vectorPath = list; }
public override void Apply(Path p) { if (p.path == null || p.path.Count == 0 || p.vectorPath == null || p.vectorPath.Count == 0) { return; } List <Vector3> funnelPath = ListPool <Vector3> .Claim(); // Split the path into different parts (separated by custom links) // and run the funnel algorithm on each of them in turn var parts = Funnel.SplitIntoParts(p); if (parts.Count == 0) { // As a really special case, it might happen that the path contained only a single node // and that node was part of a custom link (e.g added by the NodeLink2 component). // In that case the SplitIntoParts method will not know what to do with it because it is // neither a link (as only 1 of the 2 nodes of the link was part of the path) nor a normal // path part. So it will skip it. This will cause it to return an empty list. // In that case we want to simply keep the original path, which is just a single point. return; } for (int i = 0; i < parts.Count; i++) { var part = parts[i]; if (!part.isLink) { var portals = Funnel.ConstructFunnelPortals(p.path, part); var result = Funnel.Calculate(portals, unwrap, splitAtEveryPortal); funnelPath.AddRange(result); ListPool <Vector3> .Release(ref portals.left); ListPool <Vector3> .Release(ref portals.right); ListPool <Vector3> .Release(ref result); } else { // non-link parts will add the start/end points for the adjacent parts. // So if there is no non-link part before this one, then we need to add the start point of the link // and if there is no non-link part after this one, then we need to add the end point. if (i == 0 || parts[i - 1].isLink) { funnelPath.Add(part.startPoint); } if (i == parts.Count - 1 || parts[i + 1].isLink) { funnelPath.Add(part.endPoint); } } } UnityEngine.Assertions.Assert.IsTrue(funnelPath.Count >= 1); ListPool <Funnel.PathPart> .Release(ref parts); // Pool the previous vectorPath ListPool <Vector3> .Release(ref p.vectorPath); p.vectorPath = funnelPath; }
private static void Calculate(Vector2[] left, Vector2[] right, int startIndex, List <int> funnelPath, int maxCorners, out bool lastCorner) { if (left.Length != right.Length) { throw new ArgumentException(); } lastCorner = false; int num = startIndex + 1; int num2 = startIndex + 1; Vector2 vector = left[startIndex]; Vector2 vector2 = left[num2]; Vector2 vector3 = right[num]; funnelPath.Add(startIndex); int i = startIndex + 2; while (i < left.Length) { if (funnelPath.Count >= maxCorners) { return; } if (funnelPath.Count > 2000) { Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths."); break; } Vector2 vector4 = left[i]; Vector2 vector5 = right[i]; if (!Funnel.LeftOrColinear(vector3 - vector, vector5 - vector)) { goto IL_D9; } if (vector == vector3 || Funnel.RightOrColinear(vector2 - vector, vector5 - vector)) { vector3 = vector5; num = i; goto IL_D9; } vector3 = (vector = vector2); funnelPath.Add(i = (num = num2)); IL_12F: i++; continue; IL_D9: if (!Funnel.RightOrColinear(vector2 - vector, vector4 - vector)) { goto IL_12F; } if (vector == vector2 || Funnel.LeftOrColinear(vector3 - vector, vector4 - vector)) { vector2 = vector4; num2 = i; goto IL_12F; } vector2 = (vector = vector3); funnelPath.Add(-(i = (num2 = num))); goto IL_12F; } lastCorner = true; funnelPath.Add(left.Length - 1); }
public static List <Vector3> Calculate(Funnel.FunnelPortals funnel, bool unwrap, bool splitAtEveryPortal) { Vector2[] array = new Vector2[funnel.left.Count]; Vector2[] array2 = new Vector2[funnel.left.Count]; if (unwrap) { Funnel.Unwrap(funnel, array, array2); } else { for (int i = 0; i < array.Length; i++) { array[i] = Funnel.ToXZ(funnel.left[i]); array2[i] = Funnel.ToXZ(funnel.right[i]); } } Vector2[] array3 = array; int num = Funnel.FixFunnel(ref array, ref array2); List <Vector3> list = funnel.left; List <Vector3> list2 = funnel.right; if (array3 != array) { list = funnel.right; list2 = funnel.left; } List <int> list3 = ListPool <int> .Claim(); if (num == -1) { list3.Add(0); list3.Add(funnel.left.Count - 1); } else { bool flag; Funnel.Calculate(array, array2, num, list3, int.MaxValue, out flag); } List <Vector3> list4 = ListPool <Vector3> .Claim(list3.Count); Vector2 p = array[0]; int num2 = 0; for (int j = 0; j < list3.Count; j++) { int num3 = list3[j]; if (splitAtEveryPortal) { Vector2 vector = (num3 >= 0) ? array[num3] : array2[-num3]; for (int k = num2 + 1; k < Math.Abs(num3); k++) { float t = VectorMath.LineIntersectionFactorXZ(Funnel.FromXZ(array[k]), Funnel.FromXZ(array2[k]), Funnel.FromXZ(p), Funnel.FromXZ(vector)); list4.Add(Vector3.Lerp(list[k], list2[k], t)); } num2 = Mathf.Abs(num3); p = vector; } if (num3 >= 0) { list4.Add(list[num3]); } else { list4.Add(list2[-num3]); } } ListPool <Vector3> .Release(funnel.left); ListPool <Vector3> .Release(funnel.right); ListPool <int> .Release(list3); return(list4); }
/// <summary> /// Build a funnel corridor from a node list slice. /// The nodes are assumed to be of type TriangleMeshNode. /// </summary> /// <param name="nodes">Nodes to build the funnel corridor from</param> /// <param name="start">Start index in the nodes list</param> /// <param name="end">End index in the nodes list, this index is inclusive</param> public void BuildFunnelCorridor(List <GraphNode> nodes, int start, int end) { //Make sure start and end points are on the correct nodes exactStart = (nodes[start] as MeshNode).ClosestPointOnNode(exactStart); exactEnd = (nodes[end] as MeshNode).ClosestPointOnNode(exactEnd); left.Clear(); right.Clear(); left.Add(exactStart); right.Add(exactStart); this.nodes.Clear(); if (funnelSimplification) { List <GraphNode> tmp = ListPool <GraphNode> .Claim(end - start); var tagPenalties = path.seeker != null ? path.seeker.tagPenalties : Path.ZeroTagPenalties; var traversableTags = path.seeker != null ? path.seeker.traversableTags : -1; Funnel.Simplify(new Funnel.PathPart { startIndex = start, endIndex = end, startPoint = exactStart, endPoint = exactEnd, isLink = false, }, graph, nodes, tmp, tagPenalties, traversableTags); if (this.nodes.Capacity < tmp.Count) { this.nodes.Capacity = tmp.Count; } for (int i = 0; i < tmp.Count; i++) { // Guaranteed to be TriangleMeshNodes since they are all in the same graph var node = tmp[i] as TriangleMeshNode; if (node != null) { this.nodes.Add(node); } } ListPool <GraphNode> .Release(ref tmp); } else { if (this.nodes.Capacity < end - start) { this.nodes.Capacity = (end - start); } for (int i = start; i <= end; i++) { //Guaranteed to be TriangleMeshNodes since they are all in the same graph var node = nodes[i] as TriangleMeshNode; if (node != null) { this.nodes.Add(node); } } } for (int i = 0; i < this.nodes.Count - 1; i++) { /// <summary>TODO: should use return value in future versions</summary> this.nodes[i].GetPortal(this.nodes[i + 1], left, right, false); } left.Add(exactEnd); right.Add(exactEnd); }
// Token: 0x06002797 RID: 10135 RVA: 0x001B2B78 File Offset: 0x001B0D78 public static List <Vector3> Calculate(Funnel.FunnelPortals funnel, bool unwrap, bool splitAtEveryPortal) { if (funnel.left.Count != funnel.right.Count) { throw new ArgumentException("funnel.left.Count != funnel.right.Count"); } Vector2[] array = ArrayPool <Vector2> .Claim(funnel.left.Count); Vector2[] array2 = ArrayPool <Vector2> .Claim(funnel.left.Count); if (unwrap) { Funnel.Unwrap(funnel, array, array2); } else { for (int i = 0; i < funnel.left.Count; i++) { array[i] = Funnel.ToXZ(funnel.left[i]); array2[i] = Funnel.ToXZ(funnel.right[i]); } } int num = Funnel.FixFunnel(array, array2, funnel.left.Count); List <int> list = ListPool <int> .Claim(); if (num == -1) { list.Add(0); list.Add(funnel.left.Count - 1); } else { bool flag; Funnel.Calculate(array, array2, funnel.left.Count, num, list, int.MaxValue, out flag); } List <Vector3> list2 = ListPool <Vector3> .Claim(list.Count); Vector2 p = array[0]; int num2 = 0; for (int j = 0; j < list.Count; j++) { int num3 = list[j]; if (splitAtEveryPortal) { Vector2 vector = (num3 >= 0) ? array[num3] : array2[-num3]; for (int k = num2 + 1; k < Math.Abs(num3); k++) { float t = VectorMath.LineIntersectionFactorXZ(Funnel.FromXZ(array[k]), Funnel.FromXZ(array2[k]), Funnel.FromXZ(p), Funnel.FromXZ(vector)); list2.Add(Vector3.Lerp(funnel.left[k], funnel.right[k], t)); } num2 = Mathf.Abs(num3); p = vector; } if (num3 >= 0) { list2.Add(funnel.left[num3]); } else { list2.Add(funnel.right[-num3]); } } ListPool <int> .Release(ref list); ArrayPool <Vector2> .Release(ref array, false); ArrayPool <Vector2> .Release(ref array2, false); return(list2); }