using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace TransportGame.Utils { public static class Texture2DExtensions { /// /// Draws a line between two vectors /// /// Texture /// Color /// Position 1 /// Position 2 public static void DrawLine(this Texture2D @this, Color color, Vector2 p0, Vector2 p1) { DrawLine(@this, color, Convert.ToInt32(p0.x), Convert.ToInt32(p0.y), Convert.ToInt32(p1.x), Convert.ToInt32(p1.y)); } /// /// Draws a line between 2 points /// /// The texture /// X0 /// Y0 /// X1 /// Y1 /// Color public static void DrawLine(this Texture2D @this, Color color, int x0, int y0, int x1, int y1) { int dy = (int)(y1 - y0); int dx = (int)(x1 - x0); int stepx, stepy; if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } dy <<= 1; dx <<= 1; float fraction = 0; @this.SetPixelSafe(x0, y0, color); if (dx > dy) { fraction = dy - (dx >> 1); while (Mathf.Abs(x0 - x1) > 1) { if (fraction >= 0) { y0 += stepy; fraction -= dx; } x0 += stepx; fraction += dy; @this.SetPixelSafe(x0, y0, color); } } else { fraction = dx - (dy >> 1); while (Mathf.Abs(y0 - y1) > 1) { if (fraction >= 0) { x0 += stepx; fraction -= dy; } y0 += stepy; fraction += dx; @this.SetPixelSafe(x0, y0, color); } } } /// /// Draws a rhombus-like point /// /// Texture /// Position /// Radius /// Color public static void DrawPoint(this Texture2D @this, Color color, Vector2 p0, int radius) { DrawPoint(@this, color, Convert.ToInt32(p0.x), Convert.ToInt32(p0.y), radius); } /// /// Draws a rhombus-like point /// /// Texture /// Position /// Position /// Radius /// Color public static void DrawPoint(this Texture2D @this, Color color, int x0, int y0, int radius) { for (int y = y0 - radius; y <= y0 + radius; ++y) { int pts = radius - Math.Abs(y - y0); for (int x = x0 - pts; x <= x0 + pts; ++x) @this.SetPixelSafe(x, y, color); } } /// /// Fills a polygon /// /// Texture /// color /// Points public static void FillPolygon(this Texture2D @this, Color color, params Vector2[] points) { int minY = Int32.MaxValue, maxY = Int32.MinValue; // Unused... int[] ptX = points.Select(p => Convert.ToInt32(p.x)).ToArray(); int[] ptY = points.Select(p => Convert.ToInt32(p.y)).ToArray(); // Find min and max row for (int i = 0; i < points.Length; i++) { minY = Math.Min(minY, ptY[i]); maxY = Math.Max(maxY, ptY[i]); } List intersPoints = new List(); // Go through each row for (int y = minY; y <= maxY; ++y) { intersPoints.Clear(); // Find intersection points int j = points.Length - 1; for (int i = 0; i < points.Length; ++i) { // Treat special case where we have 2 points on the y axis if (ptY[i] == y && ptY[j] == y) { intersPoints.Add(Convert.ToInt32(points[i].x)); intersPoints.Add(Convert.ToInt32(points[j].x)); } // Intersection else if ((ptY[i] >= y && ptY[j] <= y) || (ptY[i] <= y && ptY[j] >= y)) { int x = Convert.ToInt32(points[i].x + (y - points[i].y) * (points[j].x - points[i].x) / (points[j].y - points[i].y)); intersPoints.Add(x); } j = i; } // Order pairs var intersPointsSorted = intersPoints.OrderBy(x => x).Distinct().ToArray(); // Draw for (int i = 0; i < intersPointsSorted.Length / 2; i++) { for (int x = intersPointsSorted[2 * i]; x <= intersPointsSorted[2 * i + 1]; x++) @this.SetPixelSafe(x, y, color); } } } /// /// Fills texture with specified color /// /// Texture /// Color public static void Fill(this Texture2D @this, Color color) { for (int x = 0; x < @this.width; ++x) for (int y = 0; y < @this.height; ++y) @this.SetPixelSafe(x, y, color); } /// /// Sets a pixel after checking if coordinates are inside image /// /// Texture /// X /// Y /// Color public static void SetPixelSafe(this Texture2D @this, int x, int y, Color color) { if (x >= 0 && y >= 0 && x < @this.width && y < @this.height) @this.SetPixel(x, y, color); } } }