PathModifyHelper.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using System.Collections.Generic;
  2. using PF;
  3. namespace ETModel
  4. {
  5. public static class PathModifyHelper
  6. {
  7. public static void StartEndModify(PF.ABPath abPath)
  8. {
  9. if (abPath.vectorPath.Count == 1)
  10. {
  11. abPath.vectorPath.Add(abPath.vectorPath[0]);
  12. }
  13. abPath.vectorPath[0] = abPath.startPoint;
  14. abPath.vectorPath[abPath.vectorPath.Count - 1] = abPath.endPoint;
  15. }
  16. public static void FunnelModify (Path p) {
  17. if (p.path == null || p.path.Count == 0 || p.vectorPath == null || p.vectorPath.Count == 0) {
  18. return;
  19. }
  20. List<Vector3> funnelPath = ListPool<Vector3>.Claim();
  21. // Split the path into different parts (separated by custom links)
  22. // and run the funnel algorithm on each of them in turn
  23. var parts = Funnel.SplitIntoParts(p);
  24. if (parts.Count == 0) {
  25. // As a really special case, it might happen that the path contained only a single node
  26. // and that node was part of a custom link (e.g added by the NodeLink2 component).
  27. // In that case the SplitIntoParts method will not know what to do with it because it is
  28. // neither a link (as only 1 of the 2 nodes of the link was part of the path) nor a normal
  29. // path part. So it will skip it. This will cause it to return an empty list.
  30. // In that case we want to simply keep the original path, which is just a single point.
  31. return;
  32. }
  33. for (int i = 0; i < parts.Count; i++) {
  34. var part = parts[i];
  35. if (!part.isLink) {
  36. var portals = Funnel.ConstructFunnelPortals(p.path, part);
  37. var result = Funnel.Calculate(portals, true, false);
  38. funnelPath.AddRange(result);
  39. ListPool<Vector3>.Release(ref portals.left);
  40. ListPool<Vector3>.Release(ref portals.right);
  41. ListPool<Vector3>.Release(ref result);
  42. } else {
  43. // non-link parts will add the start/end points for the adjacent parts.
  44. // So if there is no non-link part before this one, then we need to add the start point of the link
  45. // and if there is no non-link part after this one, then we need to add the end point.
  46. if (i == 0 || parts[i-1].isLink) {
  47. funnelPath.Add(part.startPoint);
  48. }
  49. if (i == parts.Count - 1 || parts[i+1].isLink) {
  50. funnelPath.Add(part.endPoint);
  51. }
  52. }
  53. }
  54. ListPool<Funnel.PathPart>.Release(ref parts);
  55. // Pool the previous vectorPath
  56. ListPool<Vector3>.Release(ref p.vectorPath);
  57. p.vectorPath = funnelPath;
  58. }
  59. }
  60. }