public void OnPopulateMesh(VertexBuffer vb) { Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect; Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor; float sectionStart = Mathf.Clamp(startDegree, 0, 360); float sectionEnd = Mathf.Clamp(endDegreee, 0, 360); bool clipped = sectionStart > 0 || sectionEnd < 360; sectionStart = sectionStart * Mathf.Deg2Rad; sectionEnd = sectionEnd * Mathf.Deg2Rad; Color32 centerColor2 = centerColor == null ? color : (Color32)centerColor; float radiusX = rect.width / 2; float radiusY = rect.height / 2; int sides = Mathf.CeilToInt(Mathf.PI * (radiusX + radiusY) / 4); sides = Mathf.Clamp(sides, 40, 800); float angleDelta = 2 * Mathf.PI / sides; float angle = 0; float lineAngle = 0; if (lineWidth > 0 && clipped) { lineAngle = lineWidth / Mathf.Max(radiusX, radiusY); sectionStart += lineAngle; sectionEnd -= lineAngle; } int vpos = vb.currentVertCount; float centerX = rect.x + radiusX; float centerY = rect.y + radiusY; vb.AddVert(new Vector3(centerX, centerY, 0), centerColor2); for (int i = 0; i < sides; i++) { if (angle < sectionStart) { angle = sectionStart; } else if (angle > sectionEnd) { angle = sectionEnd; } Vector3 vec = new Vector3(Mathf.Cos(angle) * (radiusX - lineWidth) + centerX, Mathf.Sin(angle) * (radiusY - lineWidth) + centerY, 0); vb.AddVert(vec, color); if (lineWidth > 0) { vb.AddVert(vec, lineColor); vb.AddVert(new Vector3(Mathf.Cos(angle) * radiusX + centerX, Mathf.Sin(angle) * radiusY + centerY, 0), lineColor); } angle += angleDelta; } if (lineWidth > 0) { int cnt = sides * 3; for (int i = 0; i < cnt; i += 3) { if (i != cnt - 3) { vb.AddTriangle(0, i + 1, i + 4); vb.AddTriangle(i + 5, i + 2, i + 3); vb.AddTriangle(i + 3, i + 6, i + 5); } else if (!clipped) { vb.AddTriangle(0, i + 1, 1); vb.AddTriangle(2, i + 2, i + 3); vb.AddTriangle(i + 3, 3, 2); } else { vb.AddTriangle(0, i + 1, i + 1); vb.AddTriangle(i + 2, i + 2, i + 3); vb.AddTriangle(i + 3, i + 3, i + 2); } } } else { for (int i = 0; i < sides; i++) { if (i != sides - 1) { vb.AddTriangle(0, i + 1, i + 2); } else if (!clipped) { vb.AddTriangle(0, i + 1, 1); } else { vb.AddTriangle(0, i + 1, i + 1); } } } if (lineWidth > 0 && clipped) { //扇形内边缘的线条 vb.AddVert(new Vector3(radiusX, radiusY, 0), lineColor); float centerRadius = lineWidth * 0.5f; sectionStart -= lineAngle; angle = sectionStart + lineAngle * 0.5f + Mathf.PI * 0.5f; vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor); angle -= Mathf.PI; vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor); vb.AddVert(new Vector3(Mathf.Cos(sectionStart) * radiusX + radiusX, Mathf.Sin(sectionStart) * radiusY + radiusY, 0), lineColor); vb.AddVert(vb.GetPosition(vpos + 3), lineColor); sectionEnd += lineAngle; angle = sectionEnd - lineAngle * 0.5f + Mathf.PI * 0.5f; vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor); angle -= Mathf.PI; vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor); vb.AddVert(vb.GetPosition(vpos + sides * 3), lineColor); vb.AddVert(new Vector3(Mathf.Cos(sectionEnd) * radiusX + radiusX, Mathf.Sin(sectionEnd) * radiusY + radiusY, 0), lineColor); vb.AddTriangles(SECTOR_CENTER_TRIANGLES, sides * 3 + 1); } }
//12 vertex static void FillRadial360(VertexBuffer vb, Rect vertRect, Origin360 origin, float amount, bool clockwise) { switch (origin) { case Origin360.Top: if (amount < 0.5f) { vertRect.width /= 2; if (clockwise) { vertRect.x += vertRect.width; } FillRadial180(vb, vertRect, clockwise ? Origin180.Left : Origin180.Right, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-8); vb.AddQuad(new Rect(vec.x, vec.y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.width /= 2; if (!clockwise) { vertRect.x += vertRect.width; } FillRadial180(vb, vertRect, clockwise ? Origin180.Right : Origin180.Left, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.x += vertRect.width; } else { vertRect.x -= vertRect.width; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; case Origin360.Bottom: if (amount < 0.5f) { vertRect.width /= 2; if (!clockwise) { vertRect.x += vertRect.width; } FillRadial180(vb, vertRect, clockwise ? Origin180.Right : Origin180.Left, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-8); vb.AddQuad(new Rect(vec.x, vec.y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.width /= 2; if (clockwise) { vertRect.x += vertRect.width; } FillRadial180(vb, vertRect, clockwise ? Origin180.Left : Origin180.Right, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.x -= vertRect.width; } else { vertRect.x += vertRect.width; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; case Origin360.Left: if (amount < 0.5f) { vertRect.height /= 2; if (!clockwise) { vertRect.y += vertRect.height; } FillRadial180(vb, vertRect, clockwise ? Origin180.Bottom : Origin180.Top, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-8); vb.AddQuad(new Rect(vec.x, vec.y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.height /= 2; if (clockwise) { vertRect.y += vertRect.height; } FillRadial180(vb, vertRect, clockwise ? Origin180.Top : Origin180.Bottom, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.y -= vertRect.height; } else { vertRect.y += vertRect.height; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; case Origin360.Right: if (amount < 0.5f) { vertRect.height /= 2; if (clockwise) { vertRect.y += vertRect.height; } FillRadial180(vb, vertRect, clockwise ? Origin180.Top : Origin180.Bottom, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-8); vb.AddQuad(new Rect(vec.x, vec.y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.height /= 2; if (!clockwise) { vertRect.y += vertRect.height; } FillRadial180(vb, vertRect, clockwise ? Origin180.Bottom : Origin180.Top, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.y += vertRect.height; } else { vertRect.y -= vertRect.height; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; } }
//8 vertex static void FillRadial180(VertexBuffer vb, Rectangle vertRect, Origin180 origin, float amount, bool clockwise) { switch (origin) { case Origin180.Top: if (amount <= 0.5f) { vertRect.Width /= 2; if (clockwise) { vertRect.X += vertRect.Width; } FillRadial90(vb, vertRect, clockwise ? Origin90.TopLeft : Origin90.TopRight, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-4); vb.AddQuad(new Rectangle(vec.X, vec.Y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.Width /= 2; if (!clockwise) { vertRect.X += vertRect.Width; } FillRadial90(vb, vertRect, clockwise ? Origin90.TopRight : Origin90.TopLeft, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.X += vertRect.Width; } else { vertRect.X -= vertRect.Width; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; case Origin180.Bottom: if (amount <= 0.5f) { vertRect.Width /= 2; if (!clockwise) { vertRect.X += vertRect.Width; } FillRadial90(vb, vertRect, clockwise ? Origin90.BottomRight : Origin90.BottomLeft, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-4); vb.AddQuad(new Rectangle(vec.X, vec.Y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.Width /= 2; if (clockwise) { vertRect.X += vertRect.Width; } FillRadial90(vb, vertRect, clockwise ? Origin90.BottomLeft : Origin90.BottomRight, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.X -= vertRect.Width; } else { vertRect.X += vertRect.Width; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; case Origin180.Left: if (amount <= 0.5f) { vertRect.Height /= 2; if (!clockwise) { vertRect.Y += vertRect.Height; } FillRadial90(vb, vertRect, clockwise ? Origin90.BottomLeft : Origin90.TopLeft, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-4); vb.AddQuad(new Rectangle(vec.X, vec.Y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.Height /= 2; if (clockwise) { vertRect.Y += vertRect.Height; } FillRadial90(vb, vertRect, clockwise ? Origin90.TopLeft : Origin90.BottomLeft, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.Y -= vertRect.Height; } else { vertRect.Y += vertRect.Height; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; case Origin180.Right: if (amount <= 0.5f) { vertRect.Height /= 2; if (clockwise) { vertRect.Y += vertRect.Height; } FillRadial90(vb, vertRect, clockwise ? Origin90.TopRight : Origin90.BottomRight, amount / 0.5f, clockwise); Vector3 vec = vb.GetPosition(-4); vb.AddQuad(new Rectangle(vec.X, vec.Y, 0, 0)); vb.AddTriangles(-4); } else { vertRect.Height /= 2; if (!clockwise) { vertRect.Y += vertRect.Height; } FillRadial90(vb, vertRect, clockwise ? Origin90.BottomRight : Origin90.TopRight, (amount - 0.5f) / 0.5f, clockwise); if (clockwise) { vertRect.Y += vertRect.Height; } else { vertRect.Y -= vertRect.Height; } vb.AddQuad(vertRect); vb.AddTriangles(-4); } break; } }