Beispiel #1
0
    void CreateNewAtlas()
    {
        if (AtlasConfig.kUsingCopyTexture)
        {
            Texture2D tex2D = new Texture2D(mWidth, mHeight, AtlasConfig.kTextureFormat, false, true);
            tex2D.filterMode = FilterMode.Bilinear;
            //tex2D.alphaIsTransparency = true;
            tex2D.SetPixels32(0, 0, mWidth, mWidth, tmpColor);
            tex2D.Apply(false);
            m_tex2DList.Add(tex2D);
        }
        else
        {
            RenderTexture renderTexture = CommonUtils.CreateDyanmicAtlasRenderTexture(mWidth, mHeight, 0, AtlasConfig.kRenderTextureFormat);
            renderTexture.name = string.Format("DynamicAtlas {0:G} -- {0:G}", mWidth, mHeight);
            renderTexture.DiscardContents(true, true);
            Material mDefaultMaterial = new Material(Shader.Find("UI/Default"));
            mDefaultMaterial.mainTexture = renderTexture;
            m_MaterialList.Add(mDefaultMaterial);

            mMaterial.SetVector(mBlitParamId, new Vector4(0, 0, 1, 1));
            Texture2D cleared_texture = new Texture2D(2, 2, AtlasConfig.kTextureFormat, false);
            Graphics.Blit(cleared_texture, renderTexture, mMaterial);
            m_RenderTexList.Add(renderTexture);
        }

        IntegerRectangle        area = DynamicAtlasManager.Instance.AllocateRectangle(0, 0, mWidth, mHeight);
        List <IntegerRectangle> list = new List <IntegerRectangle>();

        list.Add(area);
        mFreeAreasList.Add(list);
    }
Beispiel #2
0
    IntegerRectangle OnMergeAreaRecursive(IntegerRectangle target, int texIndex)
    {
        List <IntegerRectangle> data      = mFreeAreasList[texIndex];
        IntegerRectangle        mergeRect = null;

        foreach (var freeArea in data)
        {
            if (target.right == freeArea.x && target.y == freeArea.y && target.height == freeArea.height) //右
            {
                mergeRect = DynamicAtlasManager.Instance.AllocateRectangle(target.x, target.y, target.width + freeArea.width, target.height);
            }
            else if (target.x == freeArea.x && target.top == freeArea.y && target.width == freeArea.width)//上
            {
                mergeRect = DynamicAtlasManager.Instance.AllocateRectangle(target.x, target.y, target.width, target.height + freeArea.height);
            }
            else if (target.x == freeArea.right && target.y == freeArea.y && target.height == freeArea.height)//左
            {
                mergeRect = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, freeArea.y, freeArea.width + target.width, freeArea.height);
            }
            else if (target.x == freeArea.x && target.y == freeArea.top && target.width == freeArea.width)//下
            {
                mergeRect = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, freeArea.y, target.width, target.height + freeArea.height);
            }
            if (mergeRect != null)
            {
                RemoveFreeArea(texIndex, freeArea);
                return(mergeRect);
            }
        }
        if (mergeRect == null)
        {
            AddFreeArea(texIndex, target);
        }
        return(mergeRect);
    }
Beispiel #3
0
    private void filterSelfSubAreas(int index)
    {
        List <IntegerRectangle> areas = mFreeAreasList[index];

        for (int i = areas.Count - 1; i >= 0; i--)
        {
            IntegerRectangle filtered = areas[i];
            for (int j = areas.Count - 1; j >= 0; j--)
            {
                if (i != j)
                {
                    IntegerRectangle area = areas[j];
                    if (filtered.x >= area.x && filtered.y >= area.y && filtered.right <= area.right && filtered.top <= area.top)
                    {
                        DynamicAtlasManager.Instance.ReleaseRectangle(filtered);
                        IntegerRectangle topOfStack = areas.Pop();
                        if (i < areas.Count)
                        {
                            // Move the one on the top to the freed position
                            areas[i] = topOfStack;
                        }
                        break;
                    }
                }
            }
        }
    }
Beispiel #4
0
    public IntegerRectangle InsertArea(int width, int height, out int index)
    {
        IntegerRectangle result;
        bool             justRightSize;
        IntegerRectangle freeArea = GetFreeArea(width, height, out index, out justRightSize);

        if (justRightSize == false)
        {
            int resultWidth  = (width + mPadding) > freeArea.width ? freeArea.width : (width + mPadding);
            int resultHeight = (height + mPadding) > freeArea.height ? freeArea.height : (height + mPadding);
            result = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, freeArea.y, resultWidth, resultHeight);
            if (mTopFirst)  //切割此freeArea,得到新的freeArea: mNewFreeAreas
            {
                GenerateDividedAreasTopFirst(index, result, freeArea);
            }
            else
            {
                GenerateDividedAreasRightFirst(index, result, freeArea);
            }
        }
        else
        {
            result = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, freeArea.y, freeArea.width, freeArea.height);;
        }
        RemoveFreeArea(index, freeArea);//回收此freeArea,无论是正好符合还是切割,都要回收
        return(result);
    }
Beispiel #5
0
        public void PackerTexture1()
        {
            Texture2D[] packerTexs = _texMap.Values.ToArray();
            _texMap.Clear();

            _mainTex          = new Texture2D(_defaultWh, _defaultWh, TextureFormat.ARGB32, false);
            _mainTex.wrapMode = TextureWrapMode.Clamp;

            const int       padding = 0;
            RectanglePacker packer  = new RectanglePacker(_mainTex.width, _mainTex.height, padding);

            for (int i = 0; i < packerTexs.Length; i++)
            {
                packer.insertRectangle(packerTexs[i].width, packerTexs[i].height, i);
            }
            packer.packRectangles();

            IntegerRectangle rect = new IntegerRectangle();

            for (int i = 0; i < packer.rectangleCount; i++)
            {
                rect = packer.getRectangle(i, rect);
                int index = packer.getRectangleId(i);

                _mainTex.SetPixels32(rect.x, rect.y, rect.width, rect.height, packerTexs[index].GetPixels32());
                Sprite sprite = Sprite.Create(_mainTex, new Rect(rect.x, rect.y, rect.width, rect.height),
                                              Vector2.zero, _pixelsPerUnit, 0, SpriteMeshType.FullRect);
                _spriteMap.Add(packerTexs[i].name, sprite);
            }
            _mainTex.Apply();
        }
Beispiel #6
0
    IntegerRectangle GetFreeArea(int width, int height, out int index, out bool justRightSize)
    {
        IntegerRectangle best = mOutsideRectangle;

        index         = -1;
        justRightSize = false;
        int  paddedWidth  = width + mPadding;
        int  paddedHeight = height + mPadding;
        int  count        = mFreeAreasList.Count;
        bool isFindResult = false;

        for (int i = 0; i < count; i++)//从第一个图集开始查找
        {
            var item = mFreeAreasList[i];
            index = i;
            Vector2 range = m_FindRange[index];
            foreach (IntegerRectangle free in item)
            {
                if (free.x < range.x || free.y < range.y)
                {
                    if (free.x < best.x && paddedWidth <= free.width && paddedHeight <= free.height)
                    {
                        best         = free;
                        isFindResult = true;
                        if ((paddedWidth == free.width && free.width <= free.height && free.right < mWidth) || (paddedHeight == free.height && free.height <= free.width))
                        {
                            justRightSize = true;
                            break;
                        }
                    }
                }
                else
                {
                    // Outside the current packed area, no padding required
                    if (free.x < best.x && width <= free.width && height <= free.height)
                    {
                        best         = free;
                        isFindResult = true;
                        if ((width == free.width && free.width <= free.height && free.right < mWidth) || (height == free.height && free.height <= free.width))
                        {
                            justRightSize = true;
                            break;
                        }
                    }
                }
            }
            if (isFindResult)//找到了就往下一个图集找了
            {
                break;
            }
        }
        if (best == mOutsideRectangle) //没有找到适合的区域,那么就要申请新的图集了
        {
            CreateNewAtlas();
            index         = mFreeAreasList.Count - 1;
            justRightSize = false;//不支持,也不允许让 图片大小直接等于图集大小
            return(mFreeAreasList[index][0]);
        }
        return(best);
    }
Beispiel #7
0
    private void generateDividedAreas(IntegerRectangle divider, IntegerRectangle area)
    {
        int rightDelta = area.right - divider.right;

        if (rightDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(divider.right, area.y, rightDelta, area.height));
        }

        int leftDelta = divider.x - area.x;

        if (leftDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(area.x, area.y, leftDelta, area.height));
        }

        int bottomDelta = area.top - divider.top;

        if (bottomDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(area.x, divider.top, area.width, bottomDelta));
        }

        int topDelta = divider.y - area.y;

        if (topDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(area.x, area.y, area.width, topDelta));
        }
    }
    void ClearFreeAreas()
    {
        DynamicAtlas dynamicAtlas = DynamicAtlasManager.Instance.GetDynamicAtlas(_mGroup);

        if (AtlasConfig.kUsingCopyTexture)
        {
            List <List <IntegerRectangle> > freeLists = dynamicAtlas.GetFreeAreas();
            int freeListsCount         = freeLists.Count;
            List <Texture2D> tex2DList = dynamicAtlas.tex2DList;
            for (int i = 0; i < freeListsCount; i++)
            {
                var       freeList      = freeLists[i];
                int       freeListCount = freeList.Count;
                Texture2D dstTex        = tex2DList[i];
                for (int j = 0; j < freeListCount; j++)
                {
                    IntegerRectangle item   = freeList[j];
                    Color32[]        colors = new Color32[item.width * item.height];
                    for (int k = 0; k < colors.Length; ++k)
                    {
                        colors[k] = Color.clear;
                    }
                    dstTex.SetPixels32((int)item.x, (int)item.y, item.width, item.height, colors);
                    dstTex.Apply();
                }
            }
        }
        else
        {
            dynamicAtlas.ClearTextureWithBlit();
        }
    }
    private Rect IntegerRectangle2Rect(IntegerRectangle integer)
    {
        Rect rect = new Rect();

        rect.x      = (float)integer.x / (float)TEXTURE_SIZE;
        rect.y      = (float)integer.y / (float)TEXTURE_SIZE;
        rect.width  = (float)integer.width / (float)TEXTURE_SIZE;
        rect.height = (float)integer.height / (float)TEXTURE_SIZE;
        return(rect);
    }
        public bool CreateAtlas(Texture[] textures, int width = 1024, int height = 1024, int padding = 1)
        {
            bool result = false;

            rectangles.Clear();
            dictionary.Clear();
            packer.ResetAll(width, height, padding);

            CreateMaterial();
            CreateRenderTexture(width, height);

            for (int i = 0; i < textures.Length; i++)
            {
                rectangles.Add(new Rect(0, 0, textures[i].width, textures[i].height));
            }

            for (int i = 0; i < rectangles.Count; i++)
            {
                packer.insertRectangle((int)rectangles[i].width, (int)rectangles[i].height, i);
            }

            packer.packRectangles();

            int index = 0;

            if (packer.rectangleCount > 0)
            {
                for (int j = 0; j < packer.rectangleCount; j++)
                {
                    integerRect = packer.getRectangle(j, integerRect);
                    index       = packer.getRectangleId(j);

                    if (!dictionary.ContainsKey(textures[index].name))
                    {
                        Rect rect = new Rect();
                        rect.x      = (float)integerRect.x / width;
                        rect.y      = (float)integerRect.y / height;
                        rect.width  = (float)integerRect.width / width;
                        rect.height = (float)integerRect.height / height;

                        dictionary.Add(textures[index].name, rect);
                    }

                    DrawTexture(textures[index], renderTexture,
                                new Rect(integerRect.x, integerRect.y, integerRect.width, integerRect.height));
                }

                result = true;
            }

            return(result);
        }
 public IntegerRectangle AllocateRectangle(int x, int y, int width, int height)
 {
     if (mRectangleStack.Count > 0)
     {
         IntegerRectangle rectangle = mRectangleStack.Pop();
         rectangle.x      = x;
         rectangle.y      = y;
         rectangle.width  = width;
         rectangle.height = height;
         return(rectangle);
     }
     return(new IntegerRectangle(x, y, width, height));
 }
Beispiel #12
0
    bool OnMergeArea(IntegerRectangle newRect, int texIndex)
    {
        IntegerRectangle mergeRect = newRect;
        bool             isMerged  = false;

        while (mergeRect != null)
        {
            mergeRect = OnMergeAreaRecursive(mergeRect, texIndex);
            if (mergeRect != null)
            {
                isMerged = true;
            }
        }
        return(isMerged);
    }
Beispiel #13
0
    private void generateNewFreeAreas(int index, IntegerRectangle divider)
    {
        List <IntegerRectangle> areas = mFreeAreasList[index];

        for (int i = areas.Count - 1; i >= 0; i--)
        {
            IntegerRectangle area = areas[i];
            if ((divider.x >= area.right || divider.right <= area.x || divider.y >= area.top || divider.top <= area.y) == false)//divider 在area里面
            {
                generateDividedAreas(divider, area);
                areas.RemoveAt(i);
                DynamicAtlasManager.Instance.ReleaseRectangle(area);
            }
        }
        filterSelfSubAreas(index);
    }
Beispiel #14
0
    private void generateDividedAreas(IntegerRectangle divider, IntegerRectangle area)
    {
        //int count = 0;
        int rightDelta = area.right - divider.right;

        if (rightDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(divider.right, area.y, rightDelta, area.height));
            //count++;
        }

        int leftDelta = divider.x - area.x;

        if (leftDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(area.x, area.y, leftDelta, area.height));
            //count++;
        }

        int bottomDelta = area.top - divider.top;

        if (bottomDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(area.x, divider.top, area.width, bottomDelta));
            //count++;
        }

        int topDelta = divider.y - area.y;

        if (topDelta > 0)
        {
            mNewFreeAreas.Add(DynamicAtlasManager.Instance.AllocateRectangle(area.x, area.y, area.width, topDelta));
            //count++;
        }

        //if (count == 0 && (divider.width < area.width || divider.height < area.height))//没有切割
        //{
        //    // Only touching the area, store the area itself
        //    mNewFreeAreas.Add(area);
        //}
        //else
        //{
        //    DynamicAtlasManager.Instance.ReleaseRectangle(area);
        //}
    }
Beispiel #15
0
    //切割,优先上面的区域大一些
    private void GenerateDividedAreasTopFirst(int index, IntegerRectangle divider, IntegerRectangle freeArea)
    {
        int rightDelta = freeArea.right - divider.right;//找到空闲区域2

        if (rightDelta > 0)
        {
            IntegerRectangle area = DynamicAtlasManager.Instance.AllocateRectangle(divider.right, divider.y, rightDelta, divider.height);
            AddFreeArea(index, area);
        }

        int topDelta = freeArea.top - divider.top;//找到空闲区域1

        if (topDelta > 0)
        {
            IntegerRectangle area = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, divider.top, freeArea.width, topDelta);
            AddFreeArea(index, area);
        }
    }
Beispiel #16
0
    public PackingAtlas(DynamicAtlasGroup group)
    {
        int length = (int)group;

        mWidth   = length;
        mHeight  = length;
        tmpColor = new Color32[length * length];
        for (int k = 0; k < tmpColor.Length; ++k)
        {
            tmpColor[k] = Color.clear;
        }
        mUVXDiv           = 1f / mWidth;
        mUVYDiv           = 1f / mHeight;
        mOutsideRectangle = new IntegerRectangle(mWidth + 1, mWidth + 1, 0, 0);

        if (AtlasConfig.kUsingCopyTexture == false)
        {
            mMaterial    = new Material(Shader.Find("DynamicAtlas/GraphicBlit"));
            mBlitParamId = Shader.PropertyToID("_DrawRect");
        }

        CreateNewAtlas();
    }
Beispiel #17
0
    IntegerRectangle InsertArea(int width, int height, out int index)
    {
        bool             justRightSize;//宽高正好是图集大小,一般不建议这样干,但是为了兼容.
        IntegerRectangle freeArea = GetFreeArea(width, height, out index, out justRightSize);
        IntegerRectangle result;

        mNewFreeAreas.Clear();
        if (justRightSize == false)
        {
            int resultWidth  = (width + mPadding) > freeArea.width ? freeArea.width : (width + mPadding);
            int resultHeight = (height + mPadding) > freeArea.height ? freeArea.height : (height + mPadding);
            result = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, freeArea.y, resultWidth, resultHeight);
            generateNewFreeAreas(index, result);
        }
        else
        {
            result = DynamicAtlasManager.Instance.AllocateRectangle(freeArea.x, freeArea.y, freeArea.width, freeArea.height);
        }
        //RemoveFreeArea(index, freeArea);//回收此freeArea,无论是正好符合还是切割,都要回收
        while (mNewFreeAreas.Count > 0)
        {
            AddFreeArea(index, mNewFreeAreas.Pop());
        }
        Vector2 range = m_FindRange[index];

        if (result.right > range.x)//尽量的往左,往高了找
        {
            range.x = result.right;
        }

        if (result.top > range.y)
        {
            range.y = result.top;
        }
        m_FindRange[index] = range;
        return(result);
    }
Beispiel #18
0
    public void ClearAtlas()
    {
        foreach (List <IntegerRectangle> items in mFreeAreasList)
        {
            while (items.Count > 0)
            {
                DynamicAtlasManager.Instance.ReleaseRectangle(items.Pop());
            }
            items.Clear();
            IntegerRectangle area = DynamicAtlasManager.Instance.AllocateRectangle(0, 0, mWidth, mHeight);
            items.Add(area);
        }
        int count = m_FindRange.Count;

        for (int i = 0; i < count; i++)
        {
            m_FindRange[i] = Vector2.zero;
        }
        foreach (var item in _usingRect)
        {
            DynamicAtlasManager.Instance.ReleaseSaveImageData(item.Value);
        }
        _usingRect.Clear();
    }
    private void updateRectangles()
    {
        DateTime  start   = DateTime.Now;
        const int padding = 1;

        if (mPacker == null)
        {
            mPacker = new RectanglePacker((int)sliderWidth.value, (int)sliderHeight.value, padding);
        }
        else
        {
            mPacker.reset((int)sliderWidth.value, (int)sliderHeight.value, padding);
        }

        for (int i = 0; i < RECTANGLE_COUNT; i++)
        {
            mPacker.insertRectangle((int)mRectangles[i].width, (int)mRectangles[i].height, i);
        }

        mPacker.packRectangles();
        Clear();
        DateTime end = DateTime.Now;

        if (mPacker.rectangleCount > 0)
        {
            packingTimeText.text = mPacker.rectangleCount + " rectangles packed in " + (end - start).Milliseconds + "ms";
            IntegerRectangle rect = new IntegerRectangle();
            for (int j = 0; j < mPacker.rectangleCount; j++)
            {
                rect = mPacker.getRectangle(j, rect);
                int       index   = mPacker.getRectangleId(j);
                Texture2D texture = textures[index];
                SetTexture(texture, IntegerRectangle2Rect(rect));
            }
        }
    }
    private void updateRectangles()
    {
        DateTime  start   = DateTime.Now;
        const int padding = 1;

        if (mPacker == null)
        {
            mPacker = new RectanglePacker((int)sliderWidth.value, (int)sliderHeight.value, padding);
        }
        else
        {
            mPacker.Reset((int)sliderWidth.value, (int)sliderHeight.value, padding);
        }

        for (int i = 0; i < RECTANGLE_COUNT; i++)
        {
            mPacker.InsertRectangle((int)mRectangles[i].width, (int)mRectangles[i].height, i);
        }

        mPacker.PackRectangles();

        DateTime end = DateTime.Now;

        if (mPacker.rectangleCount > 0)
        {
            packingTimeText.text = mPacker.rectangleCount + " rectangles packed in " + (end - start).Milliseconds + "ms";

            mTexture.SetPixels32(mFillColor);
            IntegerRectangle rect = new IntegerRectangle();
            Color32[]        tmpColor;

            for (int j = 0; j < mPacker.rectangleCount; j++)
            {
                rect = mPacker.GetRectangle(j, rect);

                int size = rect.width * rect.height;

                tmpColor = new Color32[size];
                for (int k = 0; k < size; ++k)
                {
                    tmpColor[k] = Color.black;
                }

                mTexture.SetPixels32(rect.x, rect.y, rect.width, rect.height, tmpColor);

                int   index = mPacker.GetRectangleId(j);
                Color color = convertHexToRGBA((uint)(0xFF171703 + (((18 * ((index + 4) % 13)) << 16) + ((31 * ((index * 3) % 8)) << 8) + 63 * (((index + 1) * 3) % 5))));

                size -= 4;

                tmpColor = new Color32[size];
                for (int k = 0; k < size; ++k)
                {
                    tmpColor[k] = color;
                }

                mTexture.SetPixels32(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2, tmpColor);
            }

            mTexture.Apply();
        }
    }
Beispiel #21
0
        protected IEnumerator createPack(string savePath = "")
        {
            if (savePath != "")
            {
                if (deletePreviousCacheVersion && Directory.Exists(Application.persistentDataPath + "/AssetPacker/" + cacheName + "/"))
                {
                    foreach (string dirPath in Directory.GetDirectories(Application.persistentDataPath + "/AssetPacker/" + cacheName + "/", "*", SearchOption.AllDirectories))
                    {
                        Directory.Delete(dirPath, true);
                    }
                }

                Directory.CreateDirectory(savePath);
            }

            List <Texture2D> textures = new List <Texture2D>();
            List <string>    images   = new List <string>();

            foreach (TextureToPack itemToRaster in itemsToRaster)
            {
                WWW loader = new WWW("file:///" + itemToRaster.file);

                yield return(loader);

                textures.Add(loader.texture);
                images.Add(itemToRaster.id);
            }

            int textureSize = allow4096Textures ? 4096 : 2048;

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

            for (int i = 0; i < textures.Count; i++)
            {
                if (textures[i].width > textureSize || textures[i].height > textureSize)
                {
                    throw new Exception("A texture size is bigger than the sprite sheet size!");
                }
                else
                {
                    rectangles.Add(new Rect(0, 0, textures[i].width, textures[i].height));
                }
            }

            const int padding = 1;

            int numSpriteSheet = 0;

            while (rectangles.Count > 0)
            {
                Texture2D texture   = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false);
                Color32[] fillColor = texture.GetPixels32();
                for (int i = 0; i < fillColor.Length; ++i)
                {
                    fillColor[i] = Color.clear;
                }

                RectanglePacker packer = new RectanglePacker(texture.width, texture.height, padding);

                for (int i = 0; i < rectangles.Count; i++)
                {
                    packer.insertRectangle((int)rectangles[i].width, (int)rectangles[i].height, i);
                }

                packer.packRectangles();

                if (packer.rectangleCount > 0)
                {
                    texture.SetPixels32(fillColor);
                    IntegerRectangle    rect          = new IntegerRectangle();
                    List <TextureAsset> textureAssets = new List <TextureAsset>();

                    List <Rect>      garbageRect    = new List <Rect>();
                    List <Texture2D> garabeTextures = new List <Texture2D>();
                    List <string>    garbageImages  = new List <string>();

                    for (int j = 0; j < packer.rectangleCount; j++)
                    {
                        rect = packer.getRectangle(j, rect);

                        int index = packer.getRectangleId(j);

                        texture.SetPixels32(rect.x, rect.y, rect.width, rect.height, textures[index].GetPixels32());

                        TextureAsset textureAsset = new TextureAsset();
                        textureAsset.x      = rect.x;
                        textureAsset.y      = rect.y;
                        textureAsset.width  = rect.width;
                        textureAsset.height = rect.height;
                        textureAsset.name   = images[index];

                        textureAssets.Add(textureAsset);

                        garbageRect.Add(rectangles[index]);
                        garabeTextures.Add(textures[index]);
                        garbageImages.Add(images[index]);
                    }

                    foreach (Rect garbage in garbageRect)
                    {
                        rectangles.Remove(garbage);
                    }

                    foreach (Texture2D garbage in garabeTextures)
                    {
                        textures.Remove(garbage);
                    }

                    foreach (string garbage in garbageImages)
                    {
                        images.Remove(garbage);
                    }

                    texture.Apply();

                    if (savePath != "")
                    {
                        File.WriteAllBytes(savePath + "/data" + numSpriteSheet + ".png", texture.EncodeToPNG());
                        File.WriteAllText(savePath + "/data" + numSpriteSheet + ".json", JsonUtility.ToJson(new TextureAssets(textureAssets.ToArray())));
                        ++numSpriteSheet;
                    }

                    foreach (TextureAsset textureAsset in textureAssets)
                    {
                        mSprites.Add(textureAsset.name, Sprite.Create(texture, new Rect(textureAsset.x, textureAsset.y, textureAsset.width, textureAsset.height), Vector2.zero, pixelsPerUnit, 0, SpriteMeshType.FullRect));
                    }
                }
            }

            OnProcessCompleted.Invoke();
        }
Beispiel #22
0
    //获得最适合放texture的区域
    private IntegerRectangle GetFreeArea(int width, int height, out int index, out bool justRightSize)
    {
        index         = -1;
        justRightSize = false;

        if (width > mWidth || height > mHeight)
        {
            Debug.LogError("ERROR 图片尺寸大于图集大小: 图片大小为" + width + "x" + height + "  图集大小为" + mWidth + "x" + mHeight);
            return(null);
        }
        int paddedWidth           = width + mPadding;
        int paddedHeight          = height + mPadding;
        int count                 = mFreeAreasList.Count;
        IntegerRectangle tempArea = null;

        for (int i = 0; i < count; i++)//从第一个图集开始查找
        {
            var  item         = mFreeAreasList[i];
            bool isFindResult = false;
            foreach (var listItem in item)
            {
                IntegerRectangle area             = listItem;
                bool             isJustFullWidth  = (width == area.width || width == mWidth);
                bool             isJustFullHeight = (height == area.height || height == mHeight);
                bool             isFitWidth       = isJustFullWidth || paddedWidth <= area.width;
                bool             isFitHeight      = paddedHeight <= area.height || isJustFullHeight;
                if (isFitWidth && isFitHeight)//用最快的方式,找到能放进去的区域,如果宽或者高恰好等于图集的宽或者高,则没有paddling
                {
                    index         = i;
                    justRightSize = (isJustFullWidth || paddedWidth == area.width) && (isJustFullHeight || paddedHeight == area.height);
                    if (isJustFullWidth && isJustFullHeight)
                    {
                        return(area);
                    }
                    isFindResult = true;
                    if (tempArea != null)
                    {
                        if (mTopFirst)
                        {
                            if (tempArea.height > area.height)
                            {
                                tempArea = area;
                            }
                        }
                        else
                        {
                            if (tempArea.width > area.width)
                            {
                                tempArea = area;
                            }
                        }
                    }
                    else
                    {
                        tempArea = area;
                    }
                }
            }
            if (isFindResult)//找到了就往下一个图集找了
            {
                break;
            }
        }
        if (tempArea != null)
        {
            return(tempArea);
        }
        //没有找到适合的区域,那么就要申请新的图集了
        CreateNewAtlas();
        index         = mFreeAreasList.Count - 1;
        justRightSize = false;//不支持,也不允许让 图片大小直接等于图集大小
        return(mFreeAreasList[index][0]);
    }
Beispiel #23
0
    void OnRenderTexture(string path, Texture2D data)
    {
        if (data == null)
        {
            GetImageData getImageData;
            if (mGetImageTaskDic.TryGetValue(path, out getImageData))
            {
                if (AtlasConfig.kUsingCopyTexture)
                {
                    if (getImageData.callback != null)
                    {
                        getImageData.callback(null, new Rect(0, 0, 0, 0), path);//完成一个任务,就回调一个任务
                    }
                }
                else
                {
                    if (getImageData.BlitCallback != null)
                    {
                        getImageData.BlitCallback(null, new Rect(0, 0, 0, 0), path);//完成一个任务,就回调一个任务
                    }
                }

                DynamicAtlasManager.Instance.ReleaseGetImageData(getImageData);
                if (!mGetImageTaskDic.Remove(path))
                {
                    Debug.LogError($"无法删除GetImageData:{path}");
                }
            }
            else
            {
                Debug.Log($"没有此GetImageData任务:{path}");
            }
            return;
        }

        int index;
        IntegerRectangle useArea = InsertArea(data.width, data.height, out index);
        Rect             uv      = new Rect((useArea.x + offset) * mUVXDiv, (useArea.y + offset) * mUVYDiv, (useArea.width - mPadding - offset * 2) * mUVXDiv, (useArea.height - mPadding - offset * 2) * mUVYDiv);

        if (AtlasConfig.kUsingCopyTexture)
        {
            CopyTexture(useArea.x, useArea.y, index, data);
        }
        else
        {
            BlitTexture(useArea.x, useArea.y, index, data);
        }

        SaveImageData _SaveImageData = DynamicAtlasManager.Instance.AllocateSaveImageData(uv);

        _SaveImageData.texIndex  = index;
        _SaveImageData.rectangle = useArea;
        _usingRect[path]         = _SaveImageData;


        {
            GetImageData getImageData;
            if (mGetImageTaskDic.TryGetValue(path, out getImageData))
            {
                _usingRect[path].referenceCount = _usingRect[path].referenceCount + 1;
                if (AtlasConfig.kUsingCopyTexture)
                {
                    if (getImageData.callback != null)
                    {
                        Texture2D dstTex = m_tex2DList[index];
                        getImageData.callback(dstTex, uv, path); //完成一个任务,就回调一个任务
                    }
                }
                else
                {
                    if (getImageData.BlitCallback != null)
                    {
                        Material material = m_MaterialList[index];
                        getImageData.BlitCallback(material, uv, path); //完成一个任务,就回调一个任务
                    }
                }

                DynamicAtlasManager.Instance.ReleaseGetImageData(getImageData);
                mGetImageTaskDic.Remove(path);
            }
        }
    }
Beispiel #24
0
        protected IEnumerator createPack(string savePath = "")
        {
            if (savePath != "")
            {
                if (deletePreviousCacheVersion && Directory.Exists(Application.persistentDataPath + "/AssetPacker/" + cacheName + "/"))
                {
                    foreach (string dirPath in Directory.GetDirectories(Application.persistentDataPath + "/AssetPacker/" + cacheName + "/", "*", SearchOption.AllDirectories))
                    {
                        Directory.Delete(dirPath, true);
                    }
                }

                Directory.CreateDirectory(savePath);
            }

            List <Texture2D> textures = new List <Texture2D>();
            List <string>    images   = new List <string>();

            foreach (TextureToPack itemToRaster in itemsToRaster)
            {
                Texture2D baseTexture = itemToRaster.preLoadedTexture;

                if (!baseTexture)
                {
                    WWW loader = new WWW("file:///" + itemToRaster.file);

                    yield return(loader);

                    baseTexture = loader.texture;
                }

                if (itemToRaster.sliceParams != null)
                {
                    TextureToPack.GridSlice sliceParams = itemToRaster.sliceParams;

                    if (sliceParams.width > baseTexture.width || sliceParams.height > baseTexture.height)
                    {
                        throw new Exception(string.Format("Width and/or height of texture {0} is less than the provided slice parameters.", itemToRaster.id));
                    }

                    if (!(baseTexture.width % sliceParams.width == 0 && baseTexture.height % sliceParams.height == 0))
                    {
                        throw new Exception(string.Format("Width and/or height of texture {0} not a multiple of the provided slice parameters.", itemToRaster.id));
                    }

                    int totalRows    = baseTexture.height / sliceParams.height;
                    int totalColumns = baseTexture.width / sliceParams.width;

                    int textureIndex = 0;

                    // Scan each slice left to right, top to bottom
                    for (int rowIndex = 0; rowIndex < totalRows; ++rowIndex)
                    {
                        for (int columnIndex = 0; columnIndex < totalColumns; ++columnIndex)
                        {
                            int x = columnIndex * sliceParams.width;
                            int y = (totalRows - rowIndex - 1) * sliceParams.height;    // Starting from the top, not the bottom. Specific to GH3 sprite sheets, not nesacarily universal.

                            Color[]   pixels  = baseTexture.GetPixels(x, y, sliceParams.width, sliceParams.height);
                            Texture2D texture = new Texture2D(sliceParams.width, sliceParams.height);
                            texture.SetPixels(pixels);
                            texture.Apply();

                            textures.Add(texture);
                            images.Add(string.Format("{0}_{1}", itemToRaster.id, textureIndex.ToString("D8")));

                            ++textureIndex;
                        }
                    }
                }
                else
                {
                    textures.Add(baseTexture);
                    images.Add(itemToRaster.id);
                }
            }

            int textureSize = allow4096Textures ? 4096 : 2048;

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

            for (int i = 0; i < textures.Count; i++)
            {
                if (textures[i].width > textureSize || textures[i].height > textureSize)
                {
                    throw new Exception("A texture size is bigger than the sprite sheet size!");
                }
                else
                {
                    rectangles.Add(new Rect(0, 0, textures[i].width, textures[i].height));
                }
            }

            const int padding = 1;

            int numSpriteSheet = 0;

            while (rectangles.Count > 0)
            {
                Texture2D texture   = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false);
                Color32[] fillColor = texture.GetPixels32();
                for (int i = 0; i < fillColor.Length; ++i)
                {
                    fillColor[i] = Color.clear;
                }

                RectanglePacker packer = new RectanglePacker(texture.width, texture.height, padding);

                for (int i = 0; i < rectangles.Count; i++)
                {
                    packer.insertRectangle((int)rectangles[i].width, (int)rectangles[i].height, i);
                }

                packer.packRectangles();

                if (packer.rectangleCount > 0)
                {
                    texture.SetPixels32(fillColor);
                    IntegerRectangle    rect          = new IntegerRectangle();
                    List <TextureAsset> textureAssets = new List <TextureAsset>();

                    List <Rect>      garbageRect    = new List <Rect>();
                    List <Texture2D> garabeTextures = new List <Texture2D>();
                    List <string>    garbageImages  = new List <string>();

                    for (int j = 0; j < packer.rectangleCount; j++)
                    {
                        rect = packer.getRectangle(j, rect);

                        int index = packer.getRectangleId(j);

                        texture.SetPixels32(rect.x, rect.y, rect.width, rect.height, textures[index].GetPixels32());

                        TextureAsset textureAsset = new TextureAsset();
                        textureAsset.x      = rect.x;
                        textureAsset.y      = rect.y;
                        textureAsset.width  = rect.width;
                        textureAsset.height = rect.height;
                        textureAsset.name   = images[index];

                        textureAssets.Add(textureAsset);

                        garbageRect.Add(rectangles[index]);
                        garabeTextures.Add(textures[index]);
                        garbageImages.Add(images[index]);
                    }

                    foreach (Rect garbage in garbageRect)
                    {
                        rectangles.Remove(garbage);
                    }

                    foreach (Texture2D garbage in garabeTextures)
                    {
                        textures.Remove(garbage);
                    }

                    foreach (string garbage in garbageImages)
                    {
                        images.Remove(garbage);
                    }

                    texture.Apply();

                    if (savePath != "")
                    {
                        File.WriteAllBytes(savePath + "/data" + numSpriteSheet + ".png", texture.EncodeToPNG());
                        File.WriteAllText(savePath + "/data" + numSpriteSheet + ".json", JsonUtility.ToJson(new TextureAssets(textureAssets.ToArray()), true));
                        ++numSpriteSheet;
                    }

                    foreach (TextureAsset textureAsset in textureAssets)
                    {
                        Sprite sprite = Sprite.Create(texture, new Rect(textureAsset.x, textureAsset.y, textureAsset.width, textureAsset.height), spritePivot, pixelsPerUnit, 0, SpriteMeshType.FullRect);
                        sprite.name = textureAsset.name;
                        mSprites.Add(textureAsset.name, sprite);
                    }
                }
            }

            OnProcessCompleted.Invoke();
        }
Beispiel #25
0
 void RemoveFreeArea(int index, IntegerRectangle data)
 {
     DynamicAtlasManager.Instance.ReleaseRectangle(data);
     mFreeAreasList[index].Remove(data);
 }
Beispiel #26
0
    void AddFreeArea(int index, IntegerRectangle data)
    {
        List <IntegerRectangle> list = mFreeAreasList[index];

        list.Add(data);
    }
        public bool Push(string key, Texture2D texture)
        {
            if (string.IsNullOrEmpty(key))
            {
                return(true);
            }

            if (texture == null)
            {
                return(true);
            }

            for (int i = 0; i < m_sprites.Count; i++)
            {
                m_sprites[i].index = i;
                m_sprites[i].color = m_texture.GetPixels((int)m_sprites[i].rect.x, (int)m_sprites[i].rect.y, (int)m_sprites[i].rect.width, (int)m_sprites[i].rect.height);
            }

            m_sprites.Add(new DynamicSprite()
            {
                key   = key,
                index = -1,
                rect  = new Rect(0, 0, texture.width, texture.height),
                color = texture.GetPixels(),
            });

            m_packer.reset(width, height, padding);

            for (int i = 0; i < m_sprites.Count; i++)
            {
                m_packer.insertRectangle((int)m_sprites[i].rect.width, (int)m_sprites[i].rect.height, m_sprites[i].index);
            }

            int count = m_packer.packRectangles();

            enough = m_sprites.Count > count;

            if (enough)
            {
                m_sprites.RemoveAt(m_sprites.FindIndex(x => x.key == key));

                for (int i = 0; i < m_sprites.Count; i++)
                {
                    m_sprites[i].color = null;
                }

                return(false);
            }
            else
            {
                if (texture != null)
                {
                    texture = null;
                }

                if (m_texture.format != TextureFormat.RGBA32)
                {
                    Object.Destroy(m_texture);

                    m_texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
                }
                m_texture.SetPixels32(m_color);

                IntegerRectangle rect = new IntegerRectangle();

                Color32[] color;

                int index, id, size;

                for (int i = 0; i < count; i++)
                {
                    rect = m_packer.getRectangle(i, rect);

                    id = m_packer.getRectangleId(i);

                    index = m_sprites.FindIndex(x => x.index == id);

                    if (index != -1)
                    {
                        m_sprites[index].rect = new Rect(rect.x, rect.y, rect.width, rect.height);

                        color = new Color32[m_sprites[index].color.Length];

                        for (int j = 0; j < m_sprites[index].color.Length; j++)
                        {
                            color[j] = m_sprites[index].color[j];
                        }
                    }
                    else
                    {
                        size = rect.width * rect.height;

                        color = new Color32[size];

                        for (int j = 0; j < size; j++)
                        {
                            color[j] = Color.black;
                        }
                    }
                    m_texture.SetPixels32(rect.x, rect.y, rect.width, rect.height, color);
                }

                for (int i = 0; i < m_sprites.Count; i++)
                {
                    m_sprites[i].color = null;
                }

                if (compress)
                {
                    m_texture.Compress(true);
                }

                m_texture.Apply();

                return(true);
            }
        }
Beispiel #28
0
    void OnRenderTexture(string path, Texture2D data, GetImageData imageData)
    {
        if (data == null)
        {
            for (int i = mGetImageTasks.Count - 1; i >= 0; i--)
            {
                GetImageData item = mGetImageTasks[i];
                if (item.path.Equals(path))
                {
                    if (item.callback != null)
                    {
                        item.callback(null, new Rect(0, 0, 0, 0), path);
                    }
                    if (AtlasConfig.kUsingCopyTexture)
                    {
                        if (item.callback != null)
                        {
                            item.callback(null, new Rect(0, 0, 0, 0), path);//完成一个任务,就回调一个任务
                        }
                    }
                    else
                    {
                        if (item.BlitCallback != null)
                        {
                            item.BlitCallback(null, new Rect(0, 0, 0, 0), path);//完成一个任务,就回调一个任务
                        }
                    }

                    DynamicAtlasManager.Instance.ReleaseGetImageData(item);
                    mGetImageTasks.RemoveAt(i);
                }
            }
            return;
        }
        int index;
        IntegerRectangle useArea = InsertArea(data.width, data.height, out index);

        Rect uv = new Rect((useArea.x + offset) * mUVXDiv, (useArea.y + offset) * mUVYDiv, (useArea.width - mPadding - offset * 2) * mUVXDiv, (useArea.height - mPadding - offset * 2) * mUVYDiv);

        if (AtlasConfig.kUsingCopyTexture)
        {
            CopyTexture(useArea.x, useArea.y, index, data);
        }
        else
        {
            BlitTexture(useArea.x, useArea.y, index, data);
        }

        SaveImageData _SaveImageData = DynamicAtlasManager.Instance.AllocateSaveImageData(uv);

        _SaveImageData.texIndex  = index;
        _SaveImageData.rectangle = useArea;
        _usingRect[path]         = _SaveImageData;

        for (int i = mGetImageTasks.Count - 1; i >= 0; i--)
        {
            GetImageData item = mGetImageTasks[i];
            if (item.path.Equals(path))
            {
                _usingRect[path].referenceCount = _usingRect[path].referenceCount + 1;
                if (AtlasConfig.kUsingCopyTexture)
                {
                    if (item.callback != null)
                    {
                        Texture2D dstTex = m_tex2DList[index];
                        item.callback(dstTex, uv, path);//完成一个任务,就回调一个任务
                    }
                }
                else
                {
                    if (item.BlitCallback != null)
                    {
                        Material material = m_MaterialList[index];
                        item.BlitCallback(material, uv, path);//完成一个任务,就回调一个任务
                    }
                }
                DynamicAtlasManager.Instance.ReleaseGetImageData(item);
                mGetImageTasks.RemoveAt(i);
            }
        }
    }
 public void ReleaseRectangle(IntegerRectangle rectangle)
 {
     mRectangleStack.Add(rectangle);
 }
Beispiel #30
0
    void DrawFreeArea(int index, PackingAtlas packingAtlas)
    {
        Texture2D tex2D = null;

        if (texList.Count < index + 1)
        {
            tex2D = new Texture2D((int)_mGroup, (int)_mGroup, TextureFormat.ARGB32, false, true);
            texList.Add(tex2D);
            if (mFillColor == null)
            {
                mFillColor = tex2D.GetPixels32();
                for (int i = 0; i < mFillColor.Length; ++i)
                {
                    mFillColor[i] = Color.clear;
                }
            }
        }
        else
        {
            tex2D = texList[index];
        }
        tex2D.SetPixels32(mFillColor);
        if (isRefreshFreeAreas)
        {
            Color32[] tmpColor;
            List <IntegerRectangle> freeList = packingAtlas.GetFreeAreas()[index];
            int count = freeList.Count;
            for (int i = 0; i < count; i++)
            {
                IntegerRectangle item = freeList[i];
                int size = item.width * item.height;
                //---------------------------------描边,可能太费
                //tmpColor = new Color32[size];
                //for (int k = 0; k < size; ++k)
                //{
                //    tmpColor[k] = Color.green;//画边
                //}
                //tex2D.SetPixels32(item.x, item.y, item.width, item.height, tmpColor);
                //-------------------------
                int outLineSize = 2;
                if (item.width < outLineSize * 2 || item.height < outLineSize * 2)
                {
                    outLineSize = 0;
                }
                Color color = convertHexToRGBA((uint)(0xFF171703 + (((18 * ((i + 4) % 13)) << 16) + ((31 * ((i * 3) % 8)) << 8) + 63 * (((i + 1) * 3) % 5))));
                color.a  = 0.5f;
                size    -= outLineSize * 4;
                tmpColor = new Color32[size];
                for (int k = 0; k < size; ++k)
                {
                    tmpColor[k] = color;
                }
                tex2D.SetPixels32(item.x + outLineSize, item.y + outLineSize, item.width - outLineSize * 2, item.height - outLineSize * 2, tmpColor);
                tex2D.Apply();
            }
        }

        float poxX = (index + 1) * 10 + index * packingAtlas.atlasWidth * scale;

        GUI.DrawTexture(new Rect(poxX, formPosY, packingAtlas.atlasWidth * scale, packingAtlas.atlasHeight * scale), tex2D);
    }