public void OnPopulateMesh(VertexBuffer vb) { Rect rect = texture.GetDrawRect(vb.contentRect); if (_vertexMatrix != null) //画多边形时,要对UV处理才能有正确的显示,暂时未掌握,这里用更多的面来临时解决。 { int hc = (int)Mathf.Min(Mathf.CeilToInt(rect.width / 30), 9); int vc = (int)Mathf.Min(Mathf.CeilToInt(rect.height / 30), 9); int eachPartX = Mathf.FloorToInt(rect.width / hc); int eachPartY = Mathf.FloorToInt(rect.height / vc); float x, y; for (int i = 0; i <= vc; i++) { if (i == vc) { y = rect.yMax; } else { y = rect.y + i * eachPartY; } for (int j = 0; j <= hc; j++) { if (j == hc) { x = rect.xMax; } else { x = rect.x + j * eachPartX; } vb.AddVert(new Vector3(x, y, 0)); } } for (int i = 0; i < vc; i++) { int k = i * (hc + 1); for (int j = 1; j <= hc; j++) { int m = k + j; vb.AddTriangle(m - 1, m, m + hc); vb.AddTriangle(m, m + hc + 1, m + hc); } } } else { vb.AddQuad(rect, vb.vertexColor, vb.uvRect); vb.AddTriangles(); } }
void DrawRoundEdge(VertexBuffer vb, Vector2 p0, Vector2 p1, float lw, Color32 color, Vector2 uv) { Vector2 widthVector = Vector3.Cross(p0 - p1, new Vector3(0, 0, 1)); widthVector.Normalize(); widthVector = widthVector * lw / 2f; Vector2 lineVector = (p0 - p1).normalized * lw / 2f; int sides = Mathf.CeilToInt(Mathf.PI * lw / 2); if (sides < 6) { sides = 6; } int current = vb.currentVertCount; float angleUnit = Mathf.PI / (sides - 1); vb.AddVert(p0, color, uv); vb.AddVert(p0 + widthVector, color, uv); for (int n = 0; n < sides; n++) { vb.AddVert(p0 + Mathf.Cos(angleUnit * n) * widthVector + Mathf.Sin(angleUnit * n) * lineVector, color, uv); vb.AddTriangle(current, current + 1 + n, current + 2 + n); } }
void DrawRoundEdge(VertexBuffer vb, Vector3 p0, Vector3 p1, float lw, Color color, Vector2 uv) { Vector3 tmp = p0 - p1; Vector3 widthVector = Vector3.Cross(tmp, new Vector3(0, 0, 1)); widthVector.Normalize(); widthVector = widthVector * lw / 2f; tmp.Normalize(); Vector3 lineVector = tmp * lw / 2f; int sides = (int)Math.Ceiling(Math.PI * lw / 2); if (sides < 6) { sides = 6; } int current = vb.currentVertCount; float angleUnit = (float)Math.PI / (sides - 1); vb.AddVert(p0, color, uv); vb.AddVert(p0 + widthVector, color, uv); for (int n = 0; n < sides; n++) { vb.AddVert(p0 + (float)Math.Cos(angleUnit * n) * widthVector + (float)Math.Sin(angleUnit * n) * lineVector, color, uv); vb.AddTriangle(current, current + 1 + n, current + 2 + n); } }
public void OnPopulateMesh(VertexBuffer vb) { float w = vb.contentRect.width; float h = vb.contentRect.height; float xMax = vb.contentRect.xMax; float yMax = vb.contentRect.yMax; int hc = (int)Mathf.Min(Mathf.CeilToInt(w / gridSize), 9); int vc = (int)Mathf.Min(Mathf.CeilToInt(h / gridSize), 9); int eachPartX = Mathf.FloorToInt(w / hc); int eachPartY = Mathf.FloorToInt(h / vc); float x, y; for (int i = 0; i <= vc; i++) { if (i == vc) { y = yMax; } else { y = vb.contentRect.y + i * eachPartY; } for (int j = 0; j <= hc; j++) { if (j == hc) { x = xMax; } else { x = vb.contentRect.x + j * eachPartX; } vb.AddVert(new Vector3(x, y, 0)); } } for (int i = 0; i < vc; i++) { int k = i * (hc + 1); for (int j = 1; j <= hc; j++) { int m = k + j; vb.AddTriangle(m - 1, m, m + hc); vb.AddTriangle(m, m + hc + 1, m + hc); } } }
public void OnPopulateMesh(VertexBuffer vb) { float w = vb.contentRect.Width; float h = vb.contentRect.Height; float xMax = vb.contentRect.Right; float yMax = vb.contentRect.Bottom; int hc = (int)MathHelper.Min((int)Math.Ceiling(w / gridSize), 9); int vc = (int)MathHelper.Min((int)Math.Ceiling(h / gridSize), 9); int eachPartX = (int)Math.Floor(w / hc); int eachPartY = (int)Math.Floor(h / vc); float x, y; for (int i = 0; i <= vc; i++) { if (i == vc) { y = yMax; } else { y = vb.contentRect.Y + i * eachPartY; } for (int j = 0; j <= hc; j++) { if (j == hc) { x = xMax; } else { x = vb.contentRect.X + j * eachPartX; } vb.AddVert(new Vector3(x, y, 0)); } } for (int i = 0; i < vc; i++) { int k = i * (hc + 1); for (int j = 1; j <= hc; j++) { int m = k + j; vb.AddTriangle(m - 1, m, m + hc); vb.AddTriangle(m, m + hc + 1, m + hc); } } }
void DrawOutline(VertexBuffer vb) { int numVertices = points.Count; int start = vb.currentVertCount - numVertices; int k = vb.currentVertCount; for (int i = 0; i < numVertices; i++) { Vector3 p0 = vb.vertices[start + i]; p0.y = -p0.y; Vector3 p1; if (i < numVertices - 1) { p1 = vb.vertices[start + i + 1]; } else { p1 = vb.vertices[start]; } p1.y = -p1.y; Vector3 lineVector = p1 - p0; Vector3 widthVector = Vector3.Cross(lineVector, new Vector3(0, 0, 1)); widthVector.Normalize(); vb.AddVert(p0 - widthVector * lineWidth * 0.5f, lineColor); vb.AddVert(p0 + widthVector * lineWidth * 0.5f, lineColor); vb.AddVert(p1 - widthVector * lineWidth * 0.5f, lineColor); vb.AddVert(p1 + widthVector * lineWidth * 0.5f, lineColor); k += 4; vb.AddTriangle(k - 4, k - 3, k - 1); vb.AddTriangle(k - 4, k - 1, k - 2); //joint if (i != 0) { vb.AddTriangle(k - 6, k - 5, k - 3); vb.AddTriangle(k - 6, k - 3, k - 4); } if (i == numVertices - 1) { start += numVertices; vb.AddTriangle(k - 2, k - 1, start + 1); vb.AddTriangle(k - 2, start + 1, start); } } }
//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); float thresold = vertRect.height / vertRect.width - tan; 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 > 0) { 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 > 0) { 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 OnPopulateMesh(VertexBuffer vb) { Rectangle rect = drawRect != null ? (Rectangle)drawRect : vb.contentRect; Color color = fillColor != null ? (Color)fillColor : vb.vertexColor; float radiusX = rect.Width / 2; float radiusY = rect.Height / 2; float cornerMaxRadius = Math.Min(radiusX, radiusY); float centerX = radiusX + rect.X; float centerY = radiusY + rect.Y; vb.AddVert(new Vector3(centerX, centerY, 0), color); int cnt = vb.currentVertCount; for (int i = 0; i < 4; i++) { float radius = 0; switch (i) { case 0: radius = bottomRightRadius; break; case 1: radius = bottomLeftRadius; break; case 2: radius = topLeftRadius; break; case 3: radius = topRightRadius; break; } radius = Math.Min(cornerMaxRadius, radius); float offsetX = rect.X; float offsetY = rect.Y; if (i == 0 || i == 3) { offsetX = rect.Right - radius * 2; } if (i == 0 || i == 1) { offsetY = rect.Bottom - radius * 2; } if (radius != 0) { int partNumSides = (int)Math.Max(1, Math.Ceiling(Math.PI * radius / 8)) + 1; float angleDelta = (float)Math.PI / 2 / partNumSides; float angle = (float)Math.PI / 2 * i; float startAngle = angle; for (int j = 1; j <= partNumSides; j++) { if (j == partNumSides) //消除精度误差带来的不对齐 { angle = startAngle + (float)Math.PI / 2; } Vector3 v1 = new Vector3(offsetX + (float)Math.Cos(angle) * (radius - lineWidth) + radius, offsetY + (float)Math.Sin(angle) * (radius - lineWidth) + radius, 0); vb.AddVert(v1, color); if (lineWidth != 0) { vb.AddVert(v1, lineColor); vb.AddVert(new Vector3(offsetX + (float)Math.Cos(angle) * radius + radius, offsetY + (float)Math.Sin(angle) * radius + radius, 0), lineColor); } angle += angleDelta; } } else { Vector3 v1 = new Vector3(offsetX, offsetY, 0); if (lineWidth != 0) { if (i == 0 || i == 3) { offsetX -= lineWidth; } else { offsetX += lineWidth; } if (i == 0 || i == 1) { offsetY -= lineWidth; } else { offsetY += lineWidth; } Vector3 v2 = new Vector3(offsetX, offsetY, 0); vb.AddVert(v2, color); vb.AddVert(v2, lineColor); vb.AddVert(v1, lineColor); } else { vb.AddVert(v1, color); } } } cnt = vb.currentVertCount - cnt; if (lineWidth > 0) { 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 { 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 < cnt; i++) { vb.AddTriangle(0, i + 1, (i == cnt - 1) ? 1 : i + 2); } } }
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); } }
public void OnPopulateMesh(VertexBuffer vb) { Vector2 uvMin = vb.uvRect.position; Vector2 uvMax = new Vector2(vb.uvRect.xMax, vb.uvRect.yMax); 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 = Mathf.Clamp(fillStart - t, 0, ratio) / ratio; float t1 = Mathf.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 = Mathf.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 = Mathf.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; } }
public void OnPopulateMesh(VertexBuffer vb) { int numVertices = points.Count; if (numVertices < 3) { return; } int restIndexPos, numRestIndices; Color color = fillColor != null ? (Color)fillColor : vb.vertexColor; for (int i = 0; i < numVertices; i++) { Vector3 vec = new Vector3(points[i].X, points[i].Y, 0); if (usePercentPositions) { vec.X *= vb.contentRect.Width; vec.Y *= vb.contentRect.Height; } vb.AddVert(vec, color); } // 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); } }
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; rotation = rotation * Mathf.Deg2Rad; float angleDelta = 2 * Mathf.PI / sides; float angle = rotation; 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 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 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); } } }