public static Score GetScore(PackTexture lhs, PackTexture rhs) { int match = lhs.MultipleTextures.Intersect(rhs.MultipleTextures).Count(); return(new Score() { Lhs = lhs, Rhs = rhs, Match = match }); }
private TextureAtlas MakeTextureAtlas(PackTexture packTexture, int packTextureSize) { TextureAtlas atlas = ScriptableObject.CreateInstance <TextureAtlas>(); Texture2D textureAtlas = new Texture2D(packTextureSize, packTextureSize, TextureFormat.RGBA32, false); int itemCount = (int)Math.Sqrt(packTexture.PackableTextureCount); int itemSize = packTextureSize / itemCount; int index = 0; atlas.uvs = new Rect[packTexture.Textures.Count]; atlas.textures = packTexture.Textures.ToArray(); foreach (var texture in atlas.textures) { int width, height; Color[] buffer = GetTextureColors(texture, itemSize, out width, out height); int col = index % itemCount; int row = index / itemCount; int x = col * itemSize; int y = row * itemSize; textureAtlas.SetPixels(x, y, width, height, buffer); atlas.uvs[index] = new Rect( (float)x / (float)packTextureSize, (float)y / (float)packTextureSize, (float)width / (float)packTextureSize, (float)height / (float)packTextureSize); index += 1; } textureAtlas.Apply(); var name = Path.GetRandomFileName(); textureAtlas = SaveTexture(textureAtlas, name); atlas.textureAtlas = textureAtlas; return(atlas); }
private TextureAtlas MakeTextureAtlas(PackTexture packTexture, int packTextureSize) { TextureAtlas atlas = new TextureAtlas(); //Texture2D packedTexture = new Texture2D(packTextureSize, packTextureSize, TextureFormat.RGBA32, false); int itemCount = (int)Math.Sqrt(packTexture.PackableTextureCount); int itemSize = packTextureSize / itemCount; int packedTextureCount = 0; int index = 0; foreach (var multipleTexture in packTexture.MultipleTextures) { packedTextureCount = Math.Max(packedTextureCount, multipleTexture.textureList.Count); } Texture2D[] packedTexture = new Texture2D[packedTextureCount]; for (int i = 0; i < packedTextureCount; ++i) { packedTexture[i] = new Texture2D(packTextureSize, packTextureSize, TextureFormat.RGBA32, false); } atlas.UVs = new Rect[packTexture.MultipleTextures.Count]; atlas.MultipleTextures = packTexture.MultipleTextures.ToArray(); foreach (var texture in atlas.MultipleTextures) { int width = 0, height = 0; Color[] buffer = GetTextureColors(texture.textureList[0], itemSize, out width, out height); int col = index % itemCount; int row = index / itemCount; int x = col * itemSize; int y = row * itemSize; packedTexture[0].SetPixels(x, y, width, height, buffer); atlas.UVs[index] = new Rect( (float)x / (float)packTextureSize, (float)y / (float)packTextureSize, (float)width / (float)packTextureSize, (float)height / (float)packTextureSize); index += 1; for (int i = 1; i < texture.textureList.Count; ++i) { int extWidth = 0, extHeight = 0; Color[] extBuffer = GetTextureColors(texture.textureList[i], itemSize, out extWidth, out extHeight); if (extWidth != width || extHeight != height) { Debug.Log("Resize texture: " + width + "_" + extWidth + ", " + height + "_" + extHeight); extBuffer = ResizeImage(extBuffer, extWidth, extHeight, width, height); } packedTexture[i].SetPixels(x, y, width, height, extBuffer); } } for (int i = 0; i < packedTexture.Length; ++i) { packedTexture[i].Apply(); } atlas.PackedTexture = packedTexture; return(atlas); }
public void Pack(int packTextureSize, int maxPieceSize) { //First, we should separate each group by count. Dictionary <int, List <Group> > groupCluster = new Dictionary <int, List <Group> >(); for (int i = 0; i < groups.Count; ++i) { Group group = groups[i]; int maximum = GetMaximumTextureCount(packTextureSize, maxPieceSize, group.multipleTextures.Count); if (groupCluster.ContainsKey(maximum) == false) { groupCluster[maximum] = new List <Group>(); } groupCluster[maximum].Add(group); } //Second, we should figure out which group should be combined from each cluster. foreach (var cluster in groupCluster) { int maximum = cluster.Key; List <PackTexture> packTextures = new List <PackTexture>(); foreach (var group in cluster.Value) { packTextures.Add(new PackTexture() { Objects = new List <object>() { group.obj }, MultipleTextures = new HashSet <MultipleTexture>(group.multipleTextures, new MultipleTextureComparer()), PackableTextureCount = maximum }); } List <Score> scoreList = new List <Score>(); for (int i = 0; i < packTextures.Count; ++i) { for (int j = i + 1; j < packTextures.Count; ++j) { scoreList.Add(Score.GetScore(packTextures[i], packTextures[j])); } } scoreList.Sort((lhs, rhs) => rhs.Match - lhs.Match); for (int i = 0; i < scoreList.Count; ++i) { HashSet <MultipleTexture> unionMultipleTextures = new HashSet <MultipleTexture>(scoreList[i].Lhs.MultipleTextures.Union(scoreList[i].Rhs.MultipleTextures), new MultipleTextureComparer()); if (unionMultipleTextures.Count <= maximum) { PackTexture lhs = scoreList[i].Lhs; PackTexture rhs = scoreList[i].Rhs; List <object> newObjects = new List <object>(scoreList[i].Lhs.Objects.Concat(scoreList[i].Rhs.Objects)); PackTexture newPackTexture = new PackTexture() { Objects = newObjects, MultipleTextures = unionMultipleTextures, PackableTextureCount = maximum }; packTextures.Remove(lhs); packTextures.Remove(rhs); packTextures.Add(newPackTexture); //Remove merged Score and make Score by new Pack Texture. scoreList.RemoveAll(score => score.Lhs == lhs || score.Lhs == rhs || score.Rhs == lhs || score.Rhs == rhs); for (int j = 0; j < packTextures.Count - 1; ++j) { scoreList.Add(Score.GetScore(packTextures[j], newPackTexture)); } scoreList.Sort((l, r) => r.Match - l.Match); //for start first loop i = -1; } } foreach (var pack in packTextures) { var atlas = MakeTextureAtlas(pack, packTextureSize); atlasGroups.Add(new AtlasGroup() { Objects = pack.Objects, Atlas = atlas }); } Debug.Log("Packing count : " + maximum + ", textures : " + packTextures.Count); } }