using UnityEngine; namespace FairyGUI { /// /// /// public class FillMesh : IMeshFactory { /// /// /// public FillMethod method; /// /// /// public int origin; /// /// /// public float amount; /// /// /// public bool clockwise; public FillMesh() { clockwise = true; amount = 1; } public void OnPopulateMesh(VertexBuffer vb) { float amount = Mathf.Clamp01(this.amount); switch (method) { case FillMethod.Horizontal: FillHorizontal(vb, vb.contentRect, origin, amount); break; case FillMethod.Vertical: FillVertical(vb, vb.contentRect, origin, amount); break; case FillMethod.Radial90: FillRadial90(vb, vb.contentRect, (Origin90)origin, amount, clockwise); break; case FillMethod.Radial180: FillRadial180(vb, vb.contentRect, (Origin180)origin, amount, clockwise); break; case FillMethod.Radial360: FillRadial360(vb, vb.contentRect, (Origin360)origin, amount, clockwise); break; } } static void FillHorizontal(VertexBuffer vb, Rect vertRect, int origin, float amount) { float a = vertRect.width * amount; if ((OriginHorizontal)origin == OriginHorizontal.Right || (OriginVertical)origin == OriginVertical.Bottom) vertRect.x += (vertRect.width - a); vertRect.width = a; vb.AddQuad(vertRect); vb.AddTriangles(); } static void FillVertical(VertexBuffer vb, Rect vertRect, int origin, float amount) { float a = vertRect.height * amount; if ((OriginHorizontal)origin == OriginHorizontal.Right || (OriginVertical)origin == OriginVertical.Bottom) vertRect.y += (vertRect.height - a); vertRect.height = a; vb.AddQuad(vertRect); vb.AddTriangles(); } //4 vertex static void FillRadial90(VertexBuffer vb, Rect vertRect, Origin90 origin, float amount, bool clockwise) { bool flipX = origin == Origin90.TopRight || origin == Origin90.BottomRight; bool flipY = origin == Origin90.BottomLeft || origin == Origin90.BottomRight; if (flipX != flipY) clockwise = !clockwise; float ratio = clockwise ? amount : (1 - amount); float tan = Mathf.Tan(Mathf.PI * 0.5f * ratio); bool thresold = false; if (ratio != 1) thresold = (vertRect.height / vertRect.width - tan) > 0; if (!clockwise) thresold = !thresold; float x = vertRect.x + (ratio == 0 ? float.MaxValue : (vertRect.height / tan)); float y = vertRect.y + (ratio == 1 ? float.MaxValue : (vertRect.width * tan)); float x2 = x; float y2 = y; if (flipX) x2 = vertRect.width - x; if (flipY) y2 = vertRect.height - y; float xMin = flipX ? (vertRect.width - vertRect.x) : vertRect.xMin; float yMin = flipY ? (vertRect.height - vertRect.y) : vertRect.yMin; float xMax = flipX ? -vertRect.xMin : vertRect.xMax; float yMax = flipY ? -vertRect.yMin : vertRect.yMax; vb.AddVert(new Vector3(xMin, yMin, 0)); if (clockwise) vb.AddVert(new Vector3(xMax, yMin, 0)); if (y > vertRect.yMax) { if (thresold) vb.AddVert(new Vector3(x2, yMax, 0)); else vb.AddVert(new Vector3(xMax, yMax, 0)); } else vb.AddVert(new Vector3(xMax, y2, 0)); if (x > vertRect.xMax) { if (thresold) vb.AddVert(new Vector3(xMax, y2, 0)); else vb.AddVert(new Vector3(xMax, yMax, 0)); } else vb.AddVert(new Vector3(x2, yMax, 0)); if (!clockwise) vb.AddVert(new Vector3(xMin, yMax, 0)); if (flipX == flipY) { vb.AddTriangle(0, 1, 2); vb.AddTriangle(0, 2, 3); } else { vb.AddTriangle(2, 1, 0); vb.AddTriangle(3, 2, 0); } } //8 vertex static void FillRadial180(VertexBuffer vb, Rect 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 Rect(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 Rect(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 Rect(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 Rect(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; } } //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; } } } }