void BlitInternal(int i0, int i1, int i2, Vector2[] verts, Vector2[] uv, PlotDelegate plotDelegate) { SortIndex(i0, i1, i2, verts, out i0, out i1, out i2); var v0 = verts[i0]; var v1 = verts[i1]; var v2 = verts[i2]; var uv0 = uv[i0]; var uv1 = uv[i1]; var uv2 = uv[i2]; if (v0.y == v1.y) { BlitTriangle(v0, v1, v2, uv0, uv1, uv2, plotDelegate); } else if (v1.y == v2.y) { BlitTriangle(v1, v2, v0, uv1, uv2, uv0, plotDelegate); } else { var y = v1.y; var x = v0.x - (v0.y - y) / (v0.y - v2.y) * (v0.x - v2.x); var v3 = new Vector2(x, y); var uv3 = uv2 + (uv1 - uv2) * (v3 - v2).magnitude / (v0 - v2).magnitude; BlitTriangle(v1, v3, v0, uv1, uv3, uv0, plotDelegate); BlitTriangle(v1, v3, v2, uv1, uv3, uv2, plotDelegate); } }
void BlitHorizontalLine(int x0, int x1, int y, Vector2 uv0, Vector2 uv1, PlotDelegate plotDelegate) { if (x0 > x1) { MUtils.Swap(ref x0, ref x1); } float xx0, yy0; Vector2 newUv = Vector2.zero; for (int x = x0; x <= x1; ++x) { ToWorldSpace(x, y, out xx0, out yy0); plotDelegate(new Vector2(xx0, yy0), newUv); } }
public void Blit(SpriteRenderer spr, PlotDelegate plotDelegate) { var sp = spr.sprite; var verts = sp.vertices; ToBlitSpace(verts, spr.transform); // bounds var uv = sp.uv; // blit each triangle var tris = sp.triangles; for (int i = 0; i < tris.Length; i += 3) { var i0 = tris[i + 0]; var i1 = tris[i + 1]; var i2 = tris[i + 2]; BlitInternal(i0, i1, i2, verts, uv, plotDelegate); } }
/* * . v0 * / \ * v1 /___\ v2 * */ void BlitUpperTriangle(Vector2 v0, Vector2 v1, Vector2 v2, Vector2 uv0, Vector2 uv1, Vector2 uv2, PlotDelegate plotDelegate) { if (v1.x > v2.x) { MUtils.Swap(ref v1, ref v2); } var L1 = new RasterizedLine(v1, v0); var i1 = L1.CreatePixelIterator(); int y0 = int.MinValue; int x0; int x1; float dx = v2.x - v0.x; float dy = v0.y - v2.y; Vector2 newUv0 = Vector2.zero; Vector3 newUv1 = Vector2.zero; if (dy != 0) { while (NextY(i1, y0, out x0, out y0)) { x1 = Mathf.RoundToInt(v2.x - dx * (y0 - v2.y) / dy); BlitHorizontalLine(x0, x1, y0, newUv0, newUv1, plotDelegate); } } }
public static void Rasterize(this SpriteRenderer spr, Target target, PlotDelegate plotDelegate) { target.Blit(spr, plotDelegate); }
/* * v0 ---- v1 \ / \/ \ v2 */ void BlitTriangle(Vector2 v0, Vector2 v1, Vector2 v2, Vector2 uv0, Vector2 uv1, Vector2 uv2, PlotDelegate plotDelegate) { if (v0.x > v1.x) { MUtils.Swap(ref v0, ref v1); } var L1 = new RasterizedLine(v0, v2); var L2 = new RasterizedLine(v1, v2); var i1 = L1.CreatePixelIterator(); var i2 = L2.CreatePixelIterator(); Vector2 newUv0 = Vector2.zero; Vector3 newUv1 = Vector2.zero; var pList1 = ArrayPool <RasterizedLine.Pixel> .Get(); var pList2 = ArrayPool <RasterizedLine.Pixel> .Get(); CacheYOnChanged(i1, pList1); CacheYOnChanged(i2, pList2); if (CheckSequence(pList1, pList2)) { for (int i = 0; i < pList1.length; ++i) { var a = pList1[i]; var b = pList2[i]; BlitHorizontalLine(a.x, b.x, a.y, newUv0, newUv1, plotDelegate); } } else { for (int i = 0; i < pList1.length; ++i) { var a = pList1[i]; var b = pList2[-i - 1]; BlitHorizontalLine(a.x, b.x, a.y, newUv0, newUv1, plotDelegate); } } ArrayPool <RasterizedLine.Pixel> .Release(pList1); ArrayPool <RasterizedLine.Pixel> .Release(pList2); }