private static bool CanPackTexturesInSize(Texture2D[] textures, int size, int padding, UITexturePacker.FreeRectChoiceHeuristic heuristic) { using (var packer = new UITexturePackerSpec(size, size, false)) { for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = new Rect(); int xPadding; int yPadding; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = packer.Insert(tex.width + (xPadding*padding), tex.height + (yPadding*padding), heuristic); if (rect.width > 0 && rect.height > 0) break; // After having no padding if it still doesn't fit -- we can't pack all textures in this size. else if (xPadding == 0 && yPadding == 0) { return false; } } if (rect.width > 0 && rect.height > 0) break; } } } return true; }
private static Texture2D CreateTexture(Texture2D[] textures, ref int?size, int padding, out Rect[] texRects, out int minAtlasSize, UITexturePacker.FreeRectChoiceHeuristic heuristic) { var result = new Texture2D(1, 1); minAtlasSize = GetMinAtlasSize(textures, size ?? 128, ref padding, size ?? 128, heuristic); Debug.Log("*************************** Min size = " + minAtlasSize + " - " + DateTime.Now); NGUISettings.forceSquareAtlas = true; texRects = UITexturePackerSpec.PackTexturesSpec(result, textures, minAtlasSize, minAtlasSize, padding, minAtlasSize, heuristic); Debug.Log("*************************** texture packed - " + DateTime.Now); if (size == null) { int power = (int)Math.Round(Math.Log(minAtlasSize, 2)); size = (int)Math.Pow(2, power); } if (size <= minAtlasSize) { TextureScale.Resize(result, size.Value, size.Value, InterpolationMode.HighQualityBicubic); } else { texRects = UITexturePackerSpec.PackTextures(result, textures, size.Value, size.Value, padding, size.Value); } return(result); }
private static bool CanPackTexturesInSize(Texture2D[] textures, int size, int padding, UITexturePacker.FreeRectChoiceHeuristic heuristic) { using (var packer = new UITexturePackerSpec(size, size, false)) { for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) { continue; } Rect rect = new Rect(); int xPadding; int yPadding; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = packer.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), heuristic); if (rect.width > 0 && rect.height > 0) { break; } // After having no padding if it still doesn't fit -- we can't pack all textures in this size. else if (xPadding == 0 && yPadding == 0) { return(false); } } if (rect.width > 0 && rect.height > 0) { break; } } } } return(true); }
public static Rect[] PackTexturesSpec(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize, FreeRectChoiceHeuristic heuristic) { if (width > maxSize && height > maxSize) { return(null); } if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } // Force square by sizing up if (NGUISettings.forceSquareAtlas) { if (width > height) { height = width; } else if (height > width) { width = height; } } Storage[] storage; using (var bp = new UITexturePackerSpec(width, height, false)) { storage = new Storage[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) { continue; } Rect rect = new Rect(); int xPadding = 1; int yPadding = 1; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = bp.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), heuristic); if (rect.width > 0 && rect.height > 0) { break; } // After having no padding if it still doesn't fit -- increase texture size. else if (xPadding == 0 && yPadding == 0) { return(PackTexturesSpec(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize, heuristic)); } } if (rect.width > 0 && rect.height > 0) { break; } } storage[i] = new Storage(); storage[i].rect = rect; storage[i].paddingX = (xPadding != 0); storage[i].paddingY = (yPadding != 0); } } texture.Resize(width, height); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { texture.SetPixel(i, j, new Color()); } } // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) { continue; } Rect rect = storage[i].rect; int xPadding = (storage[i].paddingX ? padding : 0); int yPadding = (storage[i].paddingY ? padding : 0); Color[] colors = tex.GetPixels(); // Would be used to rotate the texture if need be. if (rect.width != tex.width + xPadding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((int)rect.height - (y + 1)) + x * (int)tex.width; newColors[x + y * (int)rect.width] = colors[prevIndex]; } } colors = newColors; } texture.SetPixels((int)rect.x, (int)rect.y, (int)rect.width - xPadding, (int)rect.height - yPadding, colors); rect.x /= width; rect.y /= height; rect.width = (rect.width - xPadding) / width; rect.height = (rect.height - yPadding) / height; rects[i] = rect; } texture.Apply(); return(rects); }
public static Rect[] PackTexturesSpec(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize, FreeRectChoiceHeuristic heuristic) { if (width > maxSize && height > maxSize) return null; if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } // Force square by sizing up if (NGUISettings.forceSquareAtlas) { if (width > height) height = width; else if (height > width) width = height; } Storage[] storage; using (var bp = new UITexturePackerSpec(width, height, false)) { storage = new Storage[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = new Rect(); int xPadding = 1; int yPadding = 1; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = bp.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), heuristic); if (rect.width > 0 && rect.height > 0) break; // After having no padding if it still doesn't fit -- increase texture size. else if (xPadding == 0 && yPadding == 0) { return PackTexturesSpec(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize, heuristic); } } if (rect.width > 0 && rect.height > 0) break; } storage[i] = new Storage(); storage[i].rect = rect; storage[i].paddingX = (xPadding != 0); storage[i].paddingY = (yPadding != 0); } } texture.Resize(width, height); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { texture.SetPixel(i, j, new Color()); } } // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (!tex) continue; Rect rect = storage[i].rect; int xPadding = (storage[i].paddingX ? padding : 0); int yPadding = (storage[i].paddingY ? padding : 0); Color[] colors = tex.GetPixels(); // Would be used to rotate the texture if need be. if (rect.width != tex.width + xPadding) { Color[] newColors = tex.GetPixels(); for (int x = 0; x < rect.width; x++) { for (int y = 0; y < rect.height; y++) { int prevIndex = ((int)rect.height - (y + 1)) + x * (int)tex.width; newColors[x + y * (int)rect.width] = colors[prevIndex]; } } colors = newColors; } texture.SetPixels((int)rect.x, (int)rect.y, (int)rect.width - xPadding, (int)rect.height - yPadding, colors); rect.x /= width; rect.y /= height; rect.width = (rect.width - xPadding) / width; rect.height = (rect.height - yPadding) / height; rects[i] = rect; } texture.Apply(); return rects; }