draft out some code. this is my therapy

This commit is contained in:
JohnCorby 2023-07-19 20:42:17 -07:00
parent c5873aa0ef
commit eaa6864fa3
9 changed files with 354 additions and 0 deletions

View File

@ -0,0 +1,43 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class CanvasScale : ITextureOperation
{
private readonly int _width;
private readonly int _height;
public CanvasScale(int width, int height)
{
_width = width;
_height = height;
}
public string Description => $"canvas scale {_width} {_height}";
public Texture2D Apply(Texture2D src)
{
var dest = new Texture2D(_width, _height, src.format, src.mipmapCount != 1);
dest.name = Description;
var fillPixels = new Color[dest.width * dest.height];
for (int i = 0; i < dest.width; i++)
{
for (int j = 0; j < dest.height; j++)
{
var x = i + (dest.width - _width) / 2;
var y = j + (dest.height - _height) / 2;
var colour = Color.black;
if (x < dest.width && y < dest.height) colour = dest.GetPixel(i, j);
fillPixels[i + j * dest.width] = colour;
}
}
dest.SetPixels(fillPixels);
dest.Apply();
dest.wrapMode = dest.wrapMode;
return dest;
}
}

View File

@ -0,0 +1,9 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public interface ITextureOperation
{
public string Description { get; }
public Texture2D Apply(Texture2D src);
}

View File

@ -0,0 +1,33 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class LerpGreyscale : ITextureOperation
{
private readonly Color _lightTint;
private readonly Color _darkTint;
public LerpGreyscale(Color lightTint, Color darkTint)
{
_lightTint = lightTint;
_darkTint = darkTint;
}
public string Description => $"lerp greyscale {_lightTint} {_darkTint}";
public Texture2D Apply(Texture2D src)
{
var pixels = src.GetPixels();
for (int i = 0; i < pixels.Length; i++)
{
pixels[i].r = Mathf.Lerp(_darkTint.r, _lightTint.r, pixels[i].r);
pixels[i].g = Mathf.Lerp(_darkTint.g, _lightTint.g, pixels[i].g);
pixels[i].b = Mathf.Lerp(_darkTint.b, _lightTint.b, pixels[i].b);
}
src.SetPixels(pixels);
src.Apply();
return null;
}
}

View File

@ -0,0 +1,44 @@
using OWML.Common;
using System.IO;
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class Load : ITextureOperation
{
private readonly IModBehaviour _mod;
private readonly string _filename;
private readonly bool _useMipmaps;
private readonly bool _wrap;
private readonly bool _linear;
public Load(IModBehaviour mod, string filename, bool useMipmaps = true, bool wrap = false, bool linear = false)
{
_mod = mod;
_filename = filename;
_useMipmaps = useMipmaps;
_wrap = wrap;
_linear = linear;
var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, filename);
var key = GetKey(path);
Description = $"load {key} {useMipmaps} {wrap} {linear}";
}
public string Description { get; }
public Texture2D Apply(Texture2D src)
{
var path = Path.Combine(_mod.ModHelper.Manifest.ModFolderPath, _filename);
var data = File.ReadAllBytes(path);
var dest = new Texture2D(2, 2, TextureFormat.RGBA32, _useMipmaps, _linear);
dest.name = Description;
dest.wrapMode = _wrap ? TextureWrapMode.Repeat : TextureWrapMode.Clamp;
dest.LoadImage(data);
return dest;
}
private static string GetKey(string path) => path.Substring(Main.Instance.ModHelper.OwmlConfig.ModsPath.Length);
}

View File

@ -0,0 +1,37 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class MakeClear : ITextureOperation
{
private readonly int _width;
private readonly int _height;
private readonly bool _wrap;
public MakeClear(int width, int height, bool wrap = false)
{
_width = width;
_height = height;
_wrap = wrap;
}
public string Description => $"clear {_width} {_height} {_wrap}";
public Texture2D Apply(Texture2D src)
{
var dest = new Texture2D(1, 1, TextureFormat.ARGB32, false);
dest.name = Description;
var fillColor = Color.clear;
var fillPixels = new Color[dest.width * dest.height];
for (int i = 0; i < fillPixels.Length; i++)
{
fillPixels[i] = fillColor;
}
dest.SetPixels(fillPixels);
dest.Apply();
dest.wrapMode = _wrap ? TextureWrapMode.Repeat : TextureWrapMode.Clamp;
return dest;
}
}

View File

@ -0,0 +1,59 @@
using HarmonyLib;
using NewHorizons.Utility.OWML;
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
namespace NewHorizons.Utility.Files.NHTexture;
public class NHTexture
{
private static readonly Dictionary<string, Texture2D> _cache = new();
private readonly List<ITextureOperation> _operations = new();
public void AddOperation(ITextureOperation operation)
{
_operations.Add(operation);
}
public Texture2D Apply()
{
var cacheKey = _operations.Join(x => x.Description, " > ");
if (_cache.TryGetValue(cacheKey, out var texture))
{
return texture;
}
ITextureOperation operation = null;
try
{
for (var i = 0; i < _operations.Count; i++)
{
operation = _operations[i];
var src = texture;
var dest = operation.Apply(src);
if (dest != null)
{
// makes new texture. destroy the old one
Object.DestroyImmediate(src);
texture = dest;
}
else
{
// mutates src. keep it around
texture = src;
}
}
}
catch (Exception e)
{
NHLogger.LogVerbose($"Exception thrown while performing NHTexture operation {(operation != null ? operation.Description : "NULL")} on texture {(texture != null ? texture.name : "NULL")}:\n{e}");
return null;
}
_cache.Add(cacheKey, texture);
return texture;
}
}

View File

@ -0,0 +1,60 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class Outline : ITextureOperation
{
private readonly Color _color;
private readonly int _thickness;
public Outline(Color color, int thickness)
{
_color = color;
_thickness = thickness;
}
public string Description => $"outline {_color} {_thickness}";
public Texture2D Apply(Texture2D src)
{
var outlinePixels = new Color[src.width * src.height];
var pixels = src.GetPixels();
for (int x = 0; x < src.width; x++)
{
for (int y = 0; y < src.height; y++)
{
var fillColor = new Color(0, 0, 0, 0);
if (pixels[x + y * src.width].a == 1 && CloseToTransparent(pixels, src.width, src.height, x, y, _thickness))
{
fillColor = _color;
}
outlinePixels[x + y * src.width] = fillColor;
}
}
src.SetPixels(outlinePixels);
src.Apply();
return null;
}
private static bool CloseToTransparent(Color[] pixels, int width, int height, int x, int y, int thickness)
{
// Check nearby
var minX = Mathf.Max(0, x - thickness / 2);
var minY = Mathf.Max(0, y - thickness / 2);
var maxX = Mathf.Min(width, x + thickness / 2);
var maxY = Mathf.Min(height, y + thickness / 2);
for (int i = minX; i < maxX; i++)
{
for (int j = minY; j < maxY; j++)
{
if (pixels[i + j * width].a < 1) return true;
}
}
return false;
}
}

View File

@ -0,0 +1,38 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class SlideInvert : ITextureOperation
{
public string Description => "slide invert";
public Texture2D Apply(Texture2D src)
{
var pixels = src.GetPixels();
for (var i = 0; i < pixels.Length; i++)
{
var x = i % src.width;
var y = i / src.height;
// Needs a black border
if (x == 0 || y == 0 || x == src.width - 1 || y == src.height - 1)
{
pixels[i].r = 1;
pixels[i].g = 1;
pixels[i].b = 1;
pixels[i].a = 1;
}
else
{
pixels[i].r = 1f - pixels[i].r;
pixels[i].g = 1f - pixels[i].g;
pixels[i].b = 1f - pixels[i].b;
}
}
src.SetPixels(pixels);
src.Apply();
return null;
}
}

View File

@ -0,0 +1,31 @@
using UnityEngine;
namespace NewHorizons.Utility.Files.NHTexture;
public class Tint : ITextureOperation
{
private readonly Color _tint;
public Tint(Color tint)
{
_tint = tint;
}
public string Description => $"tint {_tint}";
public Texture2D Apply(Texture2D src)
{
var pixels = src.GetPixels();
for (int i = 0; i < pixels.Length; i++)
{
pixels[i].r *= _tint.r;
pixels[i].g *= _tint.g;
pixels[i].b *= _tint.b;
}
src.SetPixels(pixels);
src.Apply();
return null;
}
}