|  |  | @@ -0,0 +1,127 @@ | 
    
    |  |  | using System; | 
    
    |  |  | using System.Collections.Generic; | 
    
    |  |  | using System.Linq; | 
    
    |  |  | using UnityEditor; | 
    
    |  |  | using UnityEngine; | 
    
    |  |  | 
 | 
    
    |  |  | namespace Editor.Utility | 
    
    |  |  | { | 
    
    |  |  | public static class EdgeMapUtils | 
    
    |  |  | { | 
    
    |  |  | public const int EDGE_SIZE = 2; | 
    
    |  |  | 
 | 
    
    |  |  | public static void Update(IEnumerable<Sprite> spr) | 
    
    |  |  | { | 
    
    |  |  | foreach (var s in spr) | 
    
    |  |  | Update(s); | 
    
    |  |  | } | 
    
    |  |  | 
 | 
    
    |  |  | private static void Update(Sprite s) | 
    
    |  |  | { | 
    
    |  |  | //aaahaha, ok, oh boy. Yeah, scan the sprite on the cpu, look for edges and plug those into a texture | 
    
    |  |  | //make sprite readable | 
    
    |  |  | var test = s.texture; | 
    
    |  |  | var path = AssetDatabase.GetAssetPath(s); | 
    
    |  |  | var spriteTi = (TextureImporter)TextureImporter.GetAtPath(path); | 
    
    |  |  | spriteTi.isReadable = true; | 
    
    |  |  | AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); | 
    
    |  |  | 
 | 
    
    |  |  | //DO STUFF | 
    
    |  |  | var edges = BuildEdgeTexture(s); | 
    
    |  |  | var savedEdgePath = SaveEdges(s, path, edges); | 
    
    |  |  | 
 | 
    
    |  |  | //link it to sprite as a secondary map | 
    
    |  |  | SpriteUtils.TryAddSecondaryTexture(spriteTi, "_EdgeMap", savedEdgePath); | 
    
    |  |  | 
 | 
    
    |  |  | //put sprite back the way it was. | 
    
    |  |  | spriteTi.isReadable = false; | 
    
    |  |  | 
 | 
    
    |  |  | 
 | 
    
    |  |  | } | 
    
    |  |  | 
 | 
    
    |  |  | private static string SaveEdges(Sprite s, string path, Texture2D edges) | 
    
    |  |  | { | 
    
    |  |  | var folder = path.Remove(path.LastIndexOf(s.name) - 1); | 
    
    |  |  | 
 | 
    
    |  |  | EditorUtils.LazyCreateFolder(folder, "EdgeMaps"); | 
    
    |  |  | 
 | 
    
    |  |  | var edgePath = $"{folder}/EdgeMaps/{s.name}_edges.png"; | 
    
    |  |  | 
 | 
    
    |  |  | var bytes = edges.EncodeToPNG(); | 
    
    |  |  | System.IO.File.WriteAllBytes(edgePath, bytes); | 
    
    |  |  | AssetDatabase.ImportAsset(edgePath, ImportAssetOptions.ForceSynchronousImport); | 
    
    |  |  | //AssetDatabase.CreateAsset(edges, edgePath); | 
    
    |  |  | 
 | 
    
    |  |  | var ti = AssetImporter.GetAtPath(edgePath) as TextureImporter; | 
    
    |  |  | ti.textureType = TextureImporterType.Sprite; | 
    
    |  |  | ti.filterMode = FilterMode.Point; | 
    
    |  |  | ti.textureCompression = TextureImporterCompression.Uncompressed; | 
    
    |  |  | ti.mipmapEnabled = false; | 
    
    |  |  | ti.alphaIsTransparency = false; | 
    
    |  |  | EditorUtility.SetDirty(ti); | 
    
    |  |  | ti.SaveAndReimport(); | 
    
    |  |  | 
 | 
    
    |  |  | return edgePath; | 
    
    |  |  | } | 
    
    |  |  | 
 | 
    
    |  |  | 
 | 
    
    |  |  | private static Texture2D BuildEdgeTexture(Sprite s) | 
    
    |  |  | { | 
    
    |  |  | var edges = new Texture2D(s.texture.width, s.texture.height, TextureFormat.RGBA32, false); | 
    
    |  |  | for (int x = 0; x < s.texture.width; x++) | 
    
    |  |  | { | 
    
    |  |  | for (int y = 0; y < s.texture.height; y++) | 
    
    |  |  | { | 
    
    |  |  | edges.SetPixel(x, y, GetEdge(s, x, y)); | 
    
    |  |  | } | 
    
    |  |  | } | 
    
    |  |  | edges.Apply(); | 
    
    |  |  | 
 | 
    
    |  |  | return edges; | 
    
    |  |  | } | 
    
    |  |  | 
 | 
    
    |  |  | //encodes edge information into 1 channel of the texture | 
    
    |  |  | private static Color GetEdge(Sprite s, int x, int y) | 
    
    |  |  | { | 
    
    |  |  | //MY COUNTERPART IS CustomRenderGraphBlock.hlsl.getSpriteEdges_float | 
    
    |  |  | var col = new Color(0, 0, 0, 0); | 
    
    |  |  | var px = s.texture.GetPixel(x, y); | 
    
    |  |  | if (px.a < 1) | 
    
    |  |  | { | 
    
    |  |  | return col; | 
    
    |  |  | } | 
    
    |  |  | else | 
    
    |  |  | { | 
    
    |  |  | for (int edgeTest = EDGE_SIZE; edgeTest >= 0; edgeTest--) | 
    
    |  |  | { | 
    
    |  |  | float edgeAlpha = 1f - (float)edgeTest / ((float)EDGE_SIZE + 1f); | 
    
    |  |  | //test up | 
    
    |  |  | if (IsEdge(s, x, y + edgeTest)) | 
    
    |  |  | col.r = edgeAlpha; | 
    
    |  |  | 
 | 
    
    |  |  | //test right | 
    
    |  |  | if (IsEdge(s, x + edgeTest, y)) | 
    
    |  |  | col.g = edgeAlpha; | 
    
    |  |  | 
 | 
    
    |  |  | //test left | 
    
    |  |  | if (IsEdge(s, x - edgeTest, y)) | 
    
    |  |  | col.b = edgeAlpha; | 
    
    |  |  | 
 | 
    
    |  |  | //test bot | 
    
    |  |  | if (IsEdge(s, x, y - edgeTest)) | 
    
    |  |  | col.a = edgeAlpha; | 
    
    |  |  | } | 
    
    |  |  | 
 | 
    
    |  |  | } | 
    
    |  |  | return col; | 
    
    |  |  | 
 | 
    
    |  |  | } | 
    
    |  |  | 
 | 
    
    |  |  | private static bool IsEdge(Sprite s, int x, int y) | 
    
    |  |  | { | 
    
    |  |  | if (x < 0 || y < 0 || x >= s.texture.width || y >= s.texture.height) | 
    
    |  |  | return true; | 
    
    |  |  | else return s.texture.GetPixel(x, y).a == 0f; | 
    
    |  |  | } | 
    
    |  |  | } | 
    
    |  |  | } |