diff --git a/Assembly-CSharp.Base.mm/src/Core/RuntimeAtlas.cs b/Assembly-CSharp.Base.mm/src/Core/RuntimeAtlas.cs index 7ebf2a3..05f70c4 100644 --- a/Assembly-CSharp.Base.mm/src/Core/RuntimeAtlas.cs +++ b/Assembly-CSharp.Base.mm/src/Core/RuntimeAtlas.cs @@ -2,8 +2,8 @@ using UnityEngine; using System.Collections.Generic; -public class RuntimeAtlasPacker { - +public class RuntimeAtlasPacker +{ public List Pages = new List(); public int Width; @@ -11,7 +11,8 @@ public class RuntimeAtlasPacker { public TextureFormat Format; public int Padding; - public RuntimeAtlasPacker(int width = 0, int height = 0, TextureFormat format = TextureFormat.RGBA32, int padding = 2) { + public RuntimeAtlasPacker(int width = 0, int height = 0, TextureFormat format = TextureFormat.RGBA32, int padding = 2) + { if (width == 0) width = RuntimeAtlasPage.DefaultSize; if (height == 0) height = RuntimeAtlasPage.DefaultSize; @@ -21,11 +22,14 @@ public RuntimeAtlasPacker(int width = 0, int height = 0, TextureFormat format = Padding = padding; } - public RuntimeAtlasSegment Pack(Texture2D tex, bool apply = false) { + public RuntimeAtlasSegment Pack(Texture2D tex, bool apply = false) + { RuntimeAtlasSegment segment; - for (int i = 0; i < Pages.Count; i++) { - if ((segment = Pages[i].Pack(tex, apply)) != null) { + for (int i = 0; i < Pages.Count; i++) + { + if ((segment = Pages[i].Pack(tex, apply)) != null) + { return segment; } } @@ -34,30 +38,34 @@ public RuntimeAtlasSegment Pack(Texture2D tex, bool apply = false) { } public Action OnNewPage; - public RuntimeAtlasPage NewPage() { + public RuntimeAtlasPage NewPage() + { RuntimeAtlasPage page = new RuntimeAtlasPage(Width, Height, Format, Padding); Pages.Add(page); OnNewPage?.Invoke(page); return page; } - public void Apply() { - for (int i = 0; i < Pages.Count; i++) { + public void Apply() + { + for (int i = 0; i < Pages.Count; i++) + { Pages[i].Apply(); } } - public bool IsPageTexture(Texture2D tex) { - for (int i = 0; i < Pages.Count; i++) { + public bool IsPageTexture(Texture2D tex) + { + for (int i = 0; i < Pages.Count; i++) + { if (ReferenceEquals(Pages[i].Texture, tex)) return true; } return false; } - } -public class RuntimeAtlasPage { - +public class RuntimeAtlasPage +{ public static int DefaultSize = Math.Min(SystemInfo.maxTextureSize, 4096); public List Segments = new List(); @@ -69,7 +77,14 @@ public class RuntimeAtlasPage { protected List _Rects = new List(); protected int _Changes; - public RuntimeAtlasPage(int width = 0, int height = 0, TextureFormat format = TextureFormat.RGBA32, int padding = 2) { + private static readonly int BlockSize = 128; + private static readonly Color32[] DefaultBlock = CreateDefaultBlock(); + private static readonly Color32 Default = new Color32(0, 0, 0, 0); + + private float _startingX, _currentY, _nextYLine; + + public RuntimeAtlasPage(int width = 0, int height = 0, TextureFormat format = TextureFormat.RGBA32, int padding = 2) + { if (width == 0) width = DefaultSize; if (height == 0) height = DefaultSize; @@ -77,15 +92,12 @@ public RuntimeAtlasPage(int width = 0, int height = 0, TextureFormat format = Te Texture.wrapMode = TextureWrapMode.Clamp; Texture.filterMode = FilterMode.Point; Texture.anisoLevel = 0; - Color[] data = new Color[128 * 128]; - Color blank = new Color(0f, 0f, 0f, 0f); - for (int i = 0; i < data.Length; i++) { - data[i] = blank; - } - for (int y = 0; y < height; y += 128) { - for (int x = 0; x < width; x += 128) { - Texture.SetPixels(x, y, 128, 128, data); + for (int y = 0; y < height; y += BlockSize) + { + for (int x = 0; x < width; x += BlockSize) + { + Texture.SetPixels32(x, y, BlockSize, BlockSize, DefaultBlock); } } @@ -94,116 +106,81 @@ public RuntimeAtlasPage(int width = 0, int height = 0, TextureFormat format = Te Padding = padding; } - private Rect texRect = new Rect(); - private bool right = true; - public RuntimeAtlasSegment Pack(Texture2D tex, bool apply = false) { - texRect.Set(Padding, Padding, tex.width + Padding, tex.height + Padding); - bool fit = _Rects.Count == 0; - - if (right) { - if (!fit) - for (int i = _Rects.Count - 1; 0 <= i; i--) { - Rect existing = _Rects[i]; - - texRect.x = existing.xMax + Padding; - texRect.y = existing.y; - if (_Feasible(texRect, i)) { - fit = true; - right = true; - break; - } - } - - if (!fit) - for (int i = 0; i < _Rects.Count; i++) { - Rect existing = _Rects[i]; - - texRect.x = existing.x; - texRect.y = existing.yMax + Padding; - if (_Feasible(texRect, i)) { - fit = true; - right = false; - break; - } - } - } else { - if (!fit) - for (int i = 0; i < _Rects.Count; i++) { - Rect existing = _Rects[i]; - - texRect.x = existing.x; - texRect.y = existing.yMax + Padding; - if (_Feasible(texRect, i)) { - fit = true; - right = false; - break; - } - } - - if (!fit) - for (int i = _Rects.Count - 1; 0 <= i; i--) { - Rect existing = _Rects[i]; - - texRect.x = existing.xMax + Padding; - texRect.y = existing.y; - if (_Feasible(texRect, i)) { - fit = true; - right = true; - break; - } - } + public RuntimeAtlasSegment Pack(Texture2D tex, bool apply = false) + { + var texRect = new Rect(); + texRect.Set(_startingX + Padding, _currentY + Padding, tex.width + Padding, tex.height + Padding); + + if (_MainRect.Contains(texRect)) + { + _startingX = texRect.xMax; + _nextYLine = Math.Max(texRect.yMax, _nextYLine); } + else + { + _startingX = 0; + _currentY = _nextYLine; + + texRect.Set(_startingX + Padding, _currentY + Padding, tex.width + Padding, tex.height + Padding); - if (!fit) { - return null; + if (_MainRect.Contains(texRect)) + { + _startingX = texRect.xMax; + _nextYLine = Math.Max(texRect.yMax, _nextYLine); + } + else + { + return null; + } } _Rects.Add(texRect); - RuntimeAtlasSegment segment = new RuntimeAtlasSegment() { + var segment = new RuntimeAtlasSegment() + { texture = Texture, x = Mathf.RoundToInt(texRect.x), y = Mathf.RoundToInt(texRect.y), width = tex.width, height = tex.height }; + Segments.Add(segment); - Texture.SetPixels(segment.x, segment.y, segment.width, segment.height, tex.GetPixels()); + Texture.SetPixels32(segment.x, segment.y, segment.width, segment.height, tex.GetPixels32()); ++_Changes; - if (apply) { + if (apply) + { Apply(); } return segment; } - protected bool _Feasible(Rect rect, int skip) { - if (!_MainRect.Contains(rect)) { - return false; - } - for (int i = 0; i < _Rects.Count; i++) { - if (i == skip) continue; - Rect existing = _Rects[i]; - if (existing.Overlaps(rect)) { - return false; - } - } - return true; - } - - public void Apply() { - if (_Changes == 0) { + public void Apply() + { + if (_Changes == 0) + { return; } _Changes = 0; Texture.Apply(false, false); } -} + private static Color32[] CreateDefaultBlock() + { + Color32[] data = new Color32[BlockSize * BlockSize]; + for (int i = 0; i < data.Length; i++) + { + data[i] = Default; + } -public class RuntimeAtlasSegment { + return data; + } +} +public class RuntimeAtlasSegment +{ public Texture2D texture; public int x; @@ -211,8 +188,8 @@ public class RuntimeAtlasSegment { public int width; public int height; - public Vector2[] uvs { + public Vector2[] uvs + { get { return ETGMod.Assets.GenerateUVs(texture, x, y, width, height); } } - }