/* * . 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); } } }
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); } }
/* * 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); }
// Bresenham's line algorithm IEnumerator <Pixel> Rasterize() { int x0 = Mathf.RoundToInt(start.x); int y0 = Mathf.RoundToInt(start.y); int x1 = Mathf.RoundToInt(end.x); int y1 = Mathf.RoundToInt(end.y); bool steep = Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0); if (steep) { MUtils.Swap(ref x0, ref y0); MUtils.Swap(ref x1, ref y1); } if (x1 < x0) { MUtils.Swap(ref x0, ref x1); MUtils.Swap(ref y0, ref y1); } int dy = y1 - y0; int dx = x1 - x0; int yi = 1; if (dy < 0) { yi = -1; dy = -dy; } int D = 2 * dy - dx; int y = y0; if (steep) { for (int x = x0; x <= x1; ++x) { yield return(new Pixel() { x = y, y = x, c = 1f, }); if (D > 0) { y = y + yi; D = D - 2 * dx; } D = D + 2 * dy; } } else { for (int x = x0; x <= x1; ++x) { yield return(new Pixel() { x = x, y = y, c = 1f, }); if (D > 0) { y = y + yi; D = D - 2 * dx; } D = D + 2 * dy; } } }