AirControl  1.3.0
Open Source, Modular, and Extensible Flight Simulator For Deep Learning Research
UGL.cs
1 /******************************************/
2 /* */
3 /* Copyright (c) 2020 monitor1394 */
4 /* https://github.com/monitor1394 */
5 /* */
6 /******************************************/
7 
8 using System.Collections.Generic;
9 using UnityEngine;
10 using UnityEngine.UI;
11 
12 namespace XUGL
13 {
18  public static class UGL
19  {
20  private static readonly Color32 s_ClearColor32 = new Color32(0, 0, 0, 0);
21  private static readonly Vector2 s_ZeroVector2 = Vector2.zero;
22  private static UIVertex[] s_Vertex = new UIVertex[4];
23  private static List<Vector3> s_CurvesPosList = new List<Vector3>();
24 
36  public static void DrawArrow(VertexHelper vh, Vector3 startPoint, Vector3 arrowPoint, float width,
37  float height, float offset, float dent, Color32 color)
38  {
39  var dir = (arrowPoint - startPoint).normalized;
40  var sharpPos = arrowPoint + (offset + height / 4) * dir;
41  var middle = sharpPos + (dent - height) * dir;
42  var diff = Vector3.Cross(dir, Vector3.forward).normalized * width / 2;
43  var left = sharpPos - height * dir + diff;
44  var right = sharpPos - height * dir - diff;
45  DrawTriangle(vh, middle, sharpPos, left, color);
46  DrawTriangle(vh, middle, sharpPos, right, color);
47  }
48 
57  public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color)
58  {
59  DrawLine(vh, startPoint, endPoint, width, color, color);
60  }
61 
71  public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color, Color32 toColor)
72  {
73  if (startPoint == endPoint) return;
74  Vector3 v = Vector3.Cross(endPoint - startPoint, Vector3.forward).normalized * width;
75  s_Vertex[0].position = startPoint - v;
76  s_Vertex[1].position = endPoint - v;
77  s_Vertex[2].position = endPoint + v;
78  s_Vertex[3].position = startPoint + v;
79 
80  for (int j = 0; j < 4; j++)
81  {
82  s_Vertex[j].color = j == 0 || j == 3 ? color : toColor;
83  s_Vertex[j].uv0 = s_ZeroVector2;
84  }
85  vh.AddUIVertexQuad(s_Vertex);
86  }
87 
97  public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 middlePoint, Vector3 endPoint,
98  float width, Color32 color)
99  {
100  var dir1 = (middlePoint - startPoint).normalized;
101  var dir2 = (endPoint - middlePoint).normalized;
102  var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized;
103  var dir2v = Vector3.Cross(dir2, Vector3.forward).normalized;
104  var dir3 = (dir1 + dir2).normalized;
105  var isDown = Vector3.Cross(dir1, dir2).z <= 0;
106  var angle = (180 - Vector3.Angle(dir1, dir2)) * Mathf.Deg2Rad / 2;
107  var diff = width / Mathf.Sin(angle);
108  var dirDp = Vector3.Cross(dir3, Vector3.forward).normalized;
109  var dnPos = middlePoint + (isDown ? dirDp : -dirDp) * diff;
110  var upPos1 = middlePoint + (isDown ? -dir1v : dir1v) * width;
111  var upPos2 = middlePoint + (isDown ? -dir2v : dir2v) * width;
112  var startUp = startPoint - dir1v * width;
113  var startDn = startPoint + dir1v * width;
114  var endUp = endPoint - dir2v * width;
115  var endDn = endPoint + dir2v * width;
116  if (isDown)
117  {
118  DrawQuadrilateral(vh, startDn, startUp, upPos1, dnPos, color);
119  DrawQuadrilateral(vh, dnPos, upPos2, endUp, endDn, color);
120  DrawTriangle(vh, dnPos, upPos1, upPos2, color);
121  }
122  else
123  {
124  DrawQuadrilateral(vh, startDn, startUp, dnPos, upPos1, color);
125  DrawQuadrilateral(vh, upPos2, dnPos, endUp, endDn, color);
126  DrawTriangle(vh, dnPos, upPos1, upPos2, color);
127  }
128  }
141  public static void DrawDashLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
142  Color32 color, Color32 toColor, float lineLength = 0f, float gapLength = 0f, List<Vector3> posList = null)
143  {
144  float dist = Vector3.Distance(startPoint, endPoint);
145  if (dist < 0.1f) return;
146  if (lineLength == 0) lineLength = 12 * width;
147  if (gapLength == 0) gapLength = 3 * width;
148  int segment = Mathf.CeilToInt(dist / (lineLength + gapLength));
149  Vector3 dir = (endPoint - startPoint).normalized;
150  Vector3 sp = startPoint, np;
151  var isGradient = !color.Equals(toColor);
152  if (posList != null) posList.Clear();
153  for (int i = 1; i <= segment; i++)
154  {
155  if (posList != null) posList.Add(sp);
156  np = startPoint + dir * dist * i / segment;
157  var dashep = np - dir * gapLength;
158  DrawLine(vh, sp, dashep, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / segment) : color);
159  sp = np;
160  }
161  if (posList != null) posList.Add(endPoint);
162  DrawLine(vh, sp, endPoint, width, toColor);
163  }
164 
177  public static void DrawDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
178  Color32 color, Color32 toColor, float lineLength = 0f, float gapLength = 0f, List<Vector3> posList = null)
179  {
180  var dist = Vector3.Distance(startPoint, endPoint);
181  if (dist < 0.1f) return;
182  if (lineLength == 0) lineLength = 3 * width;
183  if (gapLength == 0) gapLength = 3 * width;
184  var segment = Mathf.CeilToInt(dist / (lineLength + gapLength));
185  var dir = (endPoint - startPoint).normalized;
186  var sp = startPoint;
187  var np = Vector3.zero;
188  var isGradient = !color.Equals(toColor);
189  if (posList != null) posList.Clear();
190  for (int i = 1; i <= segment; i++)
191  {
192  if (posList != null) posList.Add(sp);
193  np = startPoint + dir * dist * i / segment;
194  var dashep = np - dir * gapLength;
195  DrawLine(vh, sp, dashep, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / segment) : color);
196  sp = np;
197  }
198  if (posList != null) posList.Add(endPoint);
199  DrawLine(vh, sp, endPoint, width, toColor);
200  }
201 
214  public static void DrawDashDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
215  Color32 color, float dashLength = 0f, float dotLength = 0, float gapLength = 0f,
216  List<Vector3> posList = null)
217  {
218  float dist = Vector3.Distance(startPoint, endPoint);
219  if (dist < 0.1f) return;
220  if (dashLength == 0) dashLength = 15 * width;
221  if (dotLength == 0) dotLength = 3 * width;
222  if (gapLength == 0) gapLength = 5 * width;
223  int segment = Mathf.CeilToInt(dist / (dashLength + 2 * gapLength + dotLength));
224  Vector3 dir = (endPoint - startPoint).normalized;
225  Vector3 sp = startPoint, np;
226  if (posList != null) posList.Clear();
227  for (int i = 1; i <= segment; i++)
228  {
229  if (posList != null) posList.Add(sp);
230  np = startPoint + dir * dist * i / segment;
231  var dashep = np - dir * (2 * gapLength + dotLength);
232  DrawLine(vh, sp, dashep, width, color);
233  if (posList != null) posList.Add(dashep);
234  var dotsp = dashep + gapLength * dir;
235  var dotep = dotsp + dotLength * dir;
236  DrawLine(vh, dotsp, dotep, width, color);
237  if (posList != null) posList.Add(dotsp);
238  sp = np;
239  }
240  if (posList != null) posList.Add(endPoint);
241  DrawLine(vh, sp, endPoint, width, color);
242  }
243 
256  public static void DrawDashDotDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
257  Color32 color, float dashLength = 0f, float dotLength = 0f, float gapLength = 0f,
258  List<Vector3> posList = null)
259  {
260  float dist = Vector3.Distance(startPoint, endPoint);
261  if (dist < 0.1f) return;
262  if (dashLength == 0) dashLength = 15 * width;
263  if (dotLength == 0) dotLength = 3 * width;
264  if (gapLength == 0) gapLength = 5 * width;
265  int segment = Mathf.CeilToInt(dist / (dashLength + 3 * gapLength + 2 * dotLength));
266  Vector3 dir = (endPoint - startPoint).normalized;
267  Vector3 sp = startPoint, np;
268  if (posList != null) posList.Clear();
269  for (int i = 1; i <= segment; i++)
270  {
271  if (posList != null) posList.Add(sp);
272  np = startPoint + dir * dist * i / segment;
273  var dashep = np - dir * (3 * gapLength + 2 * dotLength);
274  DrawLine(vh, sp, dashep, width, color);
275  if (posList != null) posList.Add(dashep);
276  var dotsp = dashep + gapLength * dir;
277  var dotep = dotsp + dotLength * dir;
278  DrawLine(vh, dotsp, dotep, width, color);
279  if (posList != null) posList.Add(dotep);
280  var dotsp2 = dotep + gapLength * dir;
281  var dotep2 = dotsp2 + dotLength * dir;
282  DrawLine(vh, dotsp2, dotep2, width, color);
283  if (posList != null) posList.Add(dotep2);
284  sp = np;
285  }
286  if (posList != null) posList.Add(endPoint);
287  DrawLine(vh, sp, endPoint, width, color);
288  }
289 
301  public static void DrawZebraLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width,
302  float zebraWidth, float zebraGap, Color32 color, Color32 toColor)
303  {
304  DrawDotLine(vh, startPoint, endPoint, width, color, toColor, zebraWidth, zebraGap);
305  }
306 
314  public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color)
315  {
316  DrawDiamond(vh, center, size, color, color);
317  }
318 
327  public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color, Color32 toColor)
328  {
329  var p1 = new Vector2(center.x - size, center.y);
330  var p2 = new Vector2(center.x, center.y + size);
331  var p3 = new Vector2(center.x + size, center.y);
332  var p4 = new Vector2(center.x, center.y - size);
333  DrawTriangle(vh, p4, p1, p2, color, color, toColor);
334  DrawTriangle(vh, p3, p4, p2, color, color, toColor);
335  }
336 
343  public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color)
344  {
345  DrawSquare(vh, center, radius, color, color, true);
346  }
347 
357  public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color,
358  Color32 toColor, bool vertical = true)
359  {
360  Vector3 p1, p2, p3, p4;
361  if (vertical)
362  {
363  p1 = new Vector3(center.x + radius, center.y - radius);
364  p2 = new Vector3(center.x - radius, center.y - radius);
365  p3 = new Vector3(center.x - radius, center.y + radius);
366  p4 = new Vector3(center.x + radius, center.y + radius);
367  }
368  else
369  {
370  p1 = new Vector3(center.x - radius, center.y - radius);
371  p2 = new Vector3(center.x - radius, center.y + radius);
372  p3 = new Vector3(center.x + radius, center.y + radius);
373  p4 = new Vector3(center.x + radius, center.y - radius);
374  }
375  DrawQuadrilateral(vh, p1, p2, p3, p4, color, toColor);
376  }
377 
385  public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color)
386  {
387  DrawRectangle(vh, p1, p2, radius, color, color);
388  }
389 
399  public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color,
400  Color32 toColor)
401  {
402  var dir = (p2 - p1).normalized;
403  var dirv = Vector3.Cross(dir, Vector3.forward).normalized;
404 
405  var p3 = p1 + dirv * radius;
406  var p4 = p1 - dirv * radius;
407  var p5 = p2 - dirv * radius;
408  var p6 = p2 + dirv * radius;
409  DrawQuadrilateral(vh, p3, p4, p5, p6, color, toColor);
410  }
411 
421  public static void DrawRectangle(VertexHelper vh, Vector3 p, float xRadius, float yRadius,
422  Color32 color, bool vertical = true)
423  {
424  DrawRectangle(vh, p, xRadius, yRadius, color, color, vertical);
425  }
426 
437  public static void DrawRectangle(VertexHelper vh, Vector3 p, float xRadius, float yRadius,
438  Color32 color, Color32 toColor, bool vertical = true)
439  {
440  Vector3 p1, p2, p3, p4;
441  if (vertical)
442  {
443  p1 = new Vector3(p.x + xRadius, p.y - yRadius);
444  p2 = new Vector3(p.x - xRadius, p.y - yRadius);
445  p3 = new Vector3(p.x - xRadius, p.y + yRadius);
446  p4 = new Vector3(p.x + xRadius, p.y + yRadius);
447  }
448  else
449  {
450  p1 = new Vector3(p.x - xRadius, p.y - yRadius);
451  p2 = new Vector3(p.x - xRadius, p.y + yRadius);
452  p3 = new Vector3(p.x + xRadius, p.y + yRadius);
453  p4 = new Vector3(p.x + xRadius, p.y - yRadius);
454  }
455 
456  DrawQuadrilateral(vh, p1, p2, p3, p4, color, toColor);
457  }
458 
459  public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color)
460  {
461  DrawRectangle(vh, rect, 0, color);
462  }
463  public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color)
464  {
465  DrawRectangle(vh, rect, border, color, color);
466  }
467 
468  public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color, Color32 toColor)
469  {
470  DrawRectangle(vh, rect.center, rect.width / 2 - border, rect.height / 2 - border, color, toColor, true);
471  }
472 
482  public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
483  Color32 color)
484  {
485  DrawQuadrilateral(vh, p1, p2, p3, p4, color, color);
486  }
487 
498  public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
499  Color32 startColor, Color32 toColor)
500  {
501  s_Vertex[0].position = p1;
502  s_Vertex[1].position = p2;
503  s_Vertex[2].position = p3;
504  s_Vertex[3].position = p4;
505  for (int j = 0; j < 4; j++)
506  {
507  s_Vertex[j].color = j >= 2 ? toColor : startColor;
508  s_Vertex[j].uv0 = s_ZeroVector2;
509  }
510  vh.AddUIVertexQuad(s_Vertex);
511  }
512 
513  private static void InitCornerRadius(float[] cornerRadius, float width, float height, bool horizontal,
514  bool invert, ref float brLt, ref float brRt, ref float brRb, ref float brLb, ref bool needRound)
515  {
516  if (cornerRadius == null) return;
517  if (invert)
518  {
519  if (horizontal)
520  {
521  brLt = cornerRadius.Length > 0 ? cornerRadius[1] : 0;
522  brRt = cornerRadius.Length > 1 ? cornerRadius[0] : 0;
523  brRb = cornerRadius.Length > 2 ? cornerRadius[3] : 0;
524  brLb = cornerRadius.Length > 3 ? cornerRadius[2] : 0;
525  }
526  else
527  {
528  brLt = cornerRadius.Length > 0 ? cornerRadius[3] : 0;
529  brRt = cornerRadius.Length > 1 ? cornerRadius[2] : 0;
530  brRb = cornerRadius.Length > 2 ? cornerRadius[1] : 0;
531  brLb = cornerRadius.Length > 3 ? cornerRadius[0] : 0;
532  }
533  }
534  else
535  {
536  brLt = cornerRadius.Length > 0 ? cornerRadius[0] : 0;
537  brRt = cornerRadius.Length > 1 ? cornerRadius[1] : 0;
538  brRb = cornerRadius.Length > 2 ? cornerRadius[2] : 0;
539  brLb = cornerRadius.Length > 3 ? cornerRadius[3] : 0;
540  }
541 
542  needRound = brLb != 0 || brRt != 0 || brRb != 0 || brLb != 0;
543  if (needRound)
544  {
545  var min = Mathf.Min(width, height);
546  if (brLt == 1 && brRt == 1 && brRb == 1 && brLb == 1)
547  {
548  brLt = brRt = brRb = brLb = min / 2;
549  return;
550  }
551  if (brLt > 0 && brLt <= 1) brLt = brLt * min;
552  if (brRt > 0 && brRt <= 1) brRt = brRt * min;
553  if (brRb > 0 && brRb <= 1) brRb = brRb * min;
554  if (brLb > 0 && brLb <= 1) brLb = brLb * min;
555  if (horizontal)
556  {
557  if (brLb + brLt >= height)
558  {
559  var total = brLb + brLt;
560  brLb = height * (brLb / total);
561  brLt = height * (brLt / total);
562  }
563  if (brRt + brRb >= height)
564  {
565  var total = brRt + brRb;
566  brRt = height * (brRt / total);
567  brRb = height * (brRb / total);
568  }
569  if (brLt + brRt >= width)
570  {
571  var total = brLt + brRt;
572  brLt = width * (brLt / total);
573  brRt = width * (brRt / total);
574  }
575  if (brRb + brLb >= width)
576  {
577  var total = brRb + brLb;
578  brRb = width * (brRb / total);
579  brLb = width * (brLb / total);
580  }
581  }
582  else
583  {
584  if (brLt + brRt >= width)
585  {
586  var total = brLt + brRt;
587  brLt = width * (brLt / total);
588  brRt = width * (brRt / total);
589  }
590  if (brRb + brLb >= width)
591  {
592  var total = brRb + brLb;
593  brRb = width * (brRb / total);
594  brLb = width * (brLb / total);
595  }
596  if (brLb + brLt >= height)
597  {
598  var total = brLb + brLt;
599  brLb = height * (brLb / total);
600  brLt = height * (brLt / total);
601  }
602  if (brRt + brRb >= height)
603  {
604  var total = brRt + brRb;
605  brRt = height * (brRt / total);
606  brRb = height * (brRb / total);
607  }
608  }
609  }
610  }
611 
626  public static void DrawRoundRectangle(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight,
627  Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null, bool isYAxis = false,
628  float smoothness = 2, bool invertCorner = false)
629  {
630  var isGradient = !UGLHelper.IsValueEqualsColor(color, toColor);
631  var halfWid = rectWidth / 2;
632  var halfHig = rectHeight / 2;
633  float brLt = 0, brRt = 0, brRb = 0, brLb = 0;
634  bool needRound = false;
635  InitCornerRadius(cornerRadius, rectWidth, rectHeight, isYAxis, invertCorner, ref brLt, ref brRt, ref brRb,
636  ref brLb, ref needRound);
637  var tempCenter = Vector3.zero;
638  var lbIn = new Vector3(center.x - halfWid, center.y - halfHig);
639  var ltIn = new Vector3(center.x - halfWid, center.y + halfHig);
640  var rtIn = new Vector3(center.x + halfWid, center.y + halfHig);
641  var rbIn = new Vector3(center.x + halfWid, center.y - halfHig);
642  if (needRound)
643  {
644  var lbIn2 = lbIn;
645  var ltIn2 = ltIn;
646  var rtIn2 = rtIn;
647  var rbIn2 = rbIn;
648  var roundLb = lbIn;
649  var roundLt = ltIn;
650  var roundRt = rtIn;
651  var roundRb = rbIn;
652  if (brLt > 0)
653  {
654  roundLt = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt);
655  ltIn = roundLt + brLt * Vector3.left;
656  ltIn2 = roundLt + brLt * Vector3.up;
657  }
658  if (brRt > 0)
659  {
660  roundRt = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt);
661  rtIn = roundRt + brRt * Vector3.up;
662  rtIn2 = roundRt + brRt * Vector3.right;
663  }
664  if (brRb > 0)
665  {
666  roundRb = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb);
667  rbIn = roundRb + brRb * Vector3.right;
668  rbIn2 = roundRb + brRb * Vector3.down;
669  }
670  if (brLb > 0)
671  {
672  roundLb = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb);
673  lbIn = roundLb + brLb * Vector3.left;
674  lbIn2 = roundLb + brLb * Vector3.down;
675  }
676 
677  if (isYAxis)
678  {
679  var maxLeft = Mathf.Max(brLt, brLb);
680  var maxRight = Mathf.Max(brRt, brRb);
681  var ltInRight = ltIn + maxLeft * Vector3.right;
682  var lbInRight = lbIn + maxLeft * Vector3.right;
683  var rtIn2Left = rtIn2 + maxRight * Vector3.left;
684  var rbInLeft = rbIn + maxRight * Vector3.left;
685 
686  var roundLbRight = roundLb + (maxLeft - brLb) * Vector3.right;
687  var lbIn2Right = lbIn2 + (maxLeft - brLb) * Vector3.right;
688  if (roundLbRight.x > roundRb.x) roundLbRight.x = roundRb.x;
689  if (lbIn2Right.x > roundRb.x) lbIn2Right.x = roundRb.x;
690 
691  var ltIn2Right = ltIn2 + (maxLeft - brLt) * Vector3.right;
692  var roundLtRight = roundLt + (maxLeft - brLt) * Vector3.right;
693  if (ltIn2Right.x > roundRt.x) ltIn2Right.x = roundRt.x;
694  if (roundLtRight.x > roundRt.x) roundLtRight.x = roundRt.x;
695 
696  var roundRtLeft = roundRt + (maxRight - brRt) * Vector3.left;
697  var rtInLeft = rtIn + (maxRight - brRt) * Vector3.left;
698  if (roundRtLeft.x < roundLt.x) roundRtLeft.x = roundLt.x;
699  if (rtInLeft.x < roundLt.x) rtInLeft.x = roundLt.x;
700 
701  var rbIn2Left = rbIn2 + (maxRight - brRb) * Vector3.left;
702  var roundRbLeft = roundRb + (maxRight - brRb) * Vector3.left;
703  if (rbIn2Left.x < roundLb.x) rbIn2Left.x = roundLb.x;
704  if (roundRbLeft.x < roundLb.x) roundRbLeft.x = roundLb.x;
705  if (!isGradient)
706  {
707  DrawSector(vh, roundLt, brLt, color, color, 270, 360, 1, isYAxis, smoothness);
708  DrawSector(vh, roundRt, brRt, toColor, toColor, 0, 90, 1, isYAxis, smoothness);
709  DrawSector(vh, roundRb, brRb, toColor, toColor, 90, 180, 1, isYAxis, smoothness);
710  DrawSector(vh, roundLb, brLb, color, color, 180, 270, 1, isYAxis, smoothness);
711 
712  DrawQuadrilateral(vh, ltIn, ltInRight, lbInRight, lbIn, color, color);
713  DrawQuadrilateral(vh, lbIn2, roundLb, roundLbRight, lbIn2Right, color, color);
714  DrawQuadrilateral(vh, roundLt, ltIn2, ltIn2Right, roundLtRight, color, color);
715 
716  DrawQuadrilateral(vh, rbInLeft, rtIn2Left, rtIn2, rbIn, toColor, toColor);
717  DrawQuadrilateral(vh, roundRtLeft, rtInLeft, rtIn, roundRt, toColor, toColor);
718  DrawQuadrilateral(vh, rbIn2Left, roundRbLeft, roundRb, rbIn2, toColor, toColor);
719 
720  var clt = new Vector3(center.x - halfWid + maxLeft, center.y + halfHig);
721  var crt = new Vector3(center.x + halfWid - maxRight, center.y + halfHig);
722  var crb = new Vector3(center.x + halfWid - maxRight, center.y - halfHig);
723  var clb = new Vector3(center.x - halfWid + maxLeft, center.y - halfHig);
724  if (crt.x > clt.x)
725  {
726  DrawQuadrilateral(vh, clb, clt, crt, crb, color, toColor);
727  }
728  }
729  else
730  {
731  var tempLeftColor = Color32.Lerp(color, toColor, maxLeft / rectWidth);
732  var upLeftColor = Color32.Lerp(color, tempLeftColor, brLt / maxLeft);
733  var downLeftColor = Color32.Lerp(color, tempLeftColor, brLb / maxLeft);
734 
735  var tempRightColor = Color32.Lerp(color, toColor, (rectWidth - maxRight) / rectWidth);
736  var upRightColor = Color32.Lerp(tempRightColor, toColor, (maxRight - brRt) / maxRight);
737  var downRightColor = Color32.Lerp(tempRightColor, toColor, (maxRight - brRb) / maxRight);
738 
739  DrawSector(vh, roundLt, brLt, color, upLeftColor, 270, 360, 1, isYAxis, smoothness);
740  DrawSector(vh, roundRt, brRt, upRightColor, toColor, 0, 90, 1, isYAxis, smoothness);
741  DrawSector(vh, roundRb, brRb, downRightColor, toColor, 90, 180, 1, isYAxis, smoothness);
742  DrawSector(vh, roundLb, brLb, color, downLeftColor, 180, 270, 1, isYAxis, smoothness);
743 
744  DrawQuadrilateral(vh, lbIn, ltIn, ltInRight, lbInRight, color, tempLeftColor);
745  DrawQuadrilateral(vh, lbIn2, roundLb, roundLbRight, lbIn2Right, downLeftColor,
746  roundLbRight.x == roundRb.x ? downRightColor : tempLeftColor);
747  DrawQuadrilateral(vh, roundLt, ltIn2, ltIn2Right, roundLtRight, upLeftColor,
748  ltIn2Right.x == roundRt.x ? upRightColor : tempLeftColor);
749 
750  DrawQuadrilateral(vh, rbInLeft, rtIn2Left, rtIn2, rbIn, tempRightColor, toColor);
751  DrawQuadrilateral(vh, roundRtLeft, rtInLeft, rtIn, roundRt,
752  roundRtLeft.x == roundLt.x ? upLeftColor : tempRightColor, upRightColor);
753  DrawQuadrilateral(vh, rbIn2Left, roundRbLeft, roundRb, rbIn2,
754  rbIn2Left.x == roundLb.x ? downLeftColor : tempRightColor, downRightColor);
755 
756  var clt = new Vector3(center.x - halfWid + maxLeft, center.y + halfHig);
757  var crt = new Vector3(center.x + halfWid - maxRight, center.y + halfHig);
758  var crb = new Vector3(center.x + halfWid - maxRight, center.y - halfHig);
759  var clb = new Vector3(center.x - halfWid + maxLeft, center.y - halfHig);
760  if (crt.x > clt.x)
761  {
762  DrawQuadrilateral(vh, clb, clt, crt, crb, tempLeftColor, tempRightColor);
763  }
764  }
765  }
766  else
767  {
768  var maxup = Mathf.Max(brLt, brRt);
769  var maxdown = Mathf.Max(brLb, brRb);
770  var clt = new Vector3(center.x - halfWid, center.y + halfHig - maxup);
771  var crt = new Vector3(center.x + halfWid, center.y + halfHig - maxup);
772  var crb = new Vector3(center.x + halfWid, center.y - halfHig + maxdown);
773  var clb = new Vector3(center.x - halfWid, center.y - halfHig + maxdown);
774  var lbIn2Up = lbIn2 + maxdown * Vector3.up;
775  var rbIn2Up = rbIn2 + maxdown * Vector3.up;
776  var rtInDown = rtIn + maxup * Vector3.down;
777  var ltIn2Down = ltIn2 + maxup * Vector3.down;
778 
779  var roundLtDown = roundLt + (maxup - brLt) * Vector3.down;
780  var ltInDown = ltIn + (maxup - brLt) * Vector3.down;
781  if (roundLtDown.y < roundLb.y) roundLtDown.y = roundLb.y;
782  if (ltInDown.y < roundLb.y) ltInDown.y = roundLb.y;
783 
784  var rtIn2Down = rtIn2 + (maxup - brRt) * Vector3.down;
785  var roundRtDown = roundRt + (maxup - brRt) * Vector3.down;
786  if (rtIn2Down.y < roundRb.y) rtIn2Down.y = roundRb.y;
787  if (roundRtDown.y < roundRb.y) roundRtDown.y = roundRb.y;
788 
789  var lbInUp = lbIn + (maxdown - brLb) * Vector3.up;
790  var roundLbUp = roundLb + (maxdown - brLb) * Vector3.up;
791  if (lbInUp.y > roundLt.y) lbInUp.y = roundLt.y;
792  if (roundLbUp.y > roundLt.y) roundLbUp.y = roundLt.y;
793 
794  var roundRbUp = roundRb + (maxdown - brRb) * Vector3.up;
795  var rbInUp = rbIn + (maxdown - brRb) * Vector3.up;
796  if (roundRbUp.y > roundRt.y) roundRbUp.y = roundRt.y;
797  if (rbInUp.y > roundRt.y) rbInUp.y = roundRt.y;
798 
799  if (!isGradient)
800  {
801  DrawSector(vh, roundLt, brLt, toColor, toColor, 270, 360, 1, isYAxis, smoothness);
802  DrawSector(vh, roundRt, brRt, toColor, toColor, 0, 90, 1, isYAxis, smoothness);
803  DrawSector(vh, roundRb, brRb, color, color, 90, 180, 1, isYAxis, smoothness);
804  DrawSector(vh, roundLb, brLb, color, color, 180, 270, 1, isYAxis, smoothness);
805 
806  DrawQuadrilateral(vh, ltIn2, rtIn, rtInDown, ltIn2Down, toColor, toColor);
807  DrawQuadrilateral(vh, ltIn, roundLt, roundLtDown, ltInDown, toColor, toColor);
808  DrawQuadrilateral(vh, roundRt, rtIn2, rtIn2Down, roundRtDown, toColor, toColor);
809 
810  DrawQuadrilateral(vh, lbIn2, lbIn2Up, rbIn2Up, rbIn2, color, color);
811  DrawQuadrilateral(vh, lbIn, lbInUp, roundLbUp, roundLb, color, color);
812  DrawQuadrilateral(vh, roundRb, roundRbUp, rbInUp, rbIn, color, color);
813  if (clt.y > clb.y)
814  {
815  DrawQuadrilateral(vh, clt, crt, crb, clb, toColor, color);
816  }
817  }
818  else
819  {
820  var tempUpColor = Color32.Lerp(color, toColor, (rectHeight - maxup) / rectHeight);
821  var leftUpColor = Color32.Lerp(tempUpColor, toColor, (maxup - brLt) / maxup);
822  var rightUpColor = Color32.Lerp(tempUpColor, toColor, (maxup - brRt) / maxup);
823  var tempDownColor = Color32.Lerp(color, toColor, maxdown / rectHeight);
824  var leftDownColor = Color32.Lerp(color, tempDownColor, brLb / maxdown);
825  var rightDownColor = Color32.Lerp(color, tempDownColor, brRb / maxdown);
826 
827  DrawSector(vh, roundLt, brLt, leftUpColor, toColor, 270, 360, 1, isYAxis, smoothness);
828  DrawSector(vh, roundRt, brRt, rightUpColor, toColor, 0, 90, 1, isYAxis, smoothness);
829  DrawSector(vh, roundRb, brRb, rightDownColor, color, 90, 180, 1, isYAxis, smoothness);
830  DrawSector(vh, roundLb, brLb, leftDownColor, color, 180, 270, 1, isYAxis, smoothness);
831 
832  DrawQuadrilateral(vh, ltIn2, rtIn, rtInDown, ltIn2Down, toColor, tempUpColor);
833  DrawQuadrilateral(vh, ltIn, roundLt, roundLtDown, ltInDown, leftUpColor,
834  roundLtDown.y == roundLb.y ? leftDownColor : tempUpColor);
835  DrawQuadrilateral(vh, roundRt, rtIn2, rtIn2Down, roundRtDown, rightUpColor,
836  rtIn2Down.y == roundRb.y ? rightDownColor : tempUpColor);
837 
838  DrawQuadrilateral(vh, rbIn2, lbIn2, lbIn2Up, rbIn2Up, color, tempDownColor);
839  DrawQuadrilateral(vh, roundLb, lbIn, lbInUp, roundLbUp, leftDownColor,
840  lbInUp.y == roundLt.y ? leftUpColor : tempDownColor);
841  DrawQuadrilateral(vh, rbIn, roundRb, roundRbUp, rbInUp, rightDownColor,
842  roundRbUp.y == roundRt.y ? rightUpColor : tempDownColor);
843  if (clt.y > clb.y)
844  {
845  DrawQuadrilateral(vh, clt, crt, crb, clb, tempUpColor, tempDownColor);
846  }
847  }
848  }
849  }
850  else
851  {
852  DrawQuadrilateral(vh, lbIn, ltIn, rtIn, rbIn, toColor, color);
853  }
854  }
855 
868  public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight,
869  float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null,
870  bool horizontal = false, float smoothness = 1f, bool invertCorner = false)
871  {
872  DrawBorder(vh, center, rectWidth, rectHeight, borderWidth, color, s_ClearColor32, rotate,
873  cornerRadius, horizontal, smoothness, invertCorner);
874  }
875 
888  public static void DrawBorder(VertexHelper vh, Rect rect,
889  float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null,
890  bool horizontal = false, float smoothness = 1f, bool invertCorner = false)
891  {
892  DrawBorder(vh, rect.center, rect.width, rect.height, borderWidth, color, s_ClearColor32, rotate,
893  cornerRadius, horizontal, smoothness, invertCorner);
894  }
895 
911  public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight,
912  float borderWidth, Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null,
913  bool horizontal = false, float smoothness = 1f, bool invertCorner = false)
914  {
915  if (borderWidth == 0 || UGLHelper.IsClearColor(color)) return;
916  var halfWid = rectWidth / 2;
917  var halfHig = rectHeight / 2;
918  var lbIn = new Vector3(center.x - halfWid, center.y - halfHig);
919  var lbOt = new Vector3(center.x - halfWid - borderWidth, center.y - halfHig - borderWidth);
920  var ltIn = new Vector3(center.x - halfWid, center.y + halfHig);
921  var ltOt = new Vector3(center.x - halfWid - borderWidth, center.y + halfHig + borderWidth);
922  var rtIn = new Vector3(center.x + halfWid, center.y + halfHig);
923  var rtOt = new Vector3(center.x + halfWid + borderWidth, center.y + halfHig + borderWidth);
924  var rbIn = new Vector3(center.x + halfWid, center.y - halfHig);
925  var rbOt = new Vector3(center.x + halfWid + borderWidth, center.y - halfHig - borderWidth);
926  float brLt = 0, brRt = 0, brRb = 0, brLb = 0;
927  bool needRound = false;
928  InitCornerRadius(cornerRadius, rectWidth, rectHeight, horizontal, invertCorner, ref brLt, ref brRt, ref brRb,
929  ref brLb, ref needRound);
930  var tempCenter = Vector3.zero;
931  if (UGLHelper.IsClearColor(toColor))
932  {
933  toColor = color;
934  }
935  if (needRound)
936  {
937  var lbIn2 = lbIn;
938  var lbOt2 = lbOt;
939  var ltIn2 = ltIn;
940  var ltOt2 = ltOt;
941  var rtIn2 = rtIn;
942  var rtOt2 = rtOt;
943  var rbIn2 = rbIn;
944  var rbOt2 = rbOt;
945  if (brLt > 0)
946  {
947  tempCenter = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt);
948  DrawDoughnut(vh, tempCenter, brLt, brLt + borderWidth, horizontal ? color : toColor, s_ClearColor32,
949  270, 360, smoothness);
950  ltIn = tempCenter + brLt * Vector3.left;
951  ltOt = tempCenter + (brLt + borderWidth) * Vector3.left;
952  ltIn2 = tempCenter + brLt * Vector3.up;
953  ltOt2 = tempCenter + (brLt + borderWidth) * Vector3.up;
954  }
955  if (brRt > 0)
956  {
957  tempCenter = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt);
958  DrawDoughnut(vh, tempCenter, brRt, brRt + borderWidth, toColor, s_ClearColor32, 0, 90, smoothness);
959  rtIn = tempCenter + brRt * Vector3.up;
960  rtOt = tempCenter + (brRt + borderWidth) * Vector3.up;
961  rtIn2 = tempCenter + brRt * Vector3.right;
962  rtOt2 = tempCenter + (brRt + borderWidth) * Vector3.right;
963  }
964  if (brRb > 0)
965  {
966  tempCenter = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb);
967  DrawDoughnut(vh, tempCenter, brRb, brRb + borderWidth, horizontal ? toColor : color, s_ClearColor32,
968  90, 180, smoothness);
969  rbIn = tempCenter + brRb * Vector3.right;
970  rbOt = tempCenter + (brRb + borderWidth) * Vector3.right;
971  rbIn2 = tempCenter + brRb * Vector3.down;
972  rbOt2 = tempCenter + (brRb + borderWidth) * Vector3.down;
973  }
974  if (brLb > 0)
975  {
976  tempCenter = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb);
977  DrawDoughnut(vh, tempCenter, brLb, brLb + borderWidth, color, s_ClearColor32, 180, 270, smoothness);
978  lbIn = tempCenter + brLb * Vector3.left;
979  lbOt = tempCenter + (brLb + borderWidth) * Vector3.left;
980  lbIn2 = tempCenter + brLb * Vector3.down;
981  lbOt2 = tempCenter + (brLb + borderWidth) * Vector3.down;
982  }
983  if (horizontal)
984  {
985  DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, color);
986  DrawQuadrilateral(vh, ltIn2, ltOt2, rtOt, rtIn, color, toColor);
987  DrawQuadrilateral(vh, rtIn2, rtOt2, rbOt, rbIn, toColor, toColor);
988  DrawQuadrilateral(vh, rbIn2, rbOt2, lbOt2, lbIn2, toColor, color);
989  }
990  else
991  {
992  DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, toColor);
993  DrawQuadrilateral(vh, ltIn2, ltOt2, rtOt, rtIn, toColor, toColor);
994  DrawQuadrilateral(vh, rtIn2, rtOt2, rbOt, rbIn, toColor, color);
995  DrawQuadrilateral(vh, rbIn2, rbOt2, lbOt2, lbIn2, color, color);
996  }
997  }
998  else
999  {
1000  if (rotate > 0)
1001  {
1002  lbIn = UGLHelper.RotateRound(lbIn, center, Vector3.forward, rotate);
1003  lbOt = UGLHelper.RotateRound(lbOt, center, Vector3.forward, rotate);
1004  ltIn = UGLHelper.RotateRound(ltIn, center, Vector3.forward, rotate);
1005  ltOt = UGLHelper.RotateRound(ltOt, center, Vector3.forward, rotate);
1006  rtIn = UGLHelper.RotateRound(rtIn, center, Vector3.forward, rotate);
1007  rtOt = UGLHelper.RotateRound(rtOt, center, Vector3.forward, rotate);
1008  rbIn = UGLHelper.RotateRound(rbIn, center, Vector3.forward, rotate);
1009  rbOt = UGLHelper.RotateRound(rbOt, center, Vector3.forward, rotate);
1010  }
1011  if (horizontal)
1012  {
1013  DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, color);
1014  DrawQuadrilateral(vh, ltIn, ltOt, rtOt, rtIn, color, toColor);
1015  DrawQuadrilateral(vh, rtIn, rtOt, rbOt, rbIn, toColor, toColor);
1016  DrawQuadrilateral(vh, rbIn, rbOt, lbOt, lbIn, toColor, color);
1017  }
1018  else
1019  {
1020  DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, toColor);
1021  DrawQuadrilateral(vh, ltIn, ltOt, rtOt, rtIn, toColor, toColor);
1022  DrawQuadrilateral(vh, rtIn, rtOt, rbOt, rbIn, toColor, color);
1023  DrawQuadrilateral(vh, rbIn, rbOt, lbOt, lbIn, color, color);
1024  }
1025  }
1026  }
1027 
1028  public static void DrawTriangle(VertexHelper vh, Vector3 p1,
1029  Vector3 p2, Vector3 p3, Color32 color)
1030  {
1031  DrawTriangle(vh, p1, p2, p3, color, color, color);
1032  }
1033 
1034  public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color)
1035  {
1036  DrawTriangle(vh, pos, size, color, color);
1037  }
1038 
1039  public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color, Color32 toColor)
1040  {
1041  var x = size * Mathf.Cos(30 * Mathf.PI / 180);
1042  var y = size * Mathf.Sin(30 * Mathf.PI / 180);
1043  var p1 = new Vector2(pos.x - x, pos.y - y);
1044  var p2 = new Vector2(pos.x, pos.y + size);
1045  var p3 = new Vector2(pos.x + x, pos.y - y);
1046  DrawTriangle(vh, p1, p2, p3, color, toColor, color);
1047  }
1048 
1049  public static void DrawTriangle(VertexHelper vh, Vector3 p1,
1050  Vector3 p2, Vector3 p3, Color32 color, Color32 color2, Color32 color3)
1051  {
1052  UIVertex v1 = new UIVertex();
1053  v1.position = p1;
1054  v1.color = color;
1055  v1.uv0 = s_ZeroVector2;
1056  UIVertex v2 = new UIVertex();
1057  v2.position = p2;
1058  v2.color = color2;
1059  v2.uv0 = s_ZeroVector2;
1060  UIVertex v3 = new UIVertex();
1061  v3.position = p3;
1062  v3.color = color3;
1063  v3.uv0 = s_ZeroVector2;
1064  int startIndex = vh.currentVertCount;
1065  vh.AddVert(v1);
1066  vh.AddVert(v2);
1067  vh.AddVert(v3);
1068  vh.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
1069  }
1070 
1071  public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
1072  float smoothness = 2f)
1073  {
1074  DrawCricle(vh, center, radius, color, color, 0, s_ClearColor32, smoothness);
1075  }
1076 
1077  public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
1078  Color32 toColor, float smoothness = 2f)
1079  {
1080  DrawSector(vh, center, radius, color, toColor, 0, 360, 0, s_ClearColor32, smoothness);
1081  }
1082 
1083  public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
1084  Color32 toColor, float borderWidth, Color32 borderColor, float smoothness = 2f)
1085  {
1086  DrawSector(vh, center, radius, color, toColor, 0, 360, borderWidth, borderColor, smoothness);
1087  }
1088 
1089  public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color,
1090  float borderWidth, Color32 borderColor, float smoothness = 2f)
1091  {
1092  DrawCricle(vh, center, radius, color, color, borderWidth, borderColor, smoothness);
1093  }
1094 
1095  public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
1096  Color32 color, Color32 emptyColor, float smoothness = 2f)
1097  {
1098  DrawDoughnut(vh, center, radius - tickness, radius, color, color, emptyColor, 0, 360, 0, s_ClearColor32,
1099  0, smoothness);
1100  }
1101 
1102  public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
1103  Color32 color, Color32 emptyColor, float borderWidth, Color32 borderColor, float smoothness = 2f)
1104  {
1105  DrawDoughnut(vh, center, radius - tickness, radius, color, color, emptyColor, 0, 360, borderWidth,
1106  borderColor, 0, smoothness);
1107  }
1108 
1109  public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
1110  Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f)
1111  {
1112  DrawDoughnut(vh, center, radius - tickness, radius, color, toColor, emptyColor, 0, 360, 0,
1113  s_ClearColor32, 0, smoothness);
1114  }
1115 
1116  public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness,
1117  Color32 color, Color32 toColor, Color32 emptyColor, float borderWidth, Color32 borderColor,
1118  float smoothness = 2f)
1119  {
1120  DrawDoughnut(vh, center, radius - tickness, radius, color, toColor, emptyColor, 0, 360, borderWidth,
1121  borderColor, 0, smoothness);
1122  }
1123 
1124  public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color,
1125  float startDegree, float toDegree, float smoothness = 2f)
1126  {
1127  DrawSector(vh, center, radius, color, color, startDegree, toDegree, 0, s_ClearColor32, smoothness);
1128  }
1129 
1130  public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor,
1131  float startDegree, float toDegree, int gradientType = 0, bool isYAxis = false, float smoothness = 2f)
1132  {
1133  DrawSector(vh, center, radius, color, toColor, startDegree, toDegree, 0, s_ClearColor32, 0, smoothness,
1134  gradientType, isYAxis);
1135  }
1136 
1137  public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color,
1138  float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
1139  {
1140  DrawSector(vh, center, radius, color, color, startDegree, toDegree, borderWidth, borderColor, smoothness);
1141  }
1142 
1143  public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor,
1144  float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
1145  {
1146  DrawSector(vh, center, radius, color, toColor, startDegree, toDegree, borderWidth, borderColor, 0, smoothness);
1147  }
1148 
1165  public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor,
1166  float startDegree, float toDegree, float borderWidth, Color32 borderColor, float space,
1167  float smoothness, int gradientType = 0, bool isYAxis = false)
1168  {
1169  if (radius == 0) return;
1170  if (space > 0 && Mathf.Abs(toDegree - startDegree) >= 360) space = 0;
1171  radius -= borderWidth;
1172  smoothness = (smoothness < 0 ? 2f : smoothness);
1173  int segments = (int)((2 * Mathf.PI * radius) * (Mathf.Abs(toDegree - startDegree) / 360) / smoothness);
1174  if (segments < 1) segments = 1;
1175  float startAngle = startDegree * Mathf.Deg2Rad;
1176  float toAngle = toDegree * Mathf.Deg2Rad;
1177  float realStartAngle = startAngle;
1178  float realToAngle = toAngle;
1179  float halfAngle = (toAngle - startAngle) / 2;
1180  float borderAngle = 0;
1181  float spaceAngle = 0;
1182 
1183  var p2 = center + radius * UGLHelper.GetDire(startAngle);
1184  var p3 = Vector3.zero;
1185  var p4 = Vector3.zero;
1186  var spaceCenter = center;
1187  var realCenter = center;
1188  var lastP4 = center;
1189  var lastColor = color;
1190  var needBorder = borderWidth != 0;
1191  var needSpace = space != 0;
1192  var borderLineWidth = needSpace ? borderWidth : borderWidth / 2;
1193  var lastPos = Vector3.zero;
1194  var middleDire = UGLHelper.GetDire(startAngle + halfAngle);
1195  if (needBorder || needSpace)
1196  {
1197  float spaceDiff = 0f;
1198  float borderDiff = 0f;
1199  if (needSpace)
1200  {
1201  spaceDiff = space / Mathf.Sin(halfAngle);
1202  spaceCenter = center + spaceDiff * middleDire;
1203  realCenter = spaceCenter;
1204  spaceAngle = 2 * Mathf.Asin(space / (2 * radius));
1205  realStartAngle = startAngle + spaceAngle;
1206  realToAngle = toAngle - spaceAngle;
1207  if (realToAngle < realStartAngle) realToAngle = realStartAngle;
1208  p2 = UGLHelper.GetPos(center, radius, realStartAngle);
1209  }
1210  if (needBorder)
1211  {
1212  borderDiff = borderLineWidth / Mathf.Sin(halfAngle);
1213  realCenter += borderDiff * middleDire;
1214  borderAngle = 2 * Mathf.Asin(borderLineWidth / (2 * radius));
1215  realStartAngle = realStartAngle + borderAngle;
1216  realToAngle = realToAngle - borderAngle;
1217  if (realToAngle < realStartAngle)
1218  {
1219  realToAngle = realStartAngle;
1220  p2 = UGLHelper.GetPos(center, radius, realStartAngle);
1221  }
1222  else
1223  {
1224  var borderX1 = UGLHelper.GetPos(center, radius, realStartAngle);
1225  DrawQuadrilateral(vh, realCenter, spaceCenter, p2, borderX1, borderColor);
1226  p2 = borderX1;
1227 
1228  var borderX2 = UGLHelper.GetPos(center, radius, realToAngle);
1229  var pEnd = UGLHelper.GetPos(center, radius, toAngle - spaceAngle);
1230  DrawQuadrilateral(vh, realCenter, borderX2, pEnd, spaceCenter, borderColor);
1231  }
1232  }
1233  }
1234  float segmentAngle = (realToAngle - realStartAngle) / segments;
1235  bool isLeft = startDegree >= 180;
1236  for (int i = 0; i <= segments; i++)
1237  {
1238  float currAngle = realStartAngle + i * segmentAngle;
1239  p3 = center + radius * UGLHelper.GetDire(currAngle);
1240  if (gradientType == 1)
1241  {
1242  if (isYAxis)
1243  {
1244  p4 = new Vector3(p3.x, realCenter.y);
1245  var dist = p4.x - realCenter.x;
1246  var tcolor = Color32.Lerp(color, toColor, dist >= 0
1247  ? dist / radius
1248  : Mathf.Min(radius + dist, radius) / radius);
1249  if (isLeft && (i == segments || i == 0)) tcolor = toColor;
1250  DrawQuadrilateral(vh, lastP4, p2, p3, p4, lastColor, tcolor);
1251  lastP4 = p4;
1252  lastColor = tcolor;
1253  }
1254  else
1255  {
1256  p4 = new Vector3(realCenter.x, p3.y);
1257  var tcolor = Color32.Lerp(color, toColor, Mathf.Abs(p4.y - realCenter.y) / radius);
1258  DrawQuadrilateral(vh, lastP4, p2, p3, p4, lastColor, tcolor);
1259  lastP4 = p4;
1260  lastColor = tcolor;
1261  }
1262  }
1263  else if (gradientType == 2)
1264  {
1265  var tcolor = Color32.Lerp(color, toColor, i / segments);
1266  DrawQuadrilateral(vh, realCenter, p2, p3, realCenter, lastColor, tcolor);
1267  lastColor = tcolor;
1268  }
1269  else
1270  {
1271  DrawTriangle(vh, realCenter, p2, p3, toColor, color, color);
1272  }
1273  p2 = p3;
1274 
1275  }
1276  if (needBorder || needSpace)
1277  {
1278  if (realToAngle > realStartAngle)
1279  {
1280  var borderX2 = center + radius * UGLHelper.GetDire(realToAngle);
1281  DrawTriangle(vh, realCenter, p2, borderX2, toColor, color, color);
1282  if (needBorder)
1283  {
1284  var realStartDegree = (realStartAngle - borderAngle) * Mathf.Rad2Deg;
1285  var realToDegree = (realToAngle + borderAngle) * Mathf.Rad2Deg;
1286  DrawDoughnut(vh, center, radius, radius + borderWidth, borderColor, s_ClearColor32,
1287  realStartDegree, realToDegree, smoothness);
1288  }
1289  }
1290  }
1291  }
1292 
1293  public static void DrawRoundCap(VertexHelper vh, Vector3 center, float width, float radius, float angle,
1294  bool clockwise, Color32 color, bool end)
1295  {
1296  var px = Mathf.Sin(angle * Mathf.Deg2Rad) * radius;
1297  var py = Mathf.Cos(angle * Mathf.Deg2Rad) * radius;
1298  var pos = new Vector3(px, py) + center;
1299  if (end)
1300  {
1301  if (clockwise)
1302  DrawSector(vh, pos, width, color, angle, angle + 180, 0, s_ClearColor32);
1303  else
1304  DrawSector(vh, pos, width, color, angle, angle - 180, 0, s_ClearColor32);
1305  }
1306  else
1307  {
1308  if (clockwise)
1309  DrawSector(vh, pos, width, color, angle + 180, angle + 360, 0, s_ClearColor32);
1310  else
1311  DrawSector(vh, pos, width, color, angle - 180, angle - 360, 0, s_ClearColor32);
1312  }
1313  }
1314 
1315  public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
1316  Color32 color, Color32 emptyColor, float smoothness = 2f)
1317  {
1318  DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, 0, 360, 0,
1319  s_ClearColor32, 0, smoothness);
1320  }
1321 
1322  public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
1323  Color32 color, Color32 emptyColor, float startDegree,
1324  float toDegree, float smoothness = 1f)
1325  {
1326  DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree,
1327  0, s_ClearColor32, 0, smoothness);
1328  }
1329 
1330  public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
1331  Color32 color, Color32 emptyColor, float startDegree,
1332  float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f)
1333  {
1334  DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree,
1335  borderWidth, borderColor, 0, smoothness);
1336  }
1337 
1338  public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
1339  Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f)
1340  {
1341  DrawDoughnut(vh, center, insideRadius, outsideRadius, color, toColor, emptyColor, 0, 360, 0,
1342  s_ClearColor32, 0, smoothness);
1343  }
1344 
1345  public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius,
1346  Color32 color, Color32 toColor, Color32 emptyColor, float startDegree, float toDegree, float borderWidth,
1347  Color32 borderColor, float space, float smoothness, bool roundCap = false, bool clockwise = true)
1348  {
1349  if (toDegree - startDegree == 0) return;
1350  if (space > 0 && Mathf.Abs(toDegree - startDegree) >= 360) space = 0;
1351  if (insideRadius <= 0)
1352  {
1353  DrawSector(vh, center, outsideRadius, color, toColor, startDegree, toDegree, borderWidth, borderColor,
1354  space, smoothness);
1355  return;
1356  }
1357  outsideRadius -= borderWidth;
1358  insideRadius += borderWidth;
1359  smoothness = smoothness < 0 ? 2f : smoothness;
1360  Vector3 p1, p2, p3, p4, e1, e2;
1361  var needBorder = borderWidth != 0;
1362  var needSpace = space != 0;
1363  var diffAngle = Mathf.Abs(toDegree - startDegree) * Mathf.Deg2Rad;
1364 
1365  int segments = (int)((2 * Mathf.PI * outsideRadius) * (diffAngle * Mathf.Rad2Deg / 360) / smoothness);
1366  if (segments < 1) segments = 1;
1367  float startAngle = startDegree * Mathf.Deg2Rad;
1368  float toAngle = toDegree * Mathf.Deg2Rad;
1369 
1370  float realStartOutAngle = startAngle;
1371  float realToOutAngle = toAngle;
1372  float realStartInAngle = startAngle;
1373  float realToInAngle = toAngle;
1374  float halfAngle = (toAngle - startAngle) / 2;
1375  float borderAngle = 0, borderInAngle = 0, borderHalfAngle = 0;
1376  float spaceAngle = 0, spaceInAngle = 0, spaceHalfAngle = 0;
1377 
1378  var spaceCenter = center;
1379  var realCenter = center;
1380  var startDire = new Vector3(Mathf.Sin(startAngle), Mathf.Cos(startAngle)).normalized;
1381  var toDire = new Vector3(Mathf.Sin(toAngle), Mathf.Cos(toAngle)).normalized;
1382  var middleDire = new Vector3(Mathf.Sin(startAngle + halfAngle), Mathf.Cos(startAngle + halfAngle)).normalized;
1383  p1 = center + insideRadius * startDire;
1384  p2 = center + outsideRadius * startDire;
1385  e1 = center + insideRadius * toDire;
1386  e2 = center + outsideRadius * toDire;
1387  if (roundCap)
1388  {
1389  var roundRadius = (outsideRadius - insideRadius) / 2;
1390  var roundAngleRadius = insideRadius + roundRadius;
1391  var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius);
1392  if (diffAngle < 2 * roundAngle)
1393  {
1394  roundCap = false;
1395  }
1396  }
1397  if (needBorder || needSpace)
1398  {
1399  if (needSpace)
1400  {
1401  var spaceDiff = space / Mathf.Sin(halfAngle);
1402  spaceCenter = center + Mathf.Abs(spaceDiff) * middleDire;
1403  realCenter = spaceCenter;
1404  spaceAngle = 2 * Mathf.Asin(space / (2 * outsideRadius));
1405  spaceInAngle = 2 * Mathf.Asin(space / (2 * insideRadius));
1406  spaceHalfAngle = 2 * Mathf.Asin(space / (2 * (insideRadius + (outsideRadius - insideRadius) / 2)));
1407  if (clockwise)
1408  {
1409  p1 = UGLHelper.GetPos(center, insideRadius, startAngle + spaceInAngle, false);
1410  e1 = UGLHelper.GetPos(center, insideRadius, toAngle - spaceInAngle, false);
1411  realStartOutAngle = startAngle + spaceAngle;
1412  realToOutAngle = toAngle - spaceAngle;
1413  realStartInAngle = startAngle + spaceInAngle;
1414  realToInAngle = toAngle - spaceInAngle;
1415  }
1416  else
1417  {
1418  p1 = UGLHelper.GetPos(center, insideRadius, startAngle - spaceInAngle, false);
1419  e1 = UGLHelper.GetPos(center, insideRadius, toAngle + spaceInAngle, false);
1420  realStartOutAngle = startAngle - spaceAngle;
1421  realToOutAngle = toAngle + spaceAngle;
1422  realStartInAngle = startAngle - spaceInAngle;
1423  realToOutAngle = toAngle + spaceInAngle;
1424  }
1425  p2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false);
1426  e2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false);
1427  }
1428  if (needBorder)
1429  {
1430  var borderDiff = borderWidth / Mathf.Sin(halfAngle);
1431  realCenter += Mathf.Abs(borderDiff) * middleDire;
1432  borderAngle = 2 * Mathf.Asin(borderWidth / (2 * outsideRadius));
1433  borderInAngle = 2 * Mathf.Asin(borderWidth / (2 * insideRadius));
1434  borderHalfAngle = 2 * Mathf.Asin(borderWidth / (2 * (insideRadius + (outsideRadius - insideRadius) / 2)));
1435  if (clockwise)
1436  {
1437  realStartOutAngle = realStartOutAngle + borderAngle;
1438  realToOutAngle = realToOutAngle - borderAngle;
1439  realStartInAngle = startAngle + spaceInAngle + borderInAngle;
1440  realToInAngle = toAngle - spaceInAngle - borderInAngle;
1441  var newp1 = UGLHelper.GetPos(center, insideRadius, startAngle + spaceInAngle + borderInAngle, false);
1442  var newp2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false);
1443  if (!roundCap) DrawQuadrilateral(vh, newp2, newp1, p1, p2, borderColor);
1444  p1 = newp1;
1445  p2 = newp2;
1446  if (toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle)
1447  {
1448  var newe1 = UGLHelper.GetPos(center, insideRadius, toAngle - spaceInAngle - borderInAngle, false);
1449  var newe2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false);
1450  if (!roundCap) DrawQuadrilateral(vh, newe2, e2, e1, newe1, borderColor);
1451  e1 = newe1;
1452  e2 = newe2;
1453  }
1454  }
1455  else
1456  {
1457  realStartOutAngle = realStartOutAngle - borderAngle;
1458  realToOutAngle = realToOutAngle + borderAngle;
1459  realStartInAngle = startAngle - spaceInAngle - borderInAngle;
1460  realToInAngle = toAngle + spaceInAngle + borderInAngle;
1461  var newp1 = UGLHelper.GetPos(center, insideRadius, startAngle - spaceInAngle - borderInAngle, false);
1462  var newp2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false);
1463  if (!roundCap) DrawQuadrilateral(vh, newp2, newp1, p1, p2, borderColor);
1464  p1 = newp1;
1465  p2 = newp2;
1466  if (toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle)
1467  {
1468  var newe1 = UGLHelper.GetPos(center, insideRadius, toAngle + spaceInAngle + borderInAngle, false);
1469  var newe2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false);
1470  if (!roundCap) DrawQuadrilateral(vh, newe2, e2, e1, newe1, borderColor);
1471  e1 = newe1;
1472  e2 = newe2;
1473  }
1474  }
1475  }
1476  }
1477  if (roundCap)
1478  {
1479  var roundRadius = (outsideRadius - insideRadius) / 2;
1480  var roundAngleRadius = insideRadius + roundRadius;
1481  var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius);
1482  if (clockwise)
1483  {
1484  realStartOutAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
1485  realStartInAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
1486  }
1487  else
1488  {
1489  realStartOutAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
1490  realStartInAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
1491  }
1492  var roundTotalDegree = realStartOutAngle * Mathf.Rad2Deg;
1493  var roundCenter = center + roundAngleRadius * UGLHelper.GetDire(realStartOutAngle);
1494  var sectorStartDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree;
1495  var sectorToDegree = clockwise ? roundTotalDegree + 360 : roundTotalDegree + 180;
1496  DrawSector(vh, roundCenter, roundRadius, color, sectorStartDegree, sectorToDegree, smoothness / 2);
1497  if (needBorder)
1498  {
1499  DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor,
1500  s_ClearColor32, sectorStartDegree, sectorToDegree, smoothness / 2);
1501  }
1502  p1 = UGLHelper.GetPos(center, insideRadius, realStartOutAngle);
1503  p2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle);
1504 
1505  if (clockwise)
1506  {
1507  realToOutAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
1508  realToInAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle;
1509  if (realToOutAngle < realStartOutAngle) realToOutAngle = realStartOutAngle;
1510  }
1511  else
1512  {
1513  realToOutAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
1514  realToInAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle;
1515  if (realToOutAngle > realStartOutAngle) realToOutAngle = realStartOutAngle;
1516  }
1517  roundTotalDegree = realToOutAngle * Mathf.Rad2Deg;
1518  roundCenter = center + roundAngleRadius * UGLHelper.GetDire(realToOutAngle);
1519  sectorStartDegree = clockwise ? roundTotalDegree : roundTotalDegree + 180;
1520  sectorToDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree + 360;
1521  DrawSector(vh, roundCenter, roundRadius, toColor, sectorStartDegree, sectorToDegree, smoothness / 2);
1522  if (needBorder)
1523  {
1524  DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor,
1525  s_ClearColor32, sectorStartDegree, sectorToDegree, smoothness / 2);
1526  }
1527  e1 = UGLHelper.GetPos(center, insideRadius, realToOutAngle);
1528  e2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle);
1529  }
1530  var segmentAngle = (realToInAngle - realStartInAngle) / segments;
1531  var isGradient = !UGLHelper.IsValueEqualsColor(color, toColor);
1532  for (int i = 0; i <= segments; i++)
1533  {
1534  float currAngle = realStartInAngle + i * segmentAngle;
1535  p3 = new Vector3(center.x + outsideRadius * Mathf.Sin(currAngle),
1536  center.y + outsideRadius * Mathf.Cos(currAngle));
1537  p4 = new Vector3(center.x + insideRadius * Mathf.Sin(currAngle),
1538  center.y + insideRadius * Mathf.Cos(currAngle));
1539  if (!UGLHelper.IsClearColor(emptyColor)) DrawTriangle(vh, center, p1, p4, emptyColor);
1540  if (isGradient)
1541  {
1542  var tcolor = Color32.Lerp(color, toColor, i * 1.0f / segments);
1543  DrawQuadrilateral(vh, p2, p3, p4, p1, tcolor, tcolor);
1544  }
1545  else
1546  {
1547  DrawQuadrilateral(vh, p2, p3, p4, p1, color, color);
1548  }
1549  p1 = p4;
1550  p2 = p3;
1551  }
1552  if (needBorder || needSpace || roundCap)
1553  {
1554  if (clockwise)
1555  {
1556  var isInAngleFixed = toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle;
1557  if (isInAngleFixed) DrawQuadrilateral(vh, p2, e2, e1, p1, color, toColor);
1558  else DrawTriangle(vh, p2, e2, p1, color, color, toColor);
1559  if (needBorder)
1560  {
1561  var realStartDegree = (realStartOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
1562  var realToDegree = (realToOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
1563  if (realToDegree < realStartOutAngle) realToDegree = realStartOutAngle;
1564  var inStartDegree = roundCap ? realStartDegree : (startAngle + spaceInAngle) * Mathf.Rad2Deg;
1565  var inToDegree = roundCap ? realToDegree : (toAngle - spaceInAngle) * Mathf.Rad2Deg;
1566  if (inToDegree < inStartDegree) inToDegree = inStartDegree;
1567  if (isInAngleFixed) DrawDoughnut(vh, center, insideRadius - borderWidth, insideRadius, borderColor,
1568  s_ClearColor32, inStartDegree, inToDegree, smoothness);
1569  DrawDoughnut(vh, center, outsideRadius, outsideRadius + borderWidth, borderColor, s_ClearColor32,
1570  realStartDegree, realToDegree, smoothness);
1571  }
1572  }
1573  else
1574  {
1575  var isInAngleFixed = toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle;
1576  if (isInAngleFixed) DrawQuadrilateral(vh, p2, e2, e1, p1, color, toColor);
1577  else DrawTriangle(vh, p2, e2, p1, color, color, toColor);
1578  if (needBorder)
1579  {
1580  var realStartDegree = (realStartOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
1581  var realToDegree = (realToOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg;
1582  var inStartDegree = roundCap ? realStartDegree : (startAngle - spaceInAngle) * Mathf.Rad2Deg;
1583  var inToDegree = roundCap ? realToDegree : (toAngle + spaceInAngle) * Mathf.Rad2Deg;
1584  if (inToDegree > inStartDegree) inToDegree = inStartDegree;
1585  if (isInAngleFixed)
1586  {
1587  DrawDoughnut(vh, center, insideRadius - borderWidth, insideRadius, borderColor,
1588  s_ClearColor32, inStartDegree, inToDegree, smoothness);
1589  }
1590  DrawDoughnut(vh, center, outsideRadius, outsideRadius + borderWidth, borderColor,
1591  s_ClearColor32, realStartDegree, realToDegree, smoothness);
1592  }
1593  }
1594  }
1595  }
1596 
1607  public static void DrawCurves(VertexHelper vh, Vector3 sp, Vector3 ep, Vector3 cp1, Vector3 cp2,
1608  float lineWidth, Color32 lineColor, float smoothness)
1609  {
1610  var dist = Vector3.Distance(sp, ep);
1611  var segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness));
1612  UGLHelper.GetBezierList2(ref s_CurvesPosList, sp, ep, segment, cp1, cp2);
1613  if (s_CurvesPosList.Count > 1)
1614  {
1615  var start = s_CurvesPosList[0];
1616  var to = Vector3.zero;
1617  var dir = s_CurvesPosList[1] - start;
1618  var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth;
1619  var startUp = start - diff;
1620  var startDn = start + diff;
1621  for (int i = 1; i < s_CurvesPosList.Count; i++)
1622  {
1623  to = s_CurvesPosList[i];
1624  diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth;
1625  var toUp = to - diff;
1626  var toDn = to + diff;
1627  DrawQuadrilateral(vh, startUp, toUp, toDn, startDn, lineColor);
1628  startUp = toUp;
1629  startDn = toDn;
1630  start = to;
1631  }
1632  }
1633  }
1634  }
1635 }
XUGL
Definition: UGL.cs:12