123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896 |
- using UnityEngine;
- using System.Collections.Generic;
- using Pathfinding.Util;
- namespace Pathfinding {
- public class RichPath {
- int currentPart;
- readonly List<RichPathPart> parts = new List<RichPathPart>();
- public Seeker seeker;
-
-
-
-
-
-
-
-
-
-
- public ITransform transform;
- public RichPath () {
- Clear();
- }
- public void Clear () {
- parts.Clear();
- currentPart = 0;
- Endpoint = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
- }
-
-
-
-
-
-
-
-
-
- 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;
-
-
- 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();
-
- Endpoint = path.vectorPath[path.vectorPath.Count-1];
-
- 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) {
-
- continue;
- }
- RichSpecial rps = ObjectPool<RichSpecial>.Claim().Initialize(nl, nodes[sIndex]);
- parts.Add(rps);
- } else if (!(nodes[i] is PointNode)) {
-
- 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 Vector3 Endpoint { get; private set; }
-
- public bool CompletedAllParts {
- get {
- return currentPart >= parts.Count;
- }
- }
-
- public bool IsLastPart {
- get {
- return currentPart >= parts.Count - 1;
- }
- }
- public void NextPart () {
- currentPart = Mathf.Min(currentPart + 1, parts.Count);
- }
- public RichPathPart GetCurrentPart () {
- if (parts.Count == 0) return null;
- return currentPart < parts.Count ? parts[currentPart] : parts[parts.Count - 1];
- }
-
-
-
-
- public void GetRemainingPath (List<Vector3> buffer, Vector3 currentPosition, out bool requiresRepath) {
- buffer.Clear();
- buffer.Add(currentPosition);
- requiresRepath = false;
- for (int i = currentPart; i < parts.Count; i++) {
- var part = parts[i];
- if (part is RichFunnel funnel) {
- bool lastCorner;
- if (i != 0) buffer.Add(funnel.exactStart);
- funnel.Update(i == 0 ? currentPosition : funnel.exactStart, buffer, int.MaxValue, out lastCorner, out requiresRepath);
- if (requiresRepath) {
- return;
- }
- } else if (part is RichSpecial link) {
-
- }
- }
- }
- }
- public abstract class RichPathPart : Pathfinding.Util.IAstarPooledObject {
- public abstract void OnEnterPool();
- }
- public class RichFunnel : RichPathPart {
- readonly List<Vector3> left;
- readonly List<Vector3> right;
- List<TriangleMeshNode> nodes;
- public Vector3 exactStart;
- public Vector3 exactEnd;
- NavmeshBase graph;
- int currentNode;
- Vector3 currentPosition;
- int checkForDestroyedNodesCounter;
- RichPath path;
- int[] triBuffer = new int[3];
-
- public bool funnelSimplification = true;
- public RichFunnel () {
- left = Pathfinding.Util.ListPool<Vector3>.Claim();
- right = Pathfinding.Util.ListPool<Vector3>.Claim();
- nodes = new List<TriangleMeshNode>();
- this.graph = null;
- }
-
- public RichFunnel Initialize (RichPath path, NavmeshBase graph) {
- if (graph == null) throw new System.ArgumentNullException("graph");
- if (this.graph != null) throw new System.InvalidOperationException("Trying to initialize an already initialized object. " + graph);
- this.graph = graph;
- this.path = path;
- return this;
- }
- public override void OnEnterPool () {
- left.Clear();
- right.Clear();
- nodes.Clear();
- graph = null;
- currentNode = 0;
- checkForDestroyedNodesCounter = 0;
- }
- public TriangleMeshNode CurrentNode {
- get {
- var node = nodes[currentNode];
- if (!node.Destroyed) {
- return node;
- }
- return null;
- }
- }
-
-
-
-
-
-
-
- public void BuildFunnelCorridor (List<GraphNode> nodes, int start, int end) {
-
- 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 = Pathfinding.Util.ListPool<GraphNode>.Claim(end-start);
- SimplifyPath(graph, nodes, start, end, tmp, exactStart, exactEnd);
- if (this.nodes.Capacity < tmp.Count) this.nodes.Capacity = tmp.Count;
- for (int i = 0; i < tmp.Count; i++) {
-
- var node = tmp[i] as TriangleMeshNode;
- if (node != null) this.nodes.Add(node);
- }
- Pathfinding.Util.ListPool<GraphNode>.Release(ref tmp);
- } else {
- if (this.nodes.Capacity < end-start) this.nodes.Capacity = (end-start);
- for (int i = start; i <= end; i++) {
-
- var node = nodes[i] as TriangleMeshNode;
- if (node != null) this.nodes.Add(node);
- }
- }
- for (int i = 0; i < this.nodes.Count-1; i++) {
-
- this.nodes[i].GetPortal(this.nodes[i+1], left, right, false);
- }
- left.Add(exactEnd);
- right.Add(exactEnd);
- }
-
-
-
-
-
-
-
-
- void SimplifyPath (IRaycastableGraph graph, List<GraphNode> nodes, int start, int end, List<GraphNode> result, Vector3 startPoint, Vector3 endPoint) {
- if (graph == null) throw new System.ArgumentNullException("graph");
- if (start > end) {
- throw new System.ArgumentException("start >= end");
- }
-
- {
- GraphHitInfo hit;
- if (!graph.Linecast(startPoint, endPoint, out hit) && hit.node == nodes[end]) {
- graph.Linecast(startPoint, endPoint, out hit, result);
- long penaltySum = 0;
- long penaltySum2 = 0;
- for (int i = start; i <= end; i++) {
- penaltySum += nodes[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[nodes[i].Tag] : 0);
- }
- for (int i = 0; i < result.Count; i++) {
- penaltySum2 += result[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[result[i].Tag] : 0);
- }
-
- if ((penaltySum*1.4*result.Count) < (penaltySum2*(end-start+1))) {
-
-
- result.Clear();
- } else {
-
-
- return;
- }
- }
- }
- int ostart = start;
- int count = 0;
- while (true) {
- if (count++ > 1000) {
- Debug.LogError("Was the path really long or have we got cought in an infinite loop?");
- break;
- }
- if (start == end) {
- result.Add(nodes[end]);
- return;
- }
- int resCount = result.Count;
-
- int mx = end+1;
- int mn = start+1;
- bool anySucceded = false;
- while (mx > mn+1) {
- int mid = (mx+mn)/2;
- GraphHitInfo hit;
- Vector3 sp = start == ostart ? startPoint : (Vector3)nodes[start].position;
- Vector3 ep = mid == end ? endPoint : (Vector3)nodes[mid].position;
-
-
- if (graph.Linecast(sp, ep, out hit) || hit.node != nodes[mid]) {
- mx = mid;
- } else {
- anySucceded = true;
- mn = mid;
- }
- }
- if (!anySucceded) {
- result.Add(nodes[start]);
-
- start = mn;
- } else {
-
-
- GraphHitInfo hit;
- Vector3 sp = start == ostart ? startPoint : (Vector3)nodes[start].position;
- Vector3 ep = mn == end ? endPoint : (Vector3)nodes[mn].position;
- graph.Linecast(sp, ep, out hit, result);
- long penaltySum = 0;
- long penaltySum2 = 0;
- for (int i = start; i <= mn; i++) {
- penaltySum += nodes[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[nodes[i].Tag] : 0);
- }
- for (int i = resCount; i < result.Count; i++) {
- penaltySum2 += result[i].Penalty + (path.seeker != null ? path.seeker.tagPenalties[result[i].Tag] : 0);
- }
-
- if ((penaltySum*1.4*(result.Count-resCount)) < (penaltySum2*(mn-start+1)) || result[result.Count-1] != nodes[mn]) {
-
-
- result.RemoveRange(resCount, result.Count-resCount);
- result.Add(nodes[start]);
-
- start = start+1;
- } else {
-
-
- result.RemoveAt(result.Count-1);
- start = mn;
- }
- }
- }
- }
-
-
-
-
- void UpdateFunnelCorridor (int splitIndex, List<TriangleMeshNode> prefix) {
- nodes.RemoveRange(0, splitIndex);
- nodes.InsertRange(0, prefix);
- left.Clear();
- right.Clear();
- left.Add(exactStart);
- right.Add(exactStart);
- for (int i = 0; i < nodes.Count-1; i++) {
-
- nodes[i].GetPortal(nodes[i+1], left, right, false);
- }
- left.Add(exactEnd);
- right.Add(exactEnd);
- }
-
- bool CheckForDestroyedNodes () {
-
-
-
-
- for (int i = 0, t = nodes.Count; i < t; i++) {
- if (nodes[i].Destroyed) {
- return true;
- }
- }
- return false;
- }
-
-
-
-
- public float DistanceToEndOfPath {
- get {
- var currentNode = CurrentNode;
- Vector3 closestOnNode = currentNode != null? currentNode.ClosestPointOnNode(currentPosition) : currentPosition;
- return (exactEnd - closestOnNode).magnitude;
- }
- }
-
-
-
-
- public Vector3 ClampToNavmesh (Vector3 position) {
- if (path.transform != null) position = path.transform.InverseTransform(position);
- ClampToNavmeshInternal(ref position);
- if (path.transform != null) position = path.transform.Transform(position);
- return position;
- }
-
-
-
-
-
-
-
-
-
-
- public Vector3 Update (Vector3 position, List<Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath) {
- if (path.transform != null) position = path.transform.InverseTransform(position);
- lastCorner = false;
- requiresRepath = false;
-
- if (checkForDestroyedNodesCounter >= 10) {
- checkForDestroyedNodesCounter = 0;
- requiresRepath |= CheckForDestroyedNodes();
- } else {
- checkForDestroyedNodesCounter++;
- }
- bool nodesDestroyed = ClampToNavmeshInternal(ref position);
- currentPosition = position;
- if (nodesDestroyed) {
-
-
- requiresRepath = true;
- lastCorner = false;
- buffer.Add(position);
- } else if (!FindNextCorners(position, currentNode, buffer, numCorners, out lastCorner)) {
- Debug.LogError("Failed to find next corners in the path");
- buffer.Add(position);
- }
- if (path.transform != null) {
- for (int i = 0; i < buffer.Count; i++) {
- buffer[i] = path.transform.Transform(buffer[i]);
- }
- position = path.transform.Transform(position);
- }
- return position;
- }
-
- static Queue<TriangleMeshNode> navmeshClampQueue = new Queue<TriangleMeshNode>();
-
- static List<TriangleMeshNode> navmeshClampList = new List<TriangleMeshNode>();
-
- static Dictionary<TriangleMeshNode, TriangleMeshNode> navmeshClampDict = new Dictionary<TriangleMeshNode, TriangleMeshNode>();
-
-
-
-
-
-
-
- bool ClampToNavmeshInternal (ref Vector3 position) {
- var previousNode = nodes[currentNode];
- if (previousNode.Destroyed) {
- return true;
- }
-
- if (previousNode.ContainsPoint(position)) {
- return false;
- }
-
-
- var que = navmeshClampQueue;
- var allVisited = navmeshClampList;
- var parent = navmeshClampDict;
- previousNode.TemporaryFlag1 = true;
- parent[previousNode] = null;
- que.Enqueue(previousNode);
- allVisited.Add(previousNode);
- float bestDistance = float.PositiveInfinity;
- Vector3 bestPoint = position;
- TriangleMeshNode bestNode = null;
- while (que.Count > 0) {
- var node = que.Dequeue();
-
-
-
- var closest = node.ClosestPointOnNodeXZ(position);
- var dist = VectorMath.MagnitudeXZ(closest - position);
-
-
-
- if (dist <= bestDistance * 1.05f + 0.001f) {
- if (dist < bestDistance) {
- bestDistance = dist;
- bestPoint = closest;
- bestNode = node;
- }
- for (int i = 0; i < node.connections.Length; i++) {
- var neighbour = node.connections[i].node as TriangleMeshNode;
- if (neighbour != null && !neighbour.TemporaryFlag1) {
- neighbour.TemporaryFlag1 = true;
- parent[neighbour] = node;
- que.Enqueue(neighbour);
- allVisited.Add(neighbour);
- }
- }
- }
- }
- for (int i = 0; i < allVisited.Count; i++) allVisited[i].TemporaryFlag1 = false;
- allVisited.ClearFast();
- var closestNodeInPath = nodes.IndexOf(bestNode);
-
-
- position.x = bestPoint.x;
- position.z = bestPoint.z;
-
-
- if (closestNodeInPath == -1) {
-
- var prefix = navmeshClampList;
- while (closestNodeInPath == -1) {
- prefix.Add(bestNode);
- bestNode = parent[bestNode];
- closestNodeInPath = nodes.IndexOf(bestNode);
- }
-
-
- exactStart = position;
- UpdateFunnelCorridor(closestNodeInPath, prefix);
- prefix.ClearFast();
-
- currentNode = 0;
- } else {
- currentNode = closestNodeInPath;
- }
- parent.Clear();
-
-
- return currentNode + 1 < nodes.Count && nodes[currentNode+1].Destroyed;
- }
-
-
-
-
- public void FindWalls (List<Vector3> wallBuffer, float range) {
- FindWalls(currentNode, wallBuffer, currentPosition, range);
- }
- void FindWalls (int nodeIndex, List<Vector3> wallBuffer, Vector3 position, float range) {
- if (range <= 0) return;
- bool negAbort = false;
- bool posAbort = false;
- range *= range;
- position.y = 0;
-
- for (int i = 0; !negAbort || !posAbort; i = i < 0 ? -i : -i-1) {
- if (i < 0 && negAbort) continue;
- if (i > 0 && posAbort) continue;
- if (i < 0 && nodeIndex+i < 0) {
- negAbort = true;
- continue;
- }
- if (i > 0 && nodeIndex+i >= nodes.Count) {
- posAbort = true;
- continue;
- }
- TriangleMeshNode prev = nodeIndex+i-1 < 0 ? null : nodes[nodeIndex+i-1];
- TriangleMeshNode node = nodes[nodeIndex+i];
- TriangleMeshNode next = nodeIndex+i+1 >= nodes.Count ? null : nodes[nodeIndex+i+1];
- if (node.Destroyed) {
- break;
- }
- if ((node.ClosestPointOnNodeXZ(position)-position).sqrMagnitude > range) {
- if (i < 0) negAbort = true;
- else posAbort = true;
- continue;
- }
- for (int j = 0; j < 3; j++) triBuffer[j] = 0;
- for (int j = 0; j < node.connections.Length; j++) {
- var other = node.connections[j].node as TriangleMeshNode;
- if (other == null) continue;
- int va = -1;
- for (int a = 0; a < 3; a++) {
- for (int b = 0; b < 3; b++) {
- if (node.GetVertex(a) == other.GetVertex((b+1) % 3) && node.GetVertex((a+1) % 3) == other.GetVertex(b)) {
- va = a;
- a = 3;
- break;
- }
- }
- }
- if (va == -1) {
-
- } else {
- triBuffer[va] = other == prev || other == next ? 2 : 1;
- }
- }
- for (int j = 0; j < 3; j++) {
-
-
-
-
- if (triBuffer[j] == 0) {
-
- wallBuffer.Add((Vector3)node.GetVertex(j));
- wallBuffer.Add((Vector3)node.GetVertex((j+1) % 3));
- }
- }
- }
- if (path.transform != null) {
- for (int i = 0; i < wallBuffer.Count; i++) {
- wallBuffer[i] = path.transform.Transform(wallBuffer[i]);
- }
- }
- }
- bool FindNextCorners (Vector3 origin, int startIndex, List<Vector3> funnelPath, int numCorners, out bool lastCorner) {
- lastCorner = false;
- if (left == null) throw new System.Exception("left list is null");
- if (right == null) throw new System.Exception("right list is null");
- if (funnelPath == null) throw new System.ArgumentNullException("funnelPath");
- if (left.Count != right.Count) throw new System.ArgumentException("left and right lists must have equal length");
- int diagonalCount = left.Count;
- if (diagonalCount == 0) throw new System.ArgumentException("no diagonals");
- if (diagonalCount-startIndex < 3) {
-
- funnelPath.Add(left[diagonalCount-1]);
- lastCorner = true;
- return true;
- }
- #if ASTARDEBUG
- for (int i = startIndex; i < left.Count-1; i++) {
- Debug.DrawLine(left[i], left[i+1], Color.red);
- Debug.DrawLine(right[i], right[i+1], Color.magenta);
- Debug.DrawRay(right[i], Vector3.up, Color.magenta);
- }
- for (int i = 0; i < left.Count; i++) {
- Debug.DrawLine(right[i], left[i], Color.cyan);
- }
- #endif
-
- while (left[startIndex+1] == left[startIndex+2] && right[startIndex+1] == right[startIndex+2]) {
-
-
-
- startIndex++;
- if (diagonalCount-startIndex <= 3) {
- return false;
- }
- }
- Vector3 swPoint = left[startIndex+2];
- if (swPoint == left[startIndex+1]) {
- swPoint = right[startIndex+2];
- }
-
- while (VectorMath.IsColinearXZ(origin, left[startIndex+1], right[startIndex+1]) || VectorMath.RightOrColinearXZ(left[startIndex+1], right[startIndex+1], swPoint) == VectorMath.RightOrColinearXZ(left[startIndex+1], right[startIndex+1], origin)) {
- #if ASTARDEBUG
- Debug.DrawLine(left[startIndex+1], right[startIndex+1], new Color(0, 0, 0, 0.5F));
- Debug.DrawLine(origin, swPoint, new Color(0, 0, 0, 0.5F));
- #endif
-
-
- startIndex++;
- if (diagonalCount-startIndex < 3) {
-
-
- funnelPath.Add(left[diagonalCount-1]);
- lastCorner = true;
- return true;
- }
- swPoint = left[startIndex+2];
- if (swPoint == left[startIndex+1]) {
- swPoint = right[startIndex+2];
- }
- }
-
- Vector3 portalApex = origin;
- Vector3 portalLeft = left[startIndex+1];
- Vector3 portalRight = right[startIndex+1];
- int apexIndex = startIndex+0;
- int rightIndex = startIndex+1;
- int leftIndex = startIndex+1;
- for (int i = startIndex+2; i < diagonalCount; i++) {
- if (funnelPath.Count >= numCorners) {
- return true;
- }
- if (funnelPath.Count > 2000) {
- Debug.LogWarning("Avoiding infinite loop. Remove this check if you have this long paths.");
- break;
- }
- Vector3 pLeft = left[i];
- Vector3 pRight = right[i];
-
- if (VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalRight, pRight) >= 0) {
- if (portalApex == portalRight || VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalLeft, pRight) <= 0) {
- portalRight = pRight;
- rightIndex = i;
- } else {
- funnelPath.Add(portalLeft);
- portalApex = portalLeft;
- apexIndex = leftIndex;
- portalLeft = portalApex;
- portalRight = portalApex;
- leftIndex = apexIndex;
- rightIndex = apexIndex;
- i = apexIndex;
- continue;
- }
- }
- if (VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalLeft, pLeft) <= 0) {
- if (portalApex == portalLeft || VectorMath.SignedTriangleAreaTimes2XZ(portalApex, portalRight, pLeft) >= 0) {
- portalLeft = pLeft;
- leftIndex = i;
- } else {
- funnelPath.Add(portalRight);
- portalApex = portalRight;
- apexIndex = rightIndex;
- portalLeft = portalApex;
- portalRight = portalApex;
- leftIndex = apexIndex;
- rightIndex = apexIndex;
- i = apexIndex;
- continue;
- }
- }
- }
- lastCorner = true;
- funnelPath.Add(left[diagonalCount-1]);
- return true;
- }
- }
- public class RichSpecial : RichPathPart {
- public NodeLink2 nodeLink;
- public Transform first;
- public Transform second;
- public bool reverse;
- public override void OnEnterPool () {
- nodeLink = null;
- }
-
- public RichSpecial Initialize (NodeLink2 nodeLink, GraphNode first) {
- this.nodeLink = nodeLink;
- if (first == nodeLink.startNode) {
- this.first = nodeLink.StartTransform;
- this.second = nodeLink.EndTransform;
- reverse = false;
- } else {
- this.first = nodeLink.EndTransform;
- this.second = nodeLink.StartTransform;
- reverse = true;
- }
- return this;
- }
- }
- }
|