private void BridgeFillLineLoops(VertexHelper vh, Color col, List <Vector2> innerVerts, List <Vector2> outerVerts, BoundRect br) { // Debug.Assert(outerVerts.Count == innerVerts.Count, "BridgeFillLineLoops: different size verts."); int vstart = vh.currentVertCount; // Add vertices UIVertex uivert = UIVertex.simpleVert; float bw = br.GetWidth(); float bh = br.GetHeight(); UIVertex[] uiv01 = new UIVertex[2]; for (int i = 0; i < outerVerts.Count; i++) { for (int j = 0; j < 2; j++) { var v = (j == 0)? innerVerts[i] : outerVerts[i]; float tx = (v.x - br.left) / bw; float ty = (v.y - br.bottom) / bh; uivert.position = new Vector2(v.x, v.y); uivert.uv0 = new Vector2(tx, ty); uivert.color = col; vh.AddVert(uivert); if (i == 0) { uiv01[j] = uivert; } } } vh.AddVert(uiv01[0]); vh.AddVert(uiv01[1]); // Add faces int i0 = 0 + vstart; int i1 = 1 + vstart; int vcount = outerVerts.Count * 2 + 2; for (int i = 2; i < vcount; i++) { int i2 = i + vstart; if ((i & 1) == 0) { vh.AddTriangle(i0, i1, i2); } else { vh.AddTriangle(i1, i0, i2); } i0 = i1; i1 = i2; } }
private List <Vector2> MakeCapsuleLineLoop(BoundRect br, float arcMax) { float capRadius = Mathf.Min(br.GetWidth(), br.GetHeight()) * 0.5f; int capDiv = Mathf.Max(4, (int)Mathf.Ceil(capRadius * Mathf.PI / arcMax)) & (~0x1); // Debug.Log("div:" + cornerDiv); float angle_offset; var capPivots = new Vector2[4]; if (br.GetAspectRatio() < 1.0f) { angle_offset = Mathf.PI * -0.5f; capPivots[0] = new Vector2((br.left + br.right) * 0.5f, br.top - capRadius); capPivots[1] = new Vector2((br.left + br.right) * 0.5f, br.bottom + capRadius); } else { angle_offset = 0.0f; capPivots[0] = new Vector2(br.right - capRadius, (br.top + br.bottom) * 0.5f); capPivots[1] = new Vector2(br.left + capRadius, (br.top + br.bottom) * 0.5f); } var ret = new List <Vector2>(capDiv * 2 + 2); for (int i = 0; i < 2; i++) { Vector2 cp = capPivots[i]; float base_angle = Mathf.PI * 2.0f * (float)i * 0.5f + angle_offset; for (int div = 0; div <= capDiv; div++) { float angle = (float)div / (float)capDiv * Mathf.PI + base_angle; var v = new Vector2( Mathf.Sin(angle) * capRadius + cp.x, Mathf.Cos(angle) * capRadius + cp.y ); ret.Add(v); } } // To make beaty fill mesh. for (int i = 0; i < capDiv / 2; i++) { var tmpv = ret[0]; ret.RemoveAt(0); ret.Add(tmpv); } return(ret); }
private void FillConvexLineLoop(VertexHelper vh, Color col, List <Vector2> verts, BoundRect br) { int vstart = vh.currentVertCount; // Add vertices UIVertex uivert = UIVertex.simpleVert; float bw = br.GetWidth(); float bh = br.GetHeight(); foreach (Vector2 v in verts) { float tx = (v.x - br.left) / bw; float ty = (v.y - br.bottom) / bh; uivert.position = new Vector2(v.x, v.y); uivert.uv0 = new Vector2(tx, ty); uivert.color = col; vh.AddVert(uivert); // iv++; } // Add faces int i0 = 0 + vstart; int i1 = 1 + vstart; int vcount = verts.Count; for (int i = 0; i < vcount - 2; i++) { int i2; if ((i & 1) == 0) { i2 = vcount - 1 - i / 2 + vstart; vh.AddTriangle(i0, i1, i2); } else { i2 = 2 + i / 2 + vstart; vh.AddTriangle(i1, i0, i2); } i0 = i1; i1 = i2; } }
private List <Vector2> MakeElipseLineLoop(BoundRect br, float arcMax) { // Ellipse parameters float a = br.GetWidth() * 0.5f; // x radius float b = br.GetHeight() * 0.5f; // y radius float h = ((a - b) * (a - b)) / ((a + b) * (a + b)); float c = Mathf.PI * (a + b) * (1.0f + 3.0f * h / (10.0f + Mathf.Sqrt(4.0f - 3.0f * h))); // Ramanujan's approximation. // Debug.Log("h:" + h + ", c:" + c); int DIV = Mathf.Max(8, (int)Mathf.Ceil(c / arcMax)) & (~0x1); var ret = new List <Vector2>(DIV); float cx = (br.left + br.right) * 0.5f; float cy = (br.bottom + br.top) * 0.5f; float angle_offset = (a < b) ? 0.0f : (Mathf.PI * 0.5f); for (int i = 0; i < DIV; i++) { float angle = (float)i / (float)DIV * Mathf.PI * 2.0f + angle_offset; ret.Add(new Vector2(Mathf.Sin(angle) * a + cx, Mathf.Cos(angle) * b + cy)); } return(ret); }
protected override void OnPopulateMesh(VertexHelper vh) { var rect = GetPixelAdjustedRect(); var shapebounds = new BoundRect( rect.yMax - margin.top, rect.xMax - margin.right, rect.yMin + margin.bottom, rect.xMin + margin.left ); if (shapebounds.GetWidth() < 0.0f || shapebounds.GetHeight() < 0.0f) { vh.Clear(); return; } // Vertices list is clock wise. List <Vector2> verts; switch (shapeType) { default: case ShapeType.Rectangle: verts = MakeRectangleLineLoop(shapebounds); break; case ShapeType.Ellipse: verts = MakeElipseLineLoop(shapebounds, maxArcLength); break; case ShapeType.Capsule: verts = MakeCapsuleLineLoop(shapebounds, maxArcLength); break; case ShapeType.RoundRect: verts = MakeRoundRectLineLoop(shapebounds, cornerRadius, maxArcLength); break; case ShapeType.TrimedRect: verts = MakeTrimedRectLineLoop(shapebounds, cornerRadius); break; } // var verts = MakeRectangleLineLoop(shapebounds); // var verts = MakeElipseLineLoop(shapebounds); // var verts = MakeCapsuleLineLoop(shapebounds); // var verts = MakeRoundRectLineLoop(shapebounds); RemoveDegenerateEdges(verts, 0.1f); vh.Clear(); if (borderWidth > 0.0f) { // Inset loop var insetverts = MakeInsetLineLoop(verts, borderWidth); // Create border BridgeFillLineLoops(vh, borderColor, insetverts, verts, shapebounds); // Fill shape FillConvexLineLoop(vh, color, insetverts, shapebounds); } else { // Fill shape FillConvexLineLoop(vh, color, verts, shapebounds); } }