RoundedRectMesh.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using UnityEngine;
  2. namespace FairyGUI
  3. {
  4. public class RoundedRectMesh : IMeshFactory, IHitTest
  5. {
  6. /// <summary>
  7. ///
  8. /// </summary>
  9. public Rect? drawRect;
  10. /// <summary>
  11. ///
  12. /// </summary>
  13. public float lineWidth;
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. public Color32 lineColor;
  18. /// <summary>
  19. ///
  20. /// </summary>
  21. public Color32? fillColor;
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. public float topLeftRadius;
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. public float topRightRadius;
  30. /// <summary>
  31. ///
  32. /// </summary>
  33. public float bottomLeftRadius;
  34. /// <summary>
  35. ///
  36. /// </summary>
  37. public float bottomRightRadius;
  38. public RoundedRectMesh()
  39. {
  40. lineColor = Color.black;
  41. }
  42. public void OnPopulateMesh(VertexBuffer vb)
  43. {
  44. Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect;
  45. Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor;
  46. float radiusX = rect.width / 2;
  47. float radiusY = rect.height / 2;
  48. float cornerMaxRadius = Mathf.Min(radiusX, radiusY);
  49. float centerX = radiusX + rect.x;
  50. float centerY = radiusY + rect.y;
  51. vb.AddVert(new Vector3(centerX, centerY, 0), color);
  52. int cnt = vb.currentVertCount;
  53. for (int i = 0; i < 4; i++)
  54. {
  55. float radius = 0;
  56. switch (i)
  57. {
  58. case 0:
  59. radius = bottomRightRadius;
  60. break;
  61. case 1:
  62. radius = bottomLeftRadius;
  63. break;
  64. case 2:
  65. radius = topLeftRadius;
  66. break;
  67. case 3:
  68. radius = topRightRadius;
  69. break;
  70. }
  71. radius = Mathf.Min(cornerMaxRadius, radius);
  72. float offsetX = rect.x;
  73. float offsetY = rect.y;
  74. if (i == 0 || i == 3)
  75. offsetX = rect.xMax - radius * 2;
  76. if (i == 0 || i == 1)
  77. offsetY = rect.yMax - radius * 2;
  78. if (radius != 0)
  79. {
  80. int partNumSides = Mathf.Max(1, Mathf.CeilToInt(Mathf.PI * radius / 8)) + 1;
  81. float angleDelta = Mathf.PI / 2 / partNumSides;
  82. float angle = Mathf.PI / 2 * i;
  83. float startAngle = angle;
  84. for (int j = 1; j <= partNumSides; j++)
  85. {
  86. if (j == partNumSides) //消除精度误差带来的不对齐
  87. angle = startAngle + Mathf.PI / 2;
  88. Vector3 v1 = new Vector3(offsetX + Mathf.Cos(angle) * (radius - lineWidth) + radius,
  89. offsetY + Mathf.Sin(angle) * (radius - lineWidth) + radius, 0);
  90. vb.AddVert(v1, color);
  91. if (lineWidth != 0)
  92. {
  93. vb.AddVert(v1, lineColor);
  94. vb.AddVert(new Vector3(offsetX + Mathf.Cos(angle) * radius + radius,
  95. offsetY + Mathf.Sin(angle) * radius + radius, 0), lineColor);
  96. }
  97. angle += angleDelta;
  98. }
  99. }
  100. else
  101. {
  102. Vector3 v1 = new Vector3(offsetX, offsetY, 0);
  103. if (lineWidth != 0)
  104. {
  105. if (i == 0 || i == 3)
  106. offsetX -= lineWidth;
  107. else
  108. offsetX += lineWidth;
  109. if (i == 0 || i == 1)
  110. offsetY -= lineWidth;
  111. else
  112. offsetY += lineWidth;
  113. Vector3 v2 = new Vector3(offsetX, offsetY, 0);
  114. vb.AddVert(v2, color);
  115. vb.AddVert(v2, lineColor);
  116. vb.AddVert(v1, lineColor);
  117. }
  118. else
  119. vb.AddVert(v1, color);
  120. }
  121. }
  122. cnt = vb.currentVertCount - cnt;
  123. if (lineWidth > 0)
  124. {
  125. for (int i = 0; i < cnt; i += 3)
  126. {
  127. if (i != cnt - 3)
  128. {
  129. vb.AddTriangle(0, i + 1, i + 4);
  130. vb.AddTriangle(i + 5, i + 2, i + 3);
  131. vb.AddTriangle(i + 3, i + 6, i + 5);
  132. }
  133. else
  134. {
  135. vb.AddTriangle(0, i + 1, 1);
  136. vb.AddTriangle(2, i + 2, i + 3);
  137. vb.AddTriangle(i + 3, 3, 2);
  138. }
  139. }
  140. }
  141. else
  142. {
  143. for (int i = 0; i < cnt; i++)
  144. vb.AddTriangle(0, i + 1, (i == cnt - 1) ? 1 : i + 2);
  145. }
  146. }
  147. public bool HitTest(Rect contentRect, Vector2 point)
  148. {
  149. if (drawRect != null)
  150. return ((Rect)drawRect).Contains(point);
  151. else
  152. return contentRect.Contains(point);
  153. }
  154. }
  155. }