예제 #1
0
    private void CalculateElementPacking()
    {
        int elementCount = elements.Count;

        //use the min area of all the elements to start with a sensible estimated size for the atlas to be
        int minArea = 0;

        for (int e = 0; e < elementCount; e++)
        {
            minArea += elements[e].expandedWidth * elements[e].expandedHeight;
        }

        int tryWidth  = 16;
        int tryHeight = 16;

        int tries = 0;

        while ((tryWidth - link.padding) * (tryHeight - link.padding) < minArea && tries++ < 100)
        {
            if (tries % 2 == 0)            //alternate increasing width and height until we find a size that fits everything
            {
                tryWidth *= 2;
            }
            else
            {
                tryHeight *= 2;
            }
        }

        tries = 0;

        //subtract padding because we can't pack right up to the padded border
        //but don't subtract padding*2 because the element sizes already account for padding on one side
        PRPacker packer = new PRPacker(tryWidth - link.padding, tryHeight - link.padding);

        while (tries++ < 100)        //tries is to prevent infinite loops
        {
            bool didFail = false;
            for (int e = 0; e < elementCount; e++)
            {
                PRAtlasElement element = elements[e];

                //Debug.Log("Try fitting " + element.expandedWidth + ", " + element.expandedHeight + " into " + tryWidth+","+tryHeight);
                //TODO update
                PRRect rect = packer.Insert(element.expandedWidth, element.expandedHeight, PRPacker.ChoiceHeuristic.ShortSideFit);

                if (rect.width == 0 && rect.height == 0)                //both at 0 means it failed
                {
                    didFail = true;

                    if (tryWidth <= tryHeight)                    //alternate increasing width and height until we find a size that fits everything
                    {
                        tryWidth *= 2;
                    }
                    else
                    {
                        tryHeight *= 2;
                    }

                    packer.Init(tryWidth - link.padding, tryHeight - link.padding);
                    break;
                }
                else
                {
                    element.packedRect    = rect;
                    element.packedRect.x += element.padding;                     //push the rect off the wall (note, y doesn't need this for the reason below)
                    //flip packing y coord. This is because the algorithm tries to pack everything around 0,0
                    //and we want 0,0 to be top left instead of bottom left (which it would be with Unity's coord system)
                    //there's no real reason for it to be top left, except that it's what people are used to.
                    element.packedRect.y = (tryHeight - element.packedRect.y) - element.packedRect.height;
                }
            }

            if (!didFail)
            {
                atlasWidth  = tryWidth;
                atlasHeight = tryHeight;
                break;                 //we're done!
            }
        }
    }
예제 #2
0
    private void CalculateElementPacking()
    {
        int elementCount = elements.Count;

        //use the min area of all the elements to start with a sensible estimated size for the atlas to be
        int minArea = 0;

        for(int e = 0; e<elementCount; e++)
        {
            minArea += elements[e].expandedWidth * elements[e].expandedHeight;
        }

        int tryWidth = 16;
        int tryHeight = 16;

        int tries = 0;

        while((tryWidth-link.padding)*(tryHeight-link.padding) < minArea && tries++ < 100)
        {
            if(tries % 2 == 0) //alternate increasing width and height until we find a size that fits everything
            {
                tryWidth *= 2;
            }
            else
            {
                tryHeight *= 2;
            }
        }

        tries = 0;

        //subtract padding because we can't pack right up to the padded border
        //but don't subtract padding*2 because the element sizes already account for padding on one side
        PRPacker packer = new PRPacker(tryWidth-link.padding,tryHeight-link.padding);

        while(tries++ < 100) //tries is to prevent infinite loops
        {
            bool didFail = false;
            for(int e = 0; e<elementCount; e++)
            {
                PRAtlasElement element = elements[e];

                //Debug.Log("Try fitting " + element.expandedWidth + ", " + element.expandedHeight + " into " + tryWidth+","+tryHeight);
                //TODO update
                PRRect rect = packer.Insert(element.expandedWidth,element.expandedHeight, PRPacker.ChoiceHeuristic.ShortSideFit);

                if(rect.width == 0 && rect.height == 0) //both at 0 means it failed
                {
                    didFail = true;

                    if(tryWidth <= tryHeight) //alternate increasing width and height until we find a size that fits everything
                    {
                        tryWidth *= 2;
                    }
                    else
                    {
                        tryHeight *= 2;
                    }

                    packer.Init(tryWidth-link.padding,tryHeight-link.padding);
                    break;
                }
                else
                {
                    element.packedRect = rect;
                    element.packedRect.x += element.padding; //push the rect off the wall (note, y doesn't need this for the reason below)
                    //flip packing y coord. This is because the algorithm tries to pack everything around 0,0
                    //and we want 0,0 to be top left instead of bottom left (which it would be with Unity's coord system)
                    //there's no real reason for it to be top left, except that it's what people are used to.
                    element.packedRect.y = (tryHeight - element.packedRect.y) - element.packedRect.height;
                }
            }

            if(!didFail)
            {
                atlasWidth = tryWidth;
                atlasHeight = tryHeight;
                break; //we're done!
            }
        }
    }