public static Rect[] Spliter(Rect[] rects, int maxSize, int padding, ref Rect ret, int startWidth, int startHeight,  bool resizeRect, bool isWHSame, int cellSize )
        {
            int w = 1;
            int h = 1;

            if (resizeRect)
            {
                foreach (Rect rc in rects)
                {
                    if (w < rc.width)
                        w = (int)rc.width;

                    if (h < rc.height)
                        h = (int)rc.height;
                }

                w = Mathf.NextPowerOfTwo(w);
                h = Mathf.NextPowerOfTwo(h);
            }
            else
            {
                w = startWidth;
                h = startHeight;
            }


            while (true)
            {
                List<Rect> rcs = new List<Rect>(rects);

                RectSpliter spliter = new RectSpliter(new Rect(0, 0, w, h), cellSize);

                bool isAllocFail = false;
                for (int i = 0; i < rcs.Count; i++)
                {
                    Rect tmp = rcs[i];
                    tmp.width += padding;
                    tmp.height += padding;

                    bool r = spliter.AllocRect(ref tmp);

                    if (!r)
                    {
                        isAllocFail = true;
                        break;
                    }
                    rcs[i] = tmp;
                }

                if (!isAllocFail)
                {
                    ret = spliter.rect;
                    return rcs.ToArray();
                }
                else
                {
                    if (!resizeRect)
                        return null;

                    if (!isWHSame)
                    {
                        if (w > h)
                            h *= 2;
                        else
                            w *= 2;
                    }
                    else
                    {
                        w *= 2;
                        h = w;
                    }
                }

                if (w > maxSize || h > maxSize)
                    return null;
            }

            return null;
        }
Example #2
0
        /// <summary>
        /// Pack sprites into a texture. Usually use to building atlas in runtime.
        /// The sprite's image texture should be readable.
        /// </summary>
        /// <param name="sprites">Array of sprites you want pack.</param>
        /// <param name="packSize">The target texture size.</param>
        /// <param name="mipmap">Not used.</param>
        /// <returns>Return true successed, false means sprites can not layout in the size of texture.</returns>
        public static bool PackSprites(Sprite[] sprites, int packSize, bool mipmap)
        {
            List <Sprite> sprs = new List <Sprite>(sprites);

            sprs.Sort(sortByHeight);
            sprs.Reverse();


            List <Rect> rects = new List <Rect>();

            foreach (Sprite item in sprs)
            {
                rects.Add(item.imageRect);
            }


            Rect retRc = new Rect();

            Rect[] ret = RectSpliter.Spliter(rects.ToArray(), packSize, 1, ref retRc, packSize, packSize, false, true, 4);


            if (ret != null)
            {
                if (ret.Length > 0)
                {
                    Texture2D tex  = new Texture2D(packSize, packSize, TextureFormat.ARGB32, mipmap);
                    Color32   c    = new Color32(0, 0, 0, 0);
                    Color32[] _buf = tex.GetPixels32();
                    for (int ci = 0; ci < _buf.Length; ci++)
                    {
                        _buf[ci] = c;
                    }
                    tex.SetPixels32(_buf);


                    int i = 0;
                    foreach (Rect rc in ret)
                    {
                        Sprite spr = sprs[i];

                        Rect src = new Rect(
                            spr.imageRect.x,
                            spr.image.height - spr.imageRect.y - spr.imageRect.height,
                            spr.imageRect.width, spr.imageRect.height);

                        Rect dst = new Rect(
                            rc.x,
                            tex.height - rc.y - spr.imageRect.height,
                            spr.imageRect.width, spr.imageRect.height
                            );

                        Color[] buf = spr.image.GetPixels((int)src.x, (int)src.y, (int)src.width, (int)src.height);
                        tex.SetPixels((int)dst.x, (int)dst.y, (int)dst.width, (int)dst.height, buf);


                        spr.image     = tex;
                        spr.atlas     = null;
                        spr.imageRect = new Rect(rc.x, rc.y, spr.imageRect.width, spr.imageRect.height);

                        spr.Init();

                        i++;
                    }

                    tex.Apply();

                    return(true);
                }
            }

            return(false);
        }
        public static Rect[] Spliter(Rect[] rects, int maxSize, int padding, ref Rect ret, int startWidth, int startHeight, bool resizeRect, bool isWHSame, int cellSize)
        {
            int w = 1;
            int h = 1;

            if (resizeRect)
            {
                foreach (Rect rc in rects)
                {
                    if (w < rc.width)
                    {
                        w = (int)rc.width;
                    }

                    if (h < rc.height)
                    {
                        h = (int)rc.height;
                    }
                }

                w = Mathf.NextPowerOfTwo(w);
                h = Mathf.NextPowerOfTwo(h);
            }
            else
            {
                w = startWidth;
                h = startHeight;
            }


            while (true)
            {
                List <Rect> rcs = new List <Rect>(rects);

                RectSpliter spliter = new RectSpliter(new Rect(0, 0, w, h), cellSize);

                bool isAllocFail = false;
                for (int i = 0; i < rcs.Count; i++)
                {
                    Rect tmp = rcs[i];
                    tmp.width  += padding;
                    tmp.height += padding;

                    bool r = spliter.AllocRect(ref tmp);

                    if (!r)
                    {
                        isAllocFail = true;
                        break;
                    }
                    rcs[i] = tmp;
                }

                if (!isAllocFail)
                {
                    ret = spliter.rect;
                    return(rcs.ToArray());
                }
                else
                {
                    if (!resizeRect)
                    {
                        return(null);
                    }

                    if (!isWHSame)
                    {
                        if (w > h)
                        {
                            h *= 2;
                        }
                        else
                        {
                            w *= 2;
                        }
                    }
                    else
                    {
                        w *= 2;
                        h  = w;
                    }
                }

                if (w > maxSize || h > maxSize)
                {
                    return(null);
                }
            }

            return(null);
        }