From 9f5240967a51692fa2a17a6b3c8d124dd5dc60f9 Mon Sep 17 00:00:00 2001 From: Kiryl Tkachou Date: Fri, 26 Jul 2019 15:52:40 +0300 Subject: [PATCH] Added bilinear scaling and mesh replacing export mode --- .../Utils/MA_TextureAtlasserProUtils.cs | 21 +++- .../MA_TextureAtlasserProExportWindow.cs | 4 +- .../TextureUtils/MA_TextureUtils.cs | 10 +- .../TextureUtils/TextureScaler.cs | 103 ++++++++++++++++++ 4 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 MA_ToolBox/MA_Utilities/TextureUtils/TextureScaler.cs diff --git a/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs b/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs index 130e3eb..963bc56 100644 --- a/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs +++ b/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Utils/MA_TextureAtlasserProUtils.cs @@ -315,6 +315,25 @@ namespace MA_TextureAtlasserPro } } + public static void ModifyMeshes(MA_TextureAtlasserProAtlas atlas) + { + if (atlas == null || atlas.textureQuads == null) return; + var quads = atlas.textureQuads; + for (var index = 0; index < quads.Count; index++) + { + var quad = quads[index]; + if (quad.meshes == null) continue; + var meshes = quad.meshes; + for (var meshIndex = 0; meshIndex < quad.meshes.Count; meshIndex++) + { + if (meshes[meshIndex] == null) continue; + MA_MeshUtils.MA_UVReMap(meshes[meshIndex], atlas.textureAtlasSize, quad.guiRect); + EditorUtility.SetDirty(meshes[meshIndex]); + } + } + AssetDatabase.SaveAssets(); + } + // public static void ExportAtlasTexturePNG(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH) // { // if(atlas != null && atlas.textureQuads != null) @@ -363,7 +382,7 @@ namespace MA_TextureAtlasserPro //Create new texture part Texture2D newTexturePart = (Texture2D)MA_Texture.MA_TextureUtils.ConvertToReadableTexture(q.textureGroups[i].texture); //Scale it - newTexturePart = newTexturePart.MA_Scale32D((int)q.guiRect.width, (int)q.guiRect.height); + newTexturePart = newTexturePart.ScaleTexture((int)q.guiRect.width, (int)q.guiRect.height, true); //Add it newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y); } diff --git a/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs b/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs index 48110a5..894b55f 100644 --- a/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs +++ b/MA_ToolBox/MA_TextureAtlasserPro/Scripts/Editor/Windows/MA_TextureAtlasserProExportWindow.cs @@ -130,9 +130,7 @@ namespace MA_TextureAtlasserPro } if (_replaceMeshes) - { - - } + MA_TextureAtlasserProUtils.ModifyMeshes(curWindow.textureAtlas); if(exportPngDefault) { diff --git a/MA_ToolBox/MA_Utilities/TextureUtils/MA_TextureUtils.cs b/MA_ToolBox/MA_Utilities/TextureUtils/MA_TextureUtils.cs index 38641df..6fad41b 100644 --- a/MA_ToolBox/MA_Utilities/TextureUtils/MA_TextureUtils.cs +++ b/MA_ToolBox/MA_Utilities/TextureUtils/MA_TextureUtils.cs @@ -44,6 +44,7 @@ namespace MA_Texture // Copy the pixels from the RenderTexture to the new Texture myTexture2D.ReadPixels(new Rect(0, 0, tmp.width, tmp.height), 0, 0); myTexture2D.Apply(); + myTexture2D.name = texture.name; // Reset the active RenderTexture RenderTexture.active = previous; @@ -174,11 +175,18 @@ namespace MA_Texture } } - newTexture.name = texture.name; + newTexture.name = texture.name; newTexture.Apply(); return newTexture; } + + public static Texture2D ScaleTexture(this Texture2D texture, int width, int height, bool bilinear) + { + TextureScaler.Scale(texture, width, height, bilinear); + return texture; + } + #endregion #region combine diff --git a/MA_ToolBox/MA_Utilities/TextureUtils/TextureScaler.cs b/MA_ToolBox/MA_Utilities/TextureUtils/TextureScaler.cs new file mode 100644 index 0000000..698de7e --- /dev/null +++ b/MA_ToolBox/MA_Utilities/TextureUtils/TextureScaler.cs @@ -0,0 +1,103 @@ +using System.Threading; +using UnityEngine; + +namespace MA_Texture +{ + public static class TextureScaler + { + public class ThreadData + { + public int start; + public int end; + public ThreadData (int s, int e) { + start = s; + end = e; + } + } + + private static Color[] texColors; + private static Color[] newColors; + private static int w; + private static float ratioX; + private static float ratioY; + private static int w2; + private static int finishCount; + + public static void Scale (Texture2D tex, int newWidth, int newHeight, bool useBilinear) + { + texColors = tex.GetPixels(); + newColors = new Color[newWidth * newHeight]; + if (useBilinear) + { + ratioX = 1.0f / ((float)newWidth / (tex.width-1)); + ratioY = 1.0f / ((float)newHeight / (tex.height-1)); + } + else { + ratioX = ((float)tex.width) / newWidth; + ratioY = ((float)tex.height) / newHeight; + } + w = tex.width; + w2 = newWidth; + finishCount = 0; + if (useBilinear) + { + BilinearScale(0, newHeight); + } + else + { + PointScale(0, newHeight); + } + + + tex.Resize(newWidth, newHeight); + tex.SetPixels(newColors); + tex.Apply(); + + texColors = null; + newColors = null; + } + + public static void BilinearScale (int start, int end) + { + for (var y = start; y < end; y++) + { + int yFloor = (int)Mathf.Floor(y * ratioY); + var y1 = yFloor * w; + var y2 = (yFloor+1) * w; + var yw = y * w2; + + for (var x = 0; x < w2; x++) { + int xFloor = (int)Mathf.Floor(x * ratioX); + var xLerp = x * ratioX-xFloor; + newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor+1], xLerp), + ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor+1], xLerp), + y*ratioY-yFloor); + } + } + + finishCount++; + } + + public static void PointScale (int start, int end) + { + for (var y = start; y < end; y++) + { + var thisY = (int)(ratioY * y) * w; + var yw = y * w2; + for (var x = 0; x < w2; x++) { + newColors[yw + x] = texColors[(int)(thisY + ratioX*x)]; + } + } + + finishCount++; + } + + private static Color ColorLerpUnclamped (Color c1, Color c2, float value) + { + return new Color (c1.r + (c2.r - c1.r)*value, + c1.g + (c2.g - c1.g)*value, + c1.b + (c2.b - c1.b)*value, + c1.a + (c2.a - c1.a)*value); + } + } +} \ No newline at end of file