public static Rect[] Combine(Texture2D texture, Texture2D[] textures, int width, int height, bool forceSquare, int padding, int maxSize) { PackingResult result = new PackingResult(); if (!TexCombine.Packing(ref result, textures, width, height, forceSquare, padding, maxSize)) { return(null); } width = result.width; height = result.height; texture.Resize(width, height); texture.SetPixels(new Color[width * height]); // The returned rects Rect[] rects = new Rect[textures.Length]; for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (tex == null) { continue; } Rect rect = result.data[i].rect; int xPadding = (result.data[i].paddingX ? padding : 0); int yPadding = (result.data[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); }
private static bool Packing(ref PackingResult result, Texture2D[] textures, int width, int height, bool forceSquare, int padding, int maxSize) { if (width > maxSize && height > maxSize) { return(false); } if (width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; } if (forceSquare) { if (width > height) { height = width; } else if (height > width) { width = height; } } if (result.packing == null) { result.packing = new RectangularPacking(width, height, false); } else { result.packing.Reset(width, height, false); } result.width = width; result.height = height; if (result.data == null) { result.data = new PackingData[textures.Length]; } for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (tex == null) { continue; } Rect rect = default(Rect); int xPadding = 1; int yPadding = 1; for (xPadding = 1; xPadding >= 0; --xPadding) { for (yPadding = 1; yPadding >= 0; --yPadding) { rect = result.packing.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), RectangularPacking.Heuristic.BestAreaFit); 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(TexCombine.Packing(ref result, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), forceSquare, padding, maxSize)); } } if (rect.width != 0 && rect.height != 0) { break; } } result.data[i].rect = rect; result.data[i].paddingX = (xPadding != 0); result.data[i].paddingY = (yPadding != 0); } return(true); }