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
                });
            }
Beispiel #2
0
        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);
            }
        }