//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; } }
//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); } }
void UpdateMeshNow() { _meshDirty = false; if (_texture == null || _meshFactory == null) { if (mesh.vertexCount > 0) { mesh.Clear(); if (meshModifier != null) { meshModifier(); } } return; } VertexBuffer vb = VertexBuffer.Begin(); vb.contentRect = _contentRect; vb.uvRect = _texture.uvRect; vb.vertexColor = _color; _meshFactory.OnPopulateMesh(vb); int vertCount = vb.currentVertCount; if (vertCount == 0) { if (mesh.vertexCount > 0) { mesh.Clear(); if (meshModifier != null) { meshModifier(); } } vb.End(); return; } if (_flip != FlipType.None) { bool h = _flip == FlipType.Horizontal || _flip == FlipType.Both; bool v = _flip == FlipType.Vertical || _flip == FlipType.Both; float xMax = _contentRect.xMax; float yMax = _contentRect.yMax; for (int i = 0; i < vertCount; i++) { Vector3 vec = vb.vertices[i]; if (h) { vec.x = xMax - (vec.x - _contentRect.x); } if (v) { vec.y = -(yMax - (-vec.y - _contentRect.y)); } vb.vertices[i] = vec; } if (!(h && v)) { vb.triangles.Reverse(); } } if (_texture.rotated) { float xMin = _texture.uvRect.xMin; float yMin = _texture.uvRect.yMin; float yMax = _texture.uvRect.yMax; float tmp; for (int i = 0; i < vertCount; i++) { Vector2 vec = vb.uv0[i]; tmp = vec.y; vec.y = yMin + vec.x - xMin; vec.x = xMin + yMax - tmp; vb.uv0[i] = vec; } } hasAlphaBackup = vb._alphaInVertexColor; if (hasAlphaBackup) { if (_alphaBackup == null) { _alphaBackup = new List <byte>(); } else { _alphaBackup.Clear(); } for (int i = 0; i < vertCount; i++) { Color32 col = vb.colors[i]; _alphaBackup.Add(col.a); col.a = (byte)(col.a * _alpha); vb.colors[i] = col; } } else if (_alpha != 1) { for (int i = 0; i < vertCount; i++) { Color32 col = vb.colors[i]; col.a = (byte)(col.a * _alpha); vb.colors[i] = col; } } if (_vertexMatrix != null) { Matrix4x4 mm = (Matrix4x4)_vertexMatrix; Vector3 camPos = _cameraPosition != null ? (Vector3)_cameraPosition : Vector3.zero; Vector3 center = new Vector3(camPos.x, camPos.y, 0); center -= mm.MultiplyPoint(center); for (int i = 0; i < vertCount; i++) { Vector3 pt = vb.vertices[i]; pt = mm.MultiplyPoint(pt); pt += center; Vector3 vec = pt - camPos; float lambda = -camPos.z / vec.z; pt.x = camPos.x + lambda * vec.x; pt.y = camPos.y + lambda * vec.y; pt.z = 0; vb.vertices[i] = pt; } } mesh.Clear(); #if !(UNITY_5_2 || UNITY_5_3_OR_NEWER) if (_vertices == null || _vertices.Length != vertCount) { _vertices = new Vector3[vertCount]; _uv = new Vector2[vertCount]; _colors = new Color32[vertCount]; } vb.vertices.CopyTo(_vertices); vb.uv0.CopyTo(_uv); vb.colors.CopyTo(_colors); if (_triangles == null || _triangles.Length != vb.triangles.Count) { _triangles = new int[vb.triangles.Count]; } vb.triangles.CopyTo(_triangles); mesh.vertices = _vertices; mesh.uv = _uv; mesh.triangles = _triangles; mesh.colors32 = _colors; #else #if !UNITY_5_6_OR_NEWER _colors = null; #endif mesh.SetVertices(vb.vertices); mesh.SetUVs(0, vb.uv0); mesh.SetColors(vb.colors); mesh.SetTriangles(vb.triangles, 0); #endif vb.End(); if (meshModifier != null) { meshModifier(); } }
public void OnPopulateMesh(VertexBuffer vb) { int numVertices = points.Count; if (numVertices < 3) { return; } int restIndexPos, numRestIndices; Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor; float w = vb.contentRect.width; float h = vb.contentRect.height; bool useTexcoords = texcoords.Count >= numVertices; bool fullUV = true; for (int i = 0; i < numVertices; i++) { Vector3 vec = new Vector3(points[i].x, points[i].y, 0); if (usePercentPositions) { vec.x *= w; vec.y *= h; } if (useTexcoords) { Vector2 uv = texcoords[i]; if (uv.x != 0 && uv.x != 1 || uv.y != 0 && uv.y != 1) { fullUV = false; } uv.x = Mathf.Lerp(vb.uvRect.x, vb.uvRect.xMax, uv.x); uv.y = Mathf.Lerp(vb.uvRect.y, vb.uvRect.yMax, uv.y); vb.AddVert(vec, color, uv); } else { vb.AddVert(vec, color); } } if (useTexcoords && fullUV && numVertices == 4) { vb._isArbitraryQuad = true; } // Algorithm "Ear clipping method" described here: // -> https://en.wikipedia.org/wiki/Polygon_triangulation // // Implementation inspired by: // -> http://polyk.ivank.net // -> Starling sRestIndices.Clear(); for (int i = 0; i < numVertices; ++i) { sRestIndices.Add(i); } restIndexPos = 0; numRestIndices = numVertices; Vector2 a, b, c, p; int otherIndex; bool earFound; int i0, i1, i2; while (numRestIndices > 3) { earFound = false; i0 = sRestIndices[restIndexPos % numRestIndices]; i1 = sRestIndices[(restIndexPos + 1) % numRestIndices]; i2 = sRestIndices[(restIndexPos + 2) % numRestIndices]; a = points[i0]; b = points[i1]; c = points[i2]; if ((a.y - b.y) * (c.x - b.x) + (b.x - a.x) * (c.y - b.y) >= 0) { earFound = true; for (int i = 3; i < numRestIndices; ++i) { otherIndex = sRestIndices[(restIndexPos + i) % numRestIndices]; p = points[otherIndex]; if (IsPointInTriangle(ref p, ref a, ref b, ref c)) { earFound = false; break; } } } if (earFound) { vb.AddTriangle(i0, i1, i2); sRestIndices.RemoveAt((restIndexPos + 1) % numRestIndices); numRestIndices--; restIndexPos = 0; } else { restIndexPos++; if (restIndexPos == numRestIndices) { break; // no more ears } } } vb.AddTriangle(sRestIndices[0], sRestIndices[1], sRestIndices[2]); if (colors != null) { vb.RepeatColors(colors, 0, vb.currentVertCount); } }
//4 vertex static void FillRadial90(VertexBuffer vb, Rectangle 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 = (float)Math.Tan(Math.PI * 0.5f * ratio); 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.X; float yMin = flipY ? (vertRect.Height - vertRect.Y) : vertRect.Y; float xMax = flipX ? -vertRect.X : vertRect.Right; float yMax = flipY ? -vertRect.Y : vertRect.Bottom; vb.AddVert(new Vector3(xMin, yMin, 0)); if (clockwise) { vb.AddVert(new Vector3(xMax, yMin, 0)); } if (y > vertRect.Bottom) { if (amount < 0.5f) { 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.Right) { if (amount < 0.5f) { 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); } }
public void SliceFill(VertexBuffer vb) { Rectangle gridRect = (Rectangle)_scale9Grid; Rectangle contentRect = vb.contentRect; Rectangle uvRect = vb.uvRect; float sourceW = texture.width; float sourceH = texture.height; if (graphics.flip != FlipType.None) { if (graphics.flip == FlipType.Horizontal || graphics.flip == FlipType.Both) { gridRect.X = sourceW - gridRect.Right; } if (graphics.flip == FlipType.Vertical || graphics.flip == FlipType.Both) { gridRect.Y = sourceH - gridRect.Bottom; } } float sx = uvRect.Width / sourceW; float sy = uvRect.Height / sourceH; float xMax = uvRect.Right; float yMax = uvRect.Bottom; float xMax2 = gridRect.Right; float yMax2 = gridRect.Bottom; gridTexX[0] = uvRect.X; gridTexX[1] = uvRect.X + gridRect.X * sx; gridTexX[2] = uvRect.X + xMax2 * sx; gridTexX[3] = xMax; gridTexY[0] = yMax; gridTexY[1] = yMax - gridRect.Y * sy; gridTexY[2] = yMax - yMax2 * sy; gridTexY[3] = uvRect.Y; if (contentRect.Width >= (sourceW - gridRect.Width)) { gridX[1] = gridRect.X; gridX[2] = contentRect.Width - (sourceW - xMax2); gridX[3] = contentRect.Width; } else { float tmp = gridRect.X / (sourceW - xMax2); tmp = contentRect.Width * tmp / (1 + tmp); gridX[1] = tmp; gridX[2] = tmp; gridX[3] = contentRect.Width; } if (contentRect.Height >= (sourceH - gridRect.Height)) { gridY[1] = gridRect.Y; gridY[2] = contentRect.Height - (sourceH - yMax2); gridY[3] = contentRect.Height; } else { float tmp = gridRect.Y / (sourceH - yMax2); tmp = contentRect.Height * tmp / (1 + tmp); gridY[1] = tmp; gridY[2] = tmp; gridY[3] = contentRect.Height; } if (_tileGridIndice == 0) { for (int cy = 0; cy < 4; cy++) { for (int cx = 0; cx < 4; cx++) { vb.AddVert(new Vector3(gridX[cx], gridY[cy], 0), vb.vertexColor, new Vector2(gridTexX[cx], gridTexY[cy])); } } vb.AddTriangles(TRIANGLES_9_GRID); } else { Rectangle drawRect; Rectangle texRect; int row, col; int part; for (int pi = 0; pi < 9; pi++) { col = pi % 3; row = pi / 3; part = gridTileIndice[pi]; drawRect = Rectangle.FromLTRB(gridX[col], gridY[row], gridX[col + 1], gridY[row + 1]); texRect = Rectangle.FromLTRB(gridTexX[col], gridTexY[row + 1], gridTexX[col + 1], gridTexY[row]); if (part != -1 && (_tileGridIndice & (1 << part)) != 0) { TileFill(vb, drawRect, texRect, (part == 0 || part == 1 || part == 4) ? gridRect.Width : drawRect.Width, (part == 2 || part == 3 || part == 4) ? gridRect.Height : drawRect.Height); } else { vb.AddQuad(drawRect, vb.vertexColor, texRect); } } vb.AddTriangles(); } }
public void OnPopulateMesh(VertexBuffer vb) { Vector2 uvMin = new Vector2(vb.uvRect.X, vb.uvRect.Y); Vector2 uvMax = new Vector2(vb.uvRect.Right, vb.uvRect.Bottom); int segCount = path.segmentCount; float t = 0; float lw = lineWidth; float u; for (int si = 0; si < segCount; si++) { float ratio = path.GetSegmentLength(si) / path.length; float t0 = MathHelper.Clamp(fillStart - t, 0, ratio) / ratio; float t1 = MathHelper.Clamp(fillEnd - t, 0, ratio) / ratio; if (t0 >= t1) { t += ratio; continue; } points.Clear(); ts.Clear(); path.GetPointsInSegment(si, t0, t1, points, ts, pointDensity); int cnt = points.Count; Color c0 = vb.vertexColor; Color c1 = vb.vertexColor; /*if (gradient != null) * c0 = gradient.Evaluate(t); * if (lineWidthCurve != null) * lw = lineWidthCurve.Evaluate(t);*/ if (roundEdge && si == 0 && t0 == 0) { DrawRoundEdge(vb, points[0], points[1], lw, c0, uvMin); } int vertCount = vb.currentVertCount; for (int i = 1; i < cnt; i++) { Vector3 p0 = points[i - 1]; Vector3 p1 = points[i]; int k = vertCount + (i - 1) * 2; float tc = t + ratio * ts[i]; Vector3 lineVector = p1 - p0; Vector3 widthVector = Vector3.Cross(lineVector, new Vector3(0, 0, 1)); widthVector.Normalize(); if (i == 1) { u = MathHelper.Lerp(uvMin.X, uvMax.X, t + ratio * ts[i - 1]); vb.AddVert(p0 - widthVector * lw * 0.5f, c0, new Vector2(u, uvMax.Y)); vb.AddVert(p0 + widthVector * lw * 0.5f, c0, new Vector2(u, uvMin.Y)); if (si != 0) //joint { vb.AddTriangle(k - 2, k - 1, k + 1); vb.AddTriangle(k - 2, k + 1, k); } } //if (gradient != null) // c1 = gradient.Evaluate(tc); //if (lineWidthCurve != null) // lw = lineWidthCurve.Evaluate(tc); u = MathHelper.Lerp(uvMin.X, uvMax.X, tc); vb.AddVert(p1 - widthVector * lw * 0.5f, c1, new Vector2(u, uvMax.Y)); vb.AddVert(p1 + widthVector * lw * 0.5f, c1, new Vector2(u, uvMin.Y)); vb.AddTriangle(k, k + 1, k + 3); vb.AddTriangle(k, k + 3, k + 2); } if (roundEdge && si == segCount - 1 && t1 == 1) { DrawRoundEdge(vb, points[cnt - 1], points[cnt - 2], lw, c1, uvMax); } t += ratio; } }
//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; } }
public void OnPopulateMesh(VertexBuffer vb) { if (distances != null && distances.Length < sides) { Debug.LogError("distances.Length<sides"); return; } Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect; Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor; float angleDelta = 2 * Mathf.PI / sides; float angle = rotation * Mathf.Deg2Rad; float radius = Mathf.Min(rect.width / 2, rect.height / 2); float centerX = radius + rect.x; float centerY = radius + rect.y; vb.AddVert(new Vector3(centerX, centerY, 0), centerColor == null ? color : (Color32)centerColor); for (int i = 0; i < sides; i++) { float r = radius; if (distances != null) { r *= distances[i]; } float xv = Mathf.Cos(angle) * (r - lineWidth); float yv = Mathf.Sin(angle) * (r - lineWidth); Vector3 vec = new Vector3(xv + centerX, yv + centerY, 0); vb.AddVert(vec, color); if (lineWidth > 0) { vb.AddVert(vec, lineColor); xv = Mathf.Cos(angle) * r + centerX; yv = Mathf.Sin(angle) * r + centerY; vb.AddVert(new Vector3(xv, yv, 0), lineColor); } angle += angleDelta; } if (lineWidth > 0) { int tmp = sides * 3; for (int i = 0; i < tmp; i += 3) { if (i != tmp - 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 { vb.AddTriangle(0, i + 1, 1); vb.AddTriangle(2, i + 2, i + 3); vb.AddTriangle(i + 3, 3, 2); } } } else { for (int i = 0; i < sides; i++) { vb.AddTriangle(0, i + 1, (i == sides - 1) ? 1 : i + 2); } } }
public void SliceFill(VertexBuffer vb) { Rect gridRect = (Rect)_scale9Grid; Rect contentRect = vb.contentRect; Rect uvRect = vb.uvRect; float sourceW = texture.width; float sourceH = texture.height; float sx = uvRect.width / sourceW; float sy = uvRect.height / sourceH; float xMax = uvRect.xMax; float yMax = uvRect.yMax; float xMax2 = gridRect.xMax; float yMax2 = gridRect.yMax; gridTexX[0] = uvRect.x; gridTexX[1] = uvRect.x + gridRect.x * sx; gridTexX[2] = uvRect.x + xMax2 * sx; gridTexX[3] = xMax; gridTexY[0] = yMax; gridTexY[1] = yMax - gridRect.y * sy; gridTexY[2] = yMax - yMax2 * sy; gridTexY[3] = uvRect.y; if (contentRect.width >= (sourceW - gridRect.width)) { gridX[1] = gridRect.x; gridX[2] = contentRect.width - (sourceW - xMax2); gridX[3] = contentRect.width; } else { float tmp = gridRect.x / (sourceW - xMax2); tmp = contentRect.width * tmp / (1 + tmp); gridX[1] = tmp; gridX[2] = tmp; gridX[3] = contentRect.width; } if (contentRect.height >= (sourceH - gridRect.height)) { gridY[1] = gridRect.y; gridY[2] = contentRect.height - (sourceH - yMax2); gridY[3] = contentRect.height; } else { float tmp = gridRect.y / (sourceH - yMax2); tmp = contentRect.height * tmp / (1 + tmp); gridY[1] = tmp; gridY[2] = tmp; gridY[3] = contentRect.height; } if (_tileGridIndice == 0) { for (int cy = 0; cy < 4; cy++) { for (int cx = 0; cx < 4; cx++) { vb.AddVert(new Vector2(gridX[cx], gridY[cy]), vb.vertexColor, new Vector2(gridTexX[cx], gridTexY[cy])); } } vb.AddTriangles(TRIANGLES_9_GRID); } else { int hc, vc; Rect drawRect; Rect texRect; int row, col; int part; //先计算需要的顶点数量 int vertCount = 0; for (int pi = 0; pi < 9; pi++) { col = pi % 3; row = pi / 3; part = gridTileIndice[pi]; if (part != -1 && (_tileGridIndice & (1 << part)) != 0) { if (part == 0 || part == 1 || part == 4) { hc = Mathf.CeilToInt((gridX[col + 1] - gridX[col]) / gridRect.width); } else { hc = 1; } if (part == 2 || part == 3 || part == 4) { vc = Mathf.CeilToInt((gridY[row + 1] - gridY[row]) / gridRect.height); } else { vc = 1; } vertCount += hc * vc * 4; } else { vertCount += 4; } } for (int pi = 0; pi < 9; pi++) { col = pi % 3; row = pi / 3; part = gridTileIndice[pi]; drawRect = Rect.MinMaxRect(gridX[col], gridY[row], gridX[col + 1], gridY[row + 1]); texRect = Rect.MinMaxRect(gridTexX[col], gridTexY[row + 1], gridTexX[col + 1], gridTexY[row]); if (part != -1 && (_tileGridIndice & (1 << part)) != 0) { TileFill(vb, drawRect, texRect, (part == 0 || part == 1 || part == 4) ? gridRect.width : drawRect.width, (part == 2 || part == 3 || part == 4) ? gridRect.height : drawRect.height); } else { vb.AddQuad(drawRect, vb.vertexColor, texRect); } } vb.AddTriangles(); } }
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); if (sides < 6) { sides = 6; } 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), 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); } }
public void OnPopulateMesh(VertexBuffer vb) { if (distances != null && distances.Length != sides) { throw new System.Exception("distances.Length!=sides"); } Rectangle rect = drawRect != null ? (Rectangle)drawRect : vb.contentRect; Color color = fillColor != null ? (Color)fillColor : vb.vertexColor; rotation = MathHelper.ToRadians(rotation); float angleDelta = 2 * (float)Math.PI / sides; float angle = rotation; float radius = Math.Min(rect.Width / 2, rect.Height / 2); float centerX = radius + rect.X; float centerY = radius + rect.Y; vb.AddVert(new Vector3(centerX, centerY, 0), centerColor == null ? color : (Color)centerColor); for (int i = 0; i < sides; i++) { float r = radius; if (distances != null) { r *= distances[i]; } float xv = (float)Math.Cos(angle) * (r - lineWidth); float yv = (float)Math.Sin(angle) * (r - lineWidth); Vector3 vec = new Vector3(xv + centerX, yv + centerY, 0); vb.AddVert(vec, color); if (lineWidth > 0) { vb.AddVert(vec, lineColor); xv = (float)Math.Cos(angle) * r + centerX; yv = (float)Math.Sin(angle) * r + centerY; vb.AddVert(new Vector3(xv, yv, 0), lineColor); } angle += angleDelta; } if (lineWidth > 0) { int tmp = sides * 3; for (int i = 0; i < tmp; i += 3) { if (i != tmp - 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 { vb.AddTriangle(0, i + 1, 1); vb.AddTriangle(2, i + 2, i + 3); vb.AddTriangle(i + 3, 3, 2); } } } else { for (int i = 0; i < sides; i++) { vb.AddTriangle(0, i + 1, (i == sides - 1) ? 1 : i + 2); } } }
void UpdateMeshNow() { _meshDirty = false; if (_texture == null || _meshFactory == null) { if (mesh.vertexCount > 0) { mesh.Clear(); if (meshModifier != null) { meshModifier(); } } return; } VertexBuffer vb = VertexBuffer.Begin(); vb.contentRect = _contentRect; vb.uvRect = _texture.uvRect; if (_texture != null) { vb.textureSize = new Vector2(_texture.width, _texture.height); } else { vb.textureSize = new Vector2(0, 0); } if (_flip != FlipType.None) { if (_flip == FlipType.Horizontal || _flip == FlipType.Both) { float tmp = vb.uvRect.xMin; vb.uvRect.xMin = vb.uvRect.xMax; vb.uvRect.xMax = tmp; } if (_flip == FlipType.Vertical || _flip == FlipType.Both) { float tmp = vb.uvRect.yMin; vb.uvRect.yMin = vb.uvRect.yMax; vb.uvRect.yMax = tmp; } } vb.vertexColor = _color; _meshFactory.OnPopulateMesh(vb); int vertCount = vb.currentVertCount; if (vertCount == 0) { if (mesh.vertexCount > 0) { mesh.Clear(); if (meshModifier != null) { meshModifier(); } } vb.End(); return; } if (_texture.rotated) { float xMin = _texture.uvRect.xMin; float yMin = _texture.uvRect.yMin; float yMax = _texture.uvRect.yMax; float tmp; for (int i = 0; i < vertCount; i++) { Vector2 vec = vb.uvs[i]; tmp = vec.y; vec.y = yMin + vec.x - xMin; vec.x = xMin + yMax - tmp; vb.uvs[i] = vec; } } hasAlphaBackup = vb._alphaInVertexColor; if (hasAlphaBackup) { if (_alphaBackup == null) { _alphaBackup = new List <byte>(); } else { _alphaBackup.Clear(); } for (int i = 0; i < vertCount; i++) { Color32 col = vb.colors[i]; _alphaBackup.Add(col.a); col.a = (byte)(col.a * _alpha); vb.colors[i] = col; } } else if (_alpha != 1) { for (int i = 0; i < vertCount; i++) { Color32 col = vb.colors[i]; col.a = (byte)(col.a * _alpha); vb.colors[i] = col; } } if (_vertexMatrix != null) { Vector3 camPos = _vertexMatrix.cameraPos; Vector3 center = new Vector3(camPos.x, camPos.y, 0); center -= _vertexMatrix.matrix.MultiplyPoint(center); for (int i = 0; i < vertCount; i++) { Vector3 pt = vb.vertices[i]; pt = _vertexMatrix.matrix.MultiplyPoint(pt); pt += center; Vector3 vec = pt - camPos; float lambda = -camPos.z / vec.z; pt.x = camPos.x + lambda * vec.x; pt.y = camPos.y + lambda * vec.y; pt.z = 0; vb.vertices[i] = pt; } } mesh.Clear(); #if UNITY_5_2 || UNITY_5_3_OR_NEWER mesh.SetVertices(vb.vertices); if (vb._isArbitraryQuad) { mesh.SetUVs(0, vb.FixUVForArbitraryQuad()); } else { mesh.SetUVs(0, vb.uvs); } mesh.SetColors(vb.colors); mesh.SetTriangles(vb.triangles, 0); if (vb.uvs2.Count == vb.uvs.Count) { mesh.SetUVs(1, vb.uvs2); } #if !UNITY_5_6_OR_NEWER _colors = null; #endif #else Vector3 vertices = new Vector3[vertCount]; Vector2 uv = new Vector2[vertCount]; _colors = new Color32[vertCount]; int triangles = new int[vb.triangles.Count]; vb.vertices.CopyTo(vertices); vb.uvs.CopyTo(uv); vb.colors.CopyTo(_colors); vb.triangles.CopyTo(triangles); mesh.vertices = vertices; mesh.uv = uv; mesh.triangles = triangles; mesh.colors32 = _colors; if (vb.uvs2.Count == uv.Length) { uv = new Vector2[vertCount]; vb.uvs2.CopyTo(uv); mesh.uv2 = uv; } #endif vb.End(); if (meshModifier != null) { meshModifier(); } }