using System;
using UnityEngine;
namespace ProceduralToolkit
{
///
/// Texture extensions
///
public static class TextureE
{
#region DrawLine
///
/// Draws a line on the texture
///
public static void DrawLine(this Texture2D texture, Vector2Int v0, Vector2Int v1, Color color)
{
DrawLine(texture, v0.x, v0.y, v1.x, v1.y, color);
}
///
/// Draws a line on the texture
///
public static void DrawLine(this Texture2D texture, int x0, int y0, int x1, int y1, Color color)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
Draw.RasterLine(x0, y0, x1, y1, (x, y) => texture.SetPixel(x, y, color));
}
///
/// Draws a line on pixels
///
public static void DrawLine(this Color[] pixels, int textureWidth, Vector2Int v0, Vector2Int v1, Color color)
{
DrawLine(pixels, textureWidth, v0.x, v0.y, v1.x, v1.y, color);
}
///
/// Draws a line on pixels
///
public static void DrawLine(this Color[] pixels, int textureWidth, int x0, int y0, int x1, int y1, Color color)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
Draw.RasterLine(x0, y0, x1, y1, (x, y) => pixels[x + y*textureWidth] = color);
}
#endregion DrawLine
#region DrawAALine
///
/// Draws an anti-aliased line on the texture
///
public static void DrawAALine(this Texture2D texture, Vector2Int v0, Vector2Int v1, Color color)
{
DrawAALine(texture, v0.x, v0.y, v1.x, v1.y, color);
}
///
/// Draws an anti-aliased line on the texture
///
public static void DrawAALine(this Texture2D texture, int x0, int y0, int x1, int y1, Color color)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
Draw.RasterAALine(x0, y0, x1, y1, (x, y, t) => texture.SetPixel(x, y, Color.Lerp(texture.GetPixel(x, y), color, t)));
}
///
/// Draws an anti-aliased line on pixels
///
public static void DrawAALine(this Color[] pixels, int textureWidth, Vector2Int v0, Vector2Int v1, Color color)
{
DrawAALine(pixels, textureWidth, v0.x, v0.y, v1.x, v1.y, color);
}
///
/// Draws an anti-aliased line on pixels
///
public static void DrawAALine(this Color[] pixels, int textureWidth, int x0, int y0, int x1, int y1, Color color)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
Draw.RasterAALine(x0, y0, x1, y1, (x, y, t) => pixels[x + y*textureWidth] = Color.Lerp(pixels[x + y*textureWidth], color, t));
}
#endregion DrawAALine
#region DrawCircle
///
/// Draws a circle on the texture
///
public static void DrawCircle(this Texture2D texture, Vector2Int center, int radius, Color color)
{
DrawCircle(texture, center.x, center.y, radius, color);
}
///
/// Draws a circle on the texture
///
public static void DrawCircle(this Texture2D texture, int centerX, int centerY, int radius, Color color)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
Draw.RasterCircle(centerX, centerY, radius, (x, y) => texture.SetPixel(x, y, color));
}
///
/// Draws a circle on pixels
///
public static void DrawCircle(this Color[] pixels, int textureWidth, Vector2Int center, int radius, Color color)
{
DrawCircle(pixels, textureWidth, center.x, center.y, radius, color);
}
///
/// Draws a circle on pixels
///
public static void DrawCircle(this Color[] pixels, int textureWidth, int centerX, int centerY, int radius, Color color)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
Draw.RasterCircle(centerX, centerY, radius, (x, y) => pixels[x + y*textureWidth] = color);
}
#endregion DrawCircle
#region DrawFilledCircle
///
/// Draws a filled circle on the texture using Bresenham's algorithm
///
public static void DrawFilledCircle(this Texture2D texture, Vector2Int center, int radius, Color color)
{
DrawFilledCircle(texture, center.x, center.y, radius, color);
}
///
/// Draws a filled circle on the texture using Bresenham's algorithm
///
public static void DrawFilledCircle(this Texture2D texture, int centerX, int centerY, int radius, Color color)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
Draw.RasterFilledCircle(centerX, centerY, radius, (x, y) => texture.SetPixel(x, y, color));
}
///
/// Draws a filled circle on pixels using Bresenham's algorithm
///
public static void DrawFilledCircle(this Color[] pixels, int textureWidth, Vector2Int center, int radius, Color color)
{
DrawFilledCircle(pixels, textureWidth, center.x, center.y, radius, color);
}
///
/// Draws a filled circle on pixels using Bresenham's algorithm
///
public static void DrawFilledCircle(this Color[] pixels, int textureWidth, int centerX, int centerY, int radius, Color color)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
Draw.RasterFilledCircle(centerX, centerY, radius, (x, y) => pixels[x + y*textureWidth] = color);
}
#endregion DrawFilledCircle
#region DrawRect
///
/// Draws a filled rectangle on the texture
///
public static void DrawRect(this Texture2D texture, RectInt rect, Color color)
{
DrawRect(texture, rect.x, rect.y, rect.width, rect.height, color);
}
///
/// Draws a filled rectangle on the texture
///
public static void DrawRect(this Texture2D texture, int x, int y, int blockWidth, int blockHeight, Color color)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
var pixels = new Color[blockWidth*blockHeight];
for (int _y = 0; _y < blockHeight; _y++)
{
for (int _x = 0; _x < blockWidth; _x++)
{
pixels[_x + _y*blockWidth] = color;
}
}
texture.SetPixels(x, y, blockWidth, blockHeight, pixels);
}
///
/// Draws a filled rectangle on pixels
///
public static void DrawRect(this Color[] pixels, int textureWidth, RectInt rect, Color color)
{
DrawRect(pixels, textureWidth, rect.x, rect.y, rect.width, rect.height, color);
}
///
/// Draws a filled rectangle on pixels
///
public static void DrawRect(this Color[] pixels, int textureWidth, int x, int y, int blockWidth, int blockHeight, Color color)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
for (int _y = y; _y < y + blockHeight; _y++)
{
for (int _x = x; _x < x + blockWidth; _x++)
{
pixels[_x + _y*textureWidth] = color;
}
}
}
#endregion DrawRect
#region DrawGradient
///
/// Fills the texture with a gradient
///
public static void DrawGradient(this Texture2D texture, Gradient gradient, Directions direction)
{
DrawGradient(texture, 0, 0, texture.width, texture.height, gradient, direction);
}
///
/// Draws a gradient rectangle on the texture
///
public static void DrawGradient(this Texture2D texture, RectInt rect, Gradient gradient, Directions direction)
{
DrawGradient(texture, rect.x, rect.y, rect.width, rect.height, gradient, direction);
}
///
/// Draws a gradient rectangle on the texture
///
public static void DrawGradient(this Texture2D texture, int x, int y, int blockWidth, int blockHeight, Gradient gradient,
Directions direction)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
var pixels = new Color[blockWidth*blockHeight];
Gradient(pixels, blockWidth, 0, 0, blockWidth, blockHeight, gradient, direction);
texture.SetPixels(x, y, blockWidth, blockHeight, pixels);
}
///
/// Fills pixels with a gradient
///
public static void DrawGradient(this Color[] pixels, int textureWidth, int textureHeight, Gradient gradient, Directions direction)
{
DrawGradient(pixels, textureWidth, 0, 0, textureWidth, textureHeight, gradient, direction);
}
///
/// Draws a gradient rectangle on pixels
///
public static void DrawGradient(this Color[] pixels, int textureWidth, RectInt rect, Gradient gradient, Directions direction)
{
DrawGradient(pixels, textureWidth, rect.x, rect.y, rect.width, rect.height, gradient, direction);
}
///
/// Draws a gradient rectangle on pixels
///
public static void DrawGradient(this Color[] pixels, int textureWidth, int x, int y, int blockWidth, int blockHeight, Gradient gradient,
Directions direction)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
Gradient(pixels, textureWidth, x, y, blockWidth, blockHeight, gradient, direction);
}
private static void Gradient(Color[] pixels, int textureWidth, int x, int y, int blockWidth, int blockHeight, Gradient gradient,
Directions direction)
{
Func getColor;
switch (direction)
{
case Directions.Left:
getColor = (_x, _y) => gradient.Evaluate(1 - (float) (_x - x)/(float) blockWidth);
break;
case Directions.Right:
getColor = (_x, _y) => gradient.Evaluate((float) (_x - x)/(float) blockWidth);
break;
case Directions.Down:
getColor = (_x, _y) => gradient.Evaluate(1 - (float) (_y - y)/(float) blockHeight);
break;
case Directions.Up:
getColor = (_x, _y) => gradient.Evaluate((float) (_y - y)/(float) blockHeight);
break;
default:
throw new ArgumentException("Not supported direction: " + direction, nameof(direction));
}
for (int _y = y; _y < y + blockHeight; _y++)
{
for (int _x = x; _x < x + blockWidth; _x++)
{
pixels[_x + _y*textureWidth] = getColor(_x, _y);
}
}
}
#endregion DrawGradient
#region Clear
///
/// Fills the texture with white color
///
public static void Clear(this Texture2D texture)
{
Clear(texture, Color.white);
}
///
/// Fills the texture with specified color
///
public static void Clear(this Texture2D texture, Color color)
{
if (texture == null)
{
throw new ArgumentNullException(nameof(texture));
}
var pixels = new Color[texture.width*texture.height];
for (var i = 0; i < pixels.Length; i++)
{
pixels[i] = color;
}
texture.SetPixels(pixels);
}
///
/// Fills pixels with white color
///
public static void Clear(this Color[] pixels)
{
Clear(pixels, Color.white);
}
///
/// Fills pixels with specified color
///
public static void Clear(this Color[] pixels, Color color)
{
if (pixels == null)
{
throw new ArgumentNullException(nameof(pixels));
}
for (var i = 0; i < pixels.Length; i++)
{
pixels[i] = color;
}
}
#endregion Clear
}
}