示例#1
0
        public bool Add(NativeAPI.stbrp_rect rect)
        {
            if (rect.w > m_atlasSize || rect.h > m_atlasSize)
            {
                if (IsGrowable())
                {
                    Realloc(Mathf.Max(rect.w, rect.h));
                }
                else
                {
                    throw new Exception();
                }
            }
            var requireArea = rect.w * rect.h;
            var totalArea   = m_atlasSize * m_atlasSize;

            if (totalArea - m_usedArea - requireArea <= 0)
            {
                return(false);
            }
RETRY:
            fixed(NativeAPI.stbrp_context *ctx_ = &m_ctx)
            {
                NativeAPI.stbrp_pack_rects(ctx_, &rect, 1);
            }

            if (rect.was_packed != 0)
            {
                var maxx = rect.x + rect.w;
                var maxy = rect.y + rect.h;
                if (maxx > m_usedWidth)
                {
                    m_usedWidth = maxx;
                }
                if (maxy > m_usedHeight)
                {
                    m_usedHeight = maxy;
                }
                m_usedArea += requireArea;
                m_packedRects.Add(rect);
                return(true);
            }
            else
            {
                if (IsGrowable())
                {
                    Realloc(m_atlasSize << 1);
                    goto RETRY;
                }
            }
            return(false);
        }
示例#2
0
        public void Realloc(int maxSize)
        {
            maxSize = MathLib.CeilPowerOfTwo(maxSize);
            if (maxSize != m_atlasSize)
            {
                if (m_pool != null)
                {
                    m_poolHandle.Free();
                }
                m_usedWidth  = 0;
                m_usedHeight = 0;
                m_usedArea   = 0;
                m_atlasSize  = maxSize;
                m_pool       = new NativeAPI.stbrp_node[m_atlasSize * 4];
                UDebug.Assert(m_pool != null && m_pool.Length > 0);
                m_poolHandle = GCHandle.Alloc(m_pool, GCHandleType.Pinned);
                var packedRects = m_packedRects;
                m_packedRects = new List <NativeAPI.stbrp_rect>();
                m_ctx         = new NativeAPI.stbrp_context();
                fixed(NativeAPI.stbrp_context *_ctx = &m_ctx)
                {
                    NativeAPI.stbrp_init_target(_ctx, m_atlasSize, m_atlasSize, (NativeAPI.stbrp_node *)m_poolHandle.AddrOfPinnedObject(), m_pool.Length);
                    NativeAPI.stbrp_setup_allow_out_of_mem(_ctx, 1);
                }

                for (int i = 0; i < packedRects.Count; ++i)
                {
                    var rect  = packedRects[i];
                    var _rect = new NativeAPI.stbrp_rect();
                    _rect.w  = rect.w;
                    _rect.h  = rect.h;
                    _rect.id = rect.id;
                    if (!Add(rect))
                    {
                        UDebug.LogError("Realloc failed!");
                        break;
                    }
                }
            }
        }