ShapeExtensions.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace UnityEditor.Experimental.Rendering.Universal.Path2D
  6. {
  7. internal static class ShapeExtensions
  8. {
  9. public static Polygon ToPolygon(this Vector3[] points, bool isOpenEnded)
  10. {
  11. return new Polygon()
  12. {
  13. isOpenEnded = isOpenEnded,
  14. points = points
  15. };
  16. }
  17. public static Spline ToSpline(this Vector3[] points, bool isOpenEnded)
  18. {
  19. if (!points.IsSpline(isOpenEnded) && points.IsSpline(!isOpenEnded))
  20. {
  21. var pointList = new List<Vector3>(points);
  22. if (isOpenEnded)
  23. {
  24. while (pointList.Count % 3 != 1)
  25. pointList.RemoveAt(pointList.Count-1);
  26. points = pointList.ToArray();
  27. }
  28. else
  29. {
  30. var last = pointList[pointList.Count-1];
  31. var first = pointList[0];
  32. var v = first - last;
  33. pointList.Add(last + v.normalized * (v.magnitude / 3f));
  34. pointList.Add(first - v.normalized * (v.magnitude / 3f));
  35. points = pointList.ToArray();
  36. }
  37. }
  38. if (!points.IsSpline(isOpenEnded))
  39. throw new Exception("The provided control point array can't conform a Spline.");
  40. return new Spline()
  41. {
  42. isOpenEnded = isOpenEnded,
  43. points = points
  44. };
  45. }
  46. public static bool IsSpline(this Vector3[] points, bool isOpenEnded)
  47. {
  48. if (points.Length < 4)
  49. return false;
  50. if (isOpenEnded && points.Length % 3 != 1)
  51. return false;
  52. if (!isOpenEnded && points.Length % 3 != 0)
  53. return false;
  54. return true;
  55. }
  56. public static Spline ToSpline(this Polygon polygon)
  57. {
  58. var newPointCount = polygon.points.Length * 3;
  59. if (polygon.isOpenEnded)
  60. newPointCount = (polygon.points.Length - 1) * 3 + 1;
  61. var newPoints = new Vector3[newPointCount];
  62. var controlPoints = polygon.points;
  63. var pointCount = controlPoints.Length;
  64. for (var i = 0; i < pointCount; ++i)
  65. {
  66. var nextIndex = (i + 1) % pointCount;
  67. var point = controlPoints[i];
  68. var v = controlPoints[nextIndex] - point;
  69. newPoints[i * 3] = point;
  70. if (i * 3 + 2 < newPointCount)
  71. {
  72. newPoints[i * 3 + 1] = point + v / 3f;
  73. newPoints[i * 3 + 2] = point + v * 2f / 3f;
  74. }
  75. }
  76. return new Spline()
  77. {
  78. isOpenEnded = polygon.isOpenEnded,
  79. points = newPoints
  80. };
  81. }
  82. }
  83. }