198 lines
6.8 KiB
C#
198 lines
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
namespace TransportGame.Utils
|
|
{
|
|
public static class Texture2DExtensions
|
|
{
|
|
/// <summary>
|
|
/// Draws a line between two vectors
|
|
/// </summary>
|
|
/// <param name="this">Texture</param>
|
|
/// <param name="color">Color</param>
|
|
/// <param name="p0">Position 1</param>
|
|
/// <param name="p1">Position 2</param>
|
|
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));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws a line between 2 points
|
|
/// </summary>
|
|
/// <param name="this">The texture</param>
|
|
/// <param name="x0">X0</param>
|
|
/// <param name="y0">Y0</param>
|
|
/// <param name="x1">X1</param>
|
|
/// <param name="y1">Y1</param>
|
|
/// <param name="color">Color</param>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws a rhombus-like point
|
|
/// </summary>
|
|
/// <param name="this">Texture</param>
|
|
/// <param name="p0">Position</param>
|
|
/// <param name="radius">Radius</param>
|
|
/// <param name="color">Color</param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws a rhombus-like point
|
|
/// </summary>
|
|
/// <param name="this">Texture</param>
|
|
/// <param name="x0">Position</param>
|
|
/// <param name="y0">Position</param>
|
|
/// <param name="radius">Radius</param>
|
|
/// <param name="color">Color</param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fills a polygon
|
|
/// </summary>
|
|
/// <param name="this">Texture</param>
|
|
/// <param name="color">color</param>
|
|
/// <param name="points">Points</param>
|
|
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<int> intersPoints = new List<int>();
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fills texture with specified color
|
|
/// </summary>
|
|
/// <param name="this">Texture</param>
|
|
/// <param name="color">Color</param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets a pixel after checking if coordinates are inside image
|
|
/// </summary>
|
|
/// <param name="this">Texture</param>
|
|
/// <param name="x">X</param>
|
|
/// <param name="y">Y</param>
|
|
/// <param name="color">Color</param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|