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;
    }
Example #2
0
    /// <summary>
    /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed.
    /// </summary>

    static void PackTextures(Texture2D tex, List <SpriteEntry> sprites)
    {
        Texture2D[] textures = new Texture2D[sprites.Count];
        Rect[]      rects;


        if (NGUISettings.unityPacking)
        {
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }

            rects = tex.PackTextures(textures, NGUISettings.atlasPadding, 4096);
        }
        else
        {
            sprites.Sort(Compare);
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = UITexturePacker.PackTextures(tex, textures, 4, 4, NGUISettings.atlasPadding, 4096);
        }

        for (int i = 0; i < sprites.Count; ++i)
        {
            sprites[i].rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);
            //BleedTexture(tex, sprites[i].rect);
        }
    }
    /// <summary>
    /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed.
    /// </summary>

    static bool PackTextures(Texture2D tex, List <SpriteEntry> sprites)
    {
        Texture2D[] textures = new Texture2D[sprites.Count];
        Rect[]      rects;

#if UNITY_3_5 || UNITY_4_0
        int maxSize = 4096;
#else
        int maxSize = SystemInfo.maxTextureSize;
#endif

#if UNITY_ANDROID || UNITY_IPHONE
#if !UNITY_3_5 && !UNITY_4_0
        if (PlayerSettings.targetGlesGraphics == TargetGlesGraphics.OpenGLES_1_x)
        {
            maxSize = Mathf.Min(maxSize, 1024);
        }
        else
#endif
        {
            maxSize = Mathf.Min(maxSize, NGUISettings.allow4096 ? 4096 : 2048);
        }
#endif

        if (NGUISettings.unityPacking)
        {
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = tex.PackTextures(textures, NGUISettings.atlasPadding, maxSize);
        }
        else
        {
            sprites.Sort(Compare);
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = UITexturePacker.PackTextures(tex, textures, 4, 4, NGUISettings.atlasPadding, maxSize);
        }

        for (int i = 0; i < sprites.Count; ++i)
        {
            Rect rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);

            // Make sure that we don't shrink the textures
            if (Mathf.RoundToInt(rect.width) != textures[i].width)
            {
                return(false);
            }

            SpriteEntry se = sprites[i];
            se.x      = Mathf.RoundToInt(rect.x);
            se.y      = Mathf.RoundToInt(rect.y);
            se.width  = Mathf.RoundToInt(rect.width);
            se.height = Mathf.RoundToInt(rect.height);
        }
        return(true);
    }
    public static int CreateUIAtlas(List<Texture2D> images, string atlasName, int? size, out int minSize, UITexturePacker.FreeRectChoiceHeuristic heuristic)
    {
        string selectionFolder = NGUIEditorTools.GetSelectionFolder();
        if (string.IsNullOrEmpty(atlasName))
        {
            var lastIndexOf = selectionFolder.Substring(0, selectionFolder.Length - 1).LastIndexOf("/");
            atlasName = selectionFolder.Substring(lastIndexOf + 1, selectionFolder.Length - lastIndexOf - 2);
        }

        UIAtlas atlas;
        string prefabPath = AssetDatabase.GetAllAssetPaths().FirstOrDefault(x => x.EndsWith("/" + atlasName + ".prefab"));
        if (prefabPath == null)
        {
            prefabPath = selectionFolder + atlasName + ".prefab";
            atlas = CreateAtlas(atlasName);
        }
        else
        {
            Debug.Log("Update existing");
            atlas = AssetDatabase.LoadAssetAtPath(prefabPath, typeof (UIAtlas)) as UIAtlas;
        }

        Texture2D newTexture = UpdateUIAtlas(atlas, images, ref size, out minSize, heuristic);
        var texture = SaveTexture(prefabPath, newTexture);
        atlas.spriteMaterial.mainTexture = texture;

        EditorUtility.SetDirty(atlas);

        // Update the prefab
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        Debug.Log("***************** All done - " + DateTime.Now);
        return size.Value;
    }
Example #5
0
    /// <summary>
    /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed.
    /// </summary>

    static bool PackTextures(Texture2D tex, List <SpriteEntry> sprites)
    {
        var textures = new Texture2D[sprites.Count];

        Rect[] rects;

#if UNITY_3_5 || UNITY_4_0
        int maxSize = 4096;
#else
        var maxSize = SystemInfo.maxTextureSize;
#endif

#if UNITY_ANDROID || UNITY_IPHONE
        maxSize = Mathf.Min(maxSize, NGUISettings.allow4096 ? 4096 : 2048);
#endif
        if (NGUISettings.unityPacking)
        {
            for (var i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = tex.PackTextures(textures, NGUISettings.atlasPadding, maxSize);
        }
        else
        {
            sprites.Sort(Compare);
            for (var i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = UITexturePacker.PackTextures(tex, textures, 4, 4, NGUISettings.atlasPadding, maxSize);
        }

        for (var i = 0; i < sprites.Count; ++i)
        {
            var rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);

            // Apparently Unity can take the liberty of destroying temporary textures without any warning
            if (textures[i] == null)
            {
                return(false);
            }

            // Make sure that we don't shrink the textures
            if (Mathf.RoundToInt(rect.width) != textures[i].width)
            {
                return(false);
            }

            var se = sprites[i];
            se.x      = Mathf.RoundToInt(rect.x);
            se.y      = Mathf.RoundToInt(rect.y);
            se.width  = Mathf.RoundToInt(rect.width);
            se.height = Mathf.RoundToInt(rect.height);
        }
        return(true);
    }
Example #6
0
    /// <summary>
    /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed.
    /// </summary>

    static void PackTextures(Texture2D tex, List <SpriteEntry> sprites)
    {
        Texture2D[] textures = new Texture2D[sprites.Count];
        for (int i = 0; i < sprites.Count; ++i)
        {
            textures[i] = sprites[i].tex;
        }

        //Rect[] rects = tex.PackTextures(textures, 1, 4096);
        Rect[] rects = UITexturePacker.PackTextures(tex, textures, 4, 4, UISettings.atlasPadding, 4096);
        for (int i = 0; i < sprites.Count; ++i)
        {
            sprites[i].rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);
        }
    }
{     //打包算法封装
    public Rect[] Pack(Texture2D tex, Texture2D[] imgs, int padding, object config)
    { //打包纹理
        Rect[] rects = null;

#if UNITY_3_5 || UNITY_4_0
        int maxSize = 4096;
#else
        int maxSize = SystemInfo.maxTextureSize;
#endif

        rects = UITexturePacker.PackTextures(tex, imgs, 4, 4, padding, maxSize);

        for (int i = 0; i < imgs.Length; ++i)
        {
            Rect rect = ConvertToPixels(rects[i], tex.width, tex.height, true);

            // Make sure that we don't shrink the textures
            if (Mathf.RoundToInt(rect.width) != imgs[i].width)
            {
                return(null);
            }
        }
        return(rects);
    }
        /// <summary>
        /// Rebuilds the atlas texture.
        /// </summary>
        public void RebuildAtlas()
        {
            if (this.m_Instance == null)
            {
                Debug.LogError(
                    "SPAtlasBuilder failed to rebuild the atlas, reason: Sprite Packer Instance reference is null.");
                return;
            }

            if (this.m_Instance.texture == null)
            {
                Debug.LogWarning(
                    "Sprite Packer failed to rebuild the atlas, please make sure the atlas texture reference is set.");
                return;
            }

            // Make the atlas texture readable
            if (SPTools.TextureSetReadWriteEnabled(this.m_Instance.texture, true, false))
            {
                // Get a list with the current sprites and applied actions
                List <SPSpriteInfo> spriteInfoList = this.m_Instance.GetSpriteListWithAppliedActions();

                // Get the source textures asset paths
                string[] sourceTexturePaths = this.CollectSourceTextureAssetPaths(spriteInfoList);

                // Make the source textures readable
                if (!this.SetAssetsReadWriteEnabled(sourceTexturePaths, true))
                {
                    Debug.LogError(
                        "Sprite Packer failed to make one or more of the source texture readable, please do it manually.");
                    return;
                }

                // Make sure all the textures have the correct texture format
                this.CorrectTexturesFormat(spriteInfoList);

                // If we are using max rects packing, sort the sprite info list by size
                if (this.m_Instance.packingMethod == SPInstance.PackingMethod.MaxRects)
                {
                    spriteInfoList.Sort(CompareBySize);
                }

                // Temporary textures array
                Texture2D[] textures = new Texture2D[spriteInfoList.Count];

                // Create an array to contain the sprite import data
                SPSpriteImportData[] spritesImportData = new SPSpriteImportData[spriteInfoList.Count];

                // Populate the textures and names arrays
                int ia = 0;
                foreach (SPSpriteInfo si in spriteInfoList)
                {
                    // Temporary texture
                    Texture2D texture = null;

                    // Prepare the sprite import data
                    SPSpriteImportData importData = new SPSpriteImportData();

                    // Prepare the sprite name
                    importData.name = "Sprite_" + ia.ToString();

                    if (si.targetSprite != null)
                    {
                        importData.name = si.targetSprite.name;
                    }
                    else if (si.source != null && (si.source is Texture2D || si.source is Sprite))
                    {
                        if (si.source is Texture2D)
                        {
                            importData.name = (si.source as Texture2D).name;
                        }
                        else
                        {
                            importData.name = (si.source as Sprite).name;
                        }
                    }

                    // Prepare texture
                    // In case the source texture is missing, rebuild from the already existing sprite
                    if (si.source == null && si.targetSprite != null)
                    {
                        // Copy the sprite into the temporary texture
                        texture = new Texture2D((int)si.targetSprite.rect.width, (int)si.targetSprite.rect.height,
                                                TextureFormat.ARGB32, false);
                        Color[] pixels = si.targetSprite.texture.GetPixels((int)si.targetSprite.rect.x,
                                                                           (int)si.targetSprite.rect.y,
                                                                           (int)si.targetSprite.rect.width,
                                                                           (int)si.targetSprite.rect.height);
                        texture.SetPixels(pixels);
                        texture.Apply();
                    }
                    // Handle texture source
                    else if (si.source is Texture2D)
                    {
                        // Get as texture
                        Texture2D sourceTex = si.source as Texture2D;

                        // Check if we have as source texture
                        if (sourceTex != null)
                        {
                            // Copy the source texture into the temp one
                            texture = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.ARGB32, false);
                            Color[] pixels = sourceTex.GetPixels(0, 0, sourceTex.width, sourceTex.height);
                            texture.SetPixels(pixels);
                            texture.Apply();

                            // Transfer the sprite data
                            importData.border    = Vector4.zero;
                            importData.alignment = this.m_Instance.defaultPivot;
                            importData.pivot     = this.m_Instance.defaultCustomPivot;
                        }
                    }
                    // Handle sprite source
                    else if (si.source is Sprite)
                    {
                        // Get as sprite
                        Sprite sourceSprite = si.source as Sprite;

                        // Make sure we have the sprite
                        if (sourceSprite != null)
                        {
                            // Copy the sprite into the temporary texture
                            texture = new Texture2D((int)sourceSprite.rect.width, (int)sourceSprite.rect.height,
                                                    TextureFormat.ARGB32, false);
                            Color[] pixels = sourceSprite.texture.GetPixels((int)sourceSprite.rect.x,
                                                                            (int)sourceSprite.rect.y,
                                                                            (int)sourceSprite.rect.width,
                                                                            (int)sourceSprite.rect.height);
                            texture.SetPixels(pixels);
                            texture.Apply();

                            // Transfer the sprite data
                            importData.border    = sourceSprite.border;
                            importData.alignment = SpriteAlignment.Custom;
                            importData.pivot     = new Vector2(
                                (0f - sourceSprite.bounds.center.x / sourceSprite.bounds.extents.x / 2 + 0.5f),
                                (0f - sourceSprite.bounds.center.y / sourceSprite.bounds.extents.y / 2 + 0.5f));
                        }
                    }

                    // Save the new texture into our array
                    textures[ia] = (texture != null) ? texture : new Texture2D(1, 1);

                    // Set the sprite import data
                    spritesImportData[ia] = importData;

                    // Increase the indexer
                    ia++;
                }

                // Make the source textures assets non readable
                if (SPTools.GetEditorPrefBool(SPTools.Settings_DisableReadWriteEnabled))
                {
                    this.SetAssetsReadWriteEnabled(sourceTexturePaths, false);
                }

                // Clear the source textures asset paths
                System.Array.Clear(sourceTexturePaths, 0, sourceTexturePaths.Length);

                // Create a temporary texture for the packing
                Texture2D tempTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);

                // UV coords array
                Rect[] uvs;

                // Pack the textures into the temporary
                if (this.m_Instance.packingMethod == SPInstance.PackingMethod.Unity)
                {
                    uvs = tempTexture.PackTextures(textures, this.m_Instance.padding, this.m_Instance.maxSize);
                }
                else
                {
                    uvs = UITexturePacker.PackTextures(tempTexture, textures, this.m_Instance.padding,
                                                       this.m_Instance.maxSize);

                    // Check if packing failed
                    if (uvs == null)
                    {
                        Debug.LogError(
                            "Sprite Packer texture packing failed, the textures might be exceeding the specified maximum size.");
                        return;
                    }
                }

                // Import and Configure the texture atlas (also disables Read/Write)
                SPTools.ImportAndConfigureAtlasTexture(this.m_Instance.texture, tempTexture, uvs, spritesImportData);

                // Clear the current sprite info list
                this.m_Instance.ClearSprites();

                // Clear the actions list
                this.m_Instance.ClearActions();

                // Destroy the textures from the temporary textures array
                for (int ib = 0; ib < textures.Length; ib++)
                {
                    UnityEngine.Object.DestroyImmediate(textures[ib]);
                }

                // Destroy the temporary texture
                UnityEngine.Object.DestroyImmediate(tempTexture);

                // Convert the temporary sprite info into array
                SPSpriteInfo[] spriteInfoArray = spriteInfoList.ToArray();

                // Clear the temporary sprite info list
                spriteInfoList.Clear();

                // Apply the new sprite reff to the sprite info and add the sprite info to the sprites list
                for (int i = 0; i < spriteInfoArray.Length; i++)
                {
                    SPSpriteInfo info = spriteInfoArray[i];

                    if (info.targetSprite == null)
                    {
                        info.targetSprite = SPTools.LoadSprite(this.m_Instance.texture, spritesImportData[i].name);
                    }

                    // Add to the instance sprite info list
                    this.m_Instance.AddSprite(info);
                }

                // Clear the sprites import data array
                System.Array.Clear(spritesImportData, 0, spritesImportData.Length);

                // Set dirty
                EditorUtility.SetDirty(this.m_Instance);
            }
            else
            {
                Debug.LogError("Sprite Packer failed to make the atlas texture readable, please do it manually.");
            }
        }
 public static int GetMinSize(Texture2D[] textures, UITexturePacker.FreeRectChoiceHeuristic heuristic)
 {
     int padding = 1;
     return GetMinAtlasSize(textures, 4, ref padding, 4, heuristic);
 }
    private static Texture2D UpdateUIAtlas(UIAtlas atlas, List<Texture2D> textures, ref int? size, out int minSize, UITexturePacker.FreeRectChoiceHeuristic heuristic)
    {
        Debug.Log("***************** Updating atlas " + atlas.name + " - " + DateTime.Now);
        Rect[] texRects;
        Texture2D newTexture = CreateTexture(textures.ToArray(), ref size, 1, out texRects, out minSize, heuristic);
        List<UIAtlasMaker.SpriteEntry> sprites = UIAtlasMaker.CreateSprites(textures.Cast<Texture>().ToList());
        for (int i = 0; i < sprites.Count; i++)
        {
            Rect rect = NGUIMath.ConvertToPixels(texRects[i], newTexture.width, newTexture.height, true);

            UIAtlasMaker.SpriteEntry se = sprites[i];
            se.x = Mathf.RoundToInt(rect.x);
            se.y = Mathf.RoundToInt(rect.y);
            se.width = Mathf.RoundToInt(rect.width);
            se.height = Mathf.RoundToInt(rect.height);
        }

        // Replace the sprites within the atlas
        UIAtlasMaker.ReplaceSprites(atlas, sprites);

        // Release the temporary textures
        UIAtlasMaker.ReleaseSprites(sprites);

        return newTexture;
    }
Example #11
0
    /// <summary>
    /// Pack all of the specified sprites into a single texture, updating the outer and inner rects of the sprites as needed.
    /// </summary>

    static bool PackTextures(Texture2D tex, List <SpriteEntry> sprites)
    {
        Texture2D[] textures = new Texture2D[sprites.Count];
        Rect[]      rects;

#if UNITY_3_5 || UNITY_4_0
        int maxSize = 4096;
#else
        int maxSize = SystemInfo.maxTextureSize;
#endif

#if UNITY_ANDROID || UNITY_IPHONE
        maxSize = Mathf.Min(maxSize, NGUISettings.allow4096 ? 4096 : 2048);
#endif
        if (NGUISettings.unityPacking)
        {
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = tex.PackTextures(textures, Mathf.Max(NGUISettings.atlasPadding, (NGUISettings.atlasExtendPadding << 1)), maxSize);
        }
        else
        {
            sprites.Sort(Compare);
            for (int i = 0; i < sprites.Count; ++i)
            {
                textures[i] = sprites[i].tex;
            }
            rects = UITexturePacker.PackTextures(tex, textures, 4, 4, Mathf.Max(NGUISettings.atlasPadding, (NGUISettings.atlasExtendPadding << 1)), maxSize);
        }

        for (int i = 0; i < sprites.Count; ++i)
        {
            Rect rect = NGUIMath.ConvertToPixels(rects[i], tex.width, tex.height, true);

            // Apparently Unity can take the liberty of destroying temporary textures without any warning
            if (textures[i] == null)
            {
                return(false);
            }

            // Make sure that we don't shrink the textures
            if (Mathf.RoundToInt(rect.width) != textures[i].width)
            {
                return(false);
            }

            SpriteEntry se = sprites[i];
            se.x      = Mathf.RoundToInt(rect.x);
            se.y      = Mathf.RoundToInt(rect.y);
            se.width  = Mathf.RoundToInt(rect.width);
            se.height = Mathf.RoundToInt(rect.height);
        }

        if (NGUISettings.atlasExtendPadding > 0)
        {
            Color32[] colors    = tex.GetPixels32();
            int       texWidth  = tex.width;
            int       texHeight = tex.height;
            for (int i = 0; i < sprites.Count; ++i)
            {
                SpriteEntry se   = sprites[i];
                int         xMin = se.x;
                int         xMax = se.x + se.width - 1;
                // Y-axis is inverted
                int yMin = texHeight - se.y - se.height;
                int yMax = texHeight - se.y - 1;
                for (int x = xMin - NGUISettings.atlasExtendPadding; x <= xMax + NGUISettings.atlasExtendPadding; ++x)
                {
                    for (int y = yMin - NGUISettings.atlasExtendPadding; y <= yMax + NGUISettings.atlasExtendPadding; ++y)
                    {
                        if (x < 0 || x >= texWidth || y < 0 || y >= texHeight)
                        {
                            // Out of tex bounds
                            continue;
                        }
                        if (x >= xMin && x <= xMax && y >= yMin && y <= yMax)
                        {
                            // In sprite bounds
                            continue;
                        }
                        int baseX     = Mathf.Clamp(x, xMin, xMax);
                        int baseY     = Mathf.Clamp(y, yMin, yMax);
                        int index     = y * texWidth + x;
                        int baseIndex = baseY * texWidth + baseX;
                        colors[index] = colors[baseIndex];
                    }
                }
            }
            tex.SetPixels32(colors);
        }

        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;
    }
Example #13
0
    public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize)
    {
        if (width > maxSize && height > maxSize)
        {
            return(null);
        }
        if (width > maxSize || height > maxSize)
        {
            int temp = width; width = height; height = temp;
        }

        UITexturePacker bp = new UITexturePacker(width, height, false);

        Rect[] rects = new Rect[textures.Length];

        for (int i = 0; i < textures.Length; i++)
        {
            Texture2D tex = textures[i];

            Rect rect = new Rect();

            for (int xPadding = 1; xPadding >= 0; --xPadding)
            {
                for (int yPadding = 1; yPadding >= 0; --yPadding)
                {
                    rect = bp.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit);

                    if (rect.width != 0 && rect.height != 0)
                    {
                        break;
                    }
                    // After having no padding if it still doesnt fit increase texture size.
                    else if (xPadding == 0 && yPadding == 0)
                    {
                        return(PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize));
                    }
                }
                if (rect.width != 0 && rect.height != 0)
                {
                    break;
                }
            }
            rects[i] = rect;
        }

        texture.Resize(width, height);
        texture.SetPixels(new Color[width * height]);

        for (int i = 0; i < textures.Length; i++)
        {
            Texture2D tex    = textures[i];
            Rect      rect   = rects[i];
            Color[]   colors = tex.GetPixels();

            if (rect.width != tex.width + padding)
            {
                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 - padding, (int)rect.height - padding, colors);
            rect.x     /= width;
            rect.y     /= height;
            rect.width  = (rect.width - padding) / width;
            rect.height = (rect.height - padding) / height;
            rects[i]    = rect;
        }
        return(rects);
    }
Example #14
0
    private static bool CombineSpritesHelper(string path, string dpath, string name, int padding)
    {
        string file = dpath + "/" + name + ".png";

        if (System.IO.File.Exists(file))
        {
            System.IO.File.Delete(file);
        }

        string[]         paths      = AssetDatabase.FindAssets("t:sprite", new string[] { path });
        List <Sprite>    spriteList = new List <Sprite>();
        List <Texture2D> texList    = new List <Texture2D>();

        foreach (var o in paths)
        {
            Sprite s = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(o), typeof(Sprite)) as Sprite;
            if (null != s)
            {
                spriteList.Add(s);
                texList.Add(s.texture);
            }
        }

        if (texList.Count > 0)
        {
            Texture2D tex = new Texture2D(m_maxWidth, m_maxHeight, TextureFormat.ARGB32, true);
            Rect[]    uvs = UITexturePacker.PackTextures(tex, texList.ToArray(), 4, 4, padding, m_maxWidth);
            if (null == uvs)
            {
                EditorUtility.DisplayDialog(path, "图集超过1024,需要分组成多张图集", "点击退出");
                Object.DestroyImmediate(tex);
                tex = null;
                return(false);
            }
            else
            {
                List <SpriteMetaData> metaList = new List <SpriteMetaData>();
                for (int i = 0; i < uvs.Length; ++i)
                {
                    SpriteMetaData data = new SpriteMetaData();
                    data.alignment = (int)SpriteAlignment.Center;
                    data.border    = spriteList[i].border;
                    data.name      = spriteList[i].name;
                    data.pivot     = spriteList[i].pivot;

                    float width  = UITexturePacker.currentTexSize.x;
                    float height = UITexturePacker.currentTexSize.y;
                    data.rect = new Rect(uvs[i].x * width, uvs[i].y * height, uvs[i].width * width, uvs[i].height * height);
                    //data.rect = new Rect(uvs[i].x * tex.width, uvs[i].y * tex.height, uvs[i].width * tex.width, uvs[i].height * tex.height);
                    metaList.Add(data);
                }

                System.IO.File.WriteAllBytes(file, tex.EncodeToPNG());

                AssetDatabase.ImportAsset(file, ImportAssetOptions.ForceUpdate);
                TextureImporter importer = AssetImporter.GetAtPath(file) as TextureImporter;
                importer.spritesheet        = metaList.ToArray();
                importer.spriteImportMode   = SpriteImportMode.Multiple;
                importer.textureType        = TextureImporterType.Sprite;
                importer.textureCompression = TextureImporterCompression.Uncompressed;
                importer.mipmapEnabled      = true;
                importer.isReadable         = true;
                importer.mipmapFilter       = TextureImporterMipFilter.BoxFilter;
                AssetDatabase.ImportAsset(file);
                AssetDatabase.Refresh();

                m_bitmapFont            = new BitmapFontData();
                m_bitmapFont.name       = name;
                m_bitmapFont.charCount  = metaList.Count;
                m_bitmapFont.height     = tex.height;
                m_bitmapFont.width      = tex.width;
                m_bitmapFont.size       = m_fontSize;
                m_bitmapFont.spriteList = metaList;
                m_bitmapFont.Save();
                m_bitmapFont.CreateFont();
            }
        }
        return(true);
    }
Example #15
0
    bool packTextures(int maxSize, bool unityPacking)     //, ref ArrayList outSprites, ref Rect[] rects)
    {
        if (packTex != null)
        {
            DestroyImmediate(packTex, true);
            packTex = null;
        }

        refreshSelectedCount();
        if (selectedCount == 0)
        {
            Debug.LogError("Please select some sprites, that need packe");
            return(false);
        }

        packSprites.Clear();
        List <Texture2D> listTexs = new List <Texture2D> ();

        for (int i = 0; i < mSpriteList.Count; i++)
        {
            Hashtable m = mSpriteList [i] as Hashtable;
            if (MapEx.getBool(m, "selected"))
            {
                Hashtable d    = MapEx.getMap(m, "data");
                string    name = MapEx.getString(d, "name");
                string    path = MapEx.getString(d, "path");
                Texture2D tex  = ECLEditorUtl.getObjectByPath(path) as Texture2D;
                listTexs.Add(tex);
                packSprites.Add(m);
            }
        }
        if (sortSprite != SortSprite.none)
        {
            if (sortSprite == SortSprite.SortArea)
            {
                packSprites.Sort(CompareSprite);
            }
            else
            {
                packSprites.Sort(CompareSprite2);
            }
            listTexs.Clear();
            for (int i = 0; i < packSprites.Count; i++)
            {
                Hashtable d    = MapEx.getMap(packSprites [i], "data");
                string    path = MapEx.getString(d, "path");
                setTextureReadable("Assets/" + path, TextureImporterFormat.RGBA32, TextureImporterCompression.Uncompressed, true);
                Texture2D tex = ECLEditorUtl.getObjectByPath(path) as Texture2D;
                listTexs.Add(tex);
            }
        }

//		for (int i = 0; i < listTexs.Count; i++) {
//			setTextureReadable (listTexs [i] as Texture, TextureImporterFormat.RGBA32, TextureImporterCompression.Uncompressed, true);
//		}
        packTex = new Texture2D(1, 1, TextureFormat.ARGB32, false);

        if (unityPacking)
        {
            packRects = packTex.PackTextures(listTexs.ToArray(), NGUISettings.atlasPadding, maxSize);
        }
        else
        {
            packRects = UITexturePacker.PackTextures(packTex, listTexs.ToArray(), 4, 4, NGUISettings.atlasPadding, maxSize);
        }
        _empty = new Texture2D(packTex.width, packTex.height, TextureFormat.ARGB32, false);
        bool ret = true;

        for (int i = 0; i < listTexs.Count; ++i)
        {
            Rect rect = NGUIMath.ConvertToPixels(packRects [i], packTex.width, packTex.height, true);
            packRects [i] = rect;

            // Apparently Unity can take the liberty of destroying temporary textures without any warning
            if (listTexs [i] == null)
            {
                Debug.LogWarning("Apparently Unity can take the liberty of destroying temporary textures without any warning");
                ret = false;
                break;
            }

            // Make sure that we don't shrink the textures
            if (Mathf.RoundToInt(rect.width) != listTexs [i].width)
            {
                Debug.LogError(rect.width + "====" + listTexs [i].width);
                Debug.LogWarning("Make sure that we don't shrink the textures=" + listTexs [i].name);
                ret = false;
                break;
            }
        }

//		for (int i = 0; i < listTexs.Count; i++) {
//			setTextureReadable (listTexs [i] as Texture, TextureImporterFormat.Automatic, false);
//		}
        return(ret);
    }
Example #16
0
    public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize)
    {
        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;
            }
        }
        UITexturePacker bp = new UITexturePacker(width, height, false);

        Storage[] storage = new Storage[textures.Length];

        for (int i = 0; i < textures.Length; i++)
        {
            Texture2D tex = textures[i];

            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),
                                     UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit);
                    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(PackTextures(texture, textures, width * (width <= height ? 2 : 1),
                                            height * (height < width ? 2 : 1), padding, maxSize));
                    }
                }
                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);
        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];
            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;
        }
        return(rects);
    }
	public static Rect[] PackTextures (Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize)
	{
		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;
		}
		UITexturePacker bp = new UITexturePacker(width, height, false);
		Storage[] 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),
						UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit);
					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 PackTextures(texture, textures, width * (width <= height ? 2 : 1),
							height * (height < width ? 2 : 1), padding, maxSize);
					}
				}
				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);
		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) 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;
	}
    private static int GetMinAtlasSize(Texture2D[] textures, int startSize, ref int padding, int nessSize, UITexturePacker.FreeRectChoiceHeuristic heuristic)
    {
        int startDiff = startSize /2;
        int minDiff = 0;

        int size = startSize;
        int diff = startDiff;
        bool? prevResult = null;
        while (true)
        {
            bool curResult = CanPackTexturesInSize(textures, size, (int)Math.Ceiling(padding * ((double)size / nessSize)), heuristic);

            if (prevResult.HasValue && curResult != prevResult)
            {
                if (diff/2 <= minDiff)
                {

                    if (!curResult)
                    {
                        size += diff;
                    }

                    padding = (int) Math.Ceiling(padding*((double) size/nessSize));

                    return size;
                }

                diff /= 2;
            }

            if (curResult)
            {
                size -= diff;
            }
            else
            {
                size += diff;
            }

            prevResult = curResult;
        }
    }
Example #19
0
    public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize)
    {
        if(width > maxSize && height > maxSize) return null;
        if(width > maxSize || height > maxSize) { int temp = width; width = height; height = temp; }

        UITexturePacker bp = new UITexturePacker(width, height, false);
        Rect[] rects = new Rect[textures.Length];

        for(int i = 0; i < textures.Length; i++)
        {
            Texture2D tex = textures[i];

            Rect rect = new Rect();

            for (int xPadding = 1; xPadding >=0; --xPadding)
            {
                for (int yPadding = 1; yPadding >= 0; --yPadding)
                {
                    rect = bp.Insert(tex.width + (xPadding * padding), tex.height + (yPadding * padding), UITexturePacker.FreeRectChoiceHeuristic.RectBestAreaFit);

                    if (rect.width != 0 && rect.height != 0)
                    {
                        break;
                    }
                    // After having no padding if it still doesnt fit increase texture size.
                    else if (xPadding == 0 && yPadding == 0)
                    {
                        return PackTextures(texture, textures, width * (width <= height ? 2 : 1), height * (height < width ? 2 : 1), padding, maxSize);
                    }
                }
                if (rect.width != 0 && rect.height != 0)
                {
                    break;
                }
            }
            rects[i] = rect;
        }

        texture.Resize(width, height);
        texture.SetPixels(new Color[width * height]);

        for(int i = 0; i < textures.Length; i++)
        {
            Texture2D tex = textures[i];
            Rect rect = rects[i];
            Color[] colors = tex.GetPixels();

            if(rect.width != tex.width + padding)
            {
                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 - padding, (int)rect.height - padding, colors);
            rect.x /= width;
            rect.y /= height;
            rect.width = (rect.width- padding) / width ;
            rect.height = (rect.height - padding) / height;
            rects[i] = rect;
        }
        return rects;
    }
Example #20
0
    /// <summary>
    /// 以4为基础值 大小不够则乘以2扩充图片大小
    /// </summary>
    /// <returns></returns>
    public static Rect[] PackTextures(Texture2D texture, Texture2D[] textures, int width, int height, int padding, int maxSize)
    {
        if (width > maxSize && height > maxSize)
        {
            return(null);
        }
        if (width > maxSize || height > maxSize)
        {
            int temp = width; width = height; height = temp;
        }

        UITexturePacker bp = new UITexturePacker(width, height, false);

        Storage[] 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),
                                     UITexturePacker.FreeRectChoiceHeuristic.RectBestLongSideFit);
                    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(PackTextures(texture, textures, width * (width <= height ? 2 : 1),
                                            height * (height < width ? 2 : 1), padding, maxSize));
                    }
                }
                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);
        }
        currentTexSize = new Vector2(width, height);
        int maxTexSize = Mathf.Max(width, height);//如果只按宽高是最优的图片大小,现在改成和Bitfont一样 导出正方形图

        texture.Resize(maxTexSize, maxTexSize);
        texture.SetPixels(new Color[maxTexSize * maxTexSize]);

        // 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;
            }
            float ry = maxTexSize - rect.y - rect.height;//原来是从下往上写入,现在修改成和bitfont导出设置一样,从上往下写入!
            texture.SetPixels((int)rect.x, (int)ry, (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);
    }