コード例 #1
0
            public void ReleaseAndMerge(AtlasNodePool pool)
            {
                Int16 n = m_Self;

                do
                {
                    pool.m_Nodes[n].ReleaseChildren(pool);
                    pool.m_Nodes[n].ClearIsOccupied();
                    n = pool.m_Nodes[n].m_Parent;
                }while (n >= 0 && pool.m_Nodes[n].IsMergeNeeded(pool));
            }
コード例 #2
0
            public void ReleaseChildren(AtlasNodePool pool)
            {
                if (IsLeafNode())
                {
                    return;
                }
                pool.m_Nodes[m_LeftChild].ReleaseChildren(pool);
                pool.m_Nodes[m_RightChild].ReleaseChildren(pool);

                pool.AtlasNodeFree(m_LeftChild);
                pool.AtlasNodeFree(m_RightChild);
                m_LeftChild  = -1;
                m_RightChild = -1;
            }
コード例 #3
0
        public AtlasAllocatorDynamic(int width, int height, int capacityAllocations)
        {
            // In an evenly split binary tree, the nodeCount == leafNodeCount * 2
            int capacityNodes = capacityAllocations * 2;

            Debug.Assert(capacityNodes < (1 << 16), "Error: AtlasAllocatorDynamic: Attempted to allocate a capacity of " + capacityNodes + ", which is greater than our 16-bit indices can support. Please request a capacity <=" + (1 << 16));
            m_Pool = new AtlasNodePool((Int16)capacityNodes);

            m_NodeFromID = new Dictionary <int, Int16>(capacityAllocations);

            Int16 rootParent = -1;

            m_Root = m_Pool.AtlasNodeCreate(rootParent);
            m_Pool.m_Nodes[m_Root].m_Rect.Set(width, height, 0, 0);
            m_Width  = width;
            m_Height = height;

            // string debug = "";
            // DebugStringFromNode(ref debug, m_Root);
            // Debug.Log("Allocating atlas = " + debug);
        }
コード例 #4
0
 public bool IsMergeNeeded(AtlasNodePool pool)
 {
     return(pool.m_Nodes[m_LeftChild].IsLeafNode() && (!pool.m_Nodes[m_LeftChild].IsOccupied()) &&
            pool.m_Nodes[m_RightChild].IsLeafNode() && (!pool.m_Nodes[m_RightChild].IsOccupied()));
 }
コード例 #5
0
            public Int16 Allocate(AtlasNodePool pool, int width, int height)
            {
                if (Mathf.Min(width, height) < 1)
                {
                    // Degenerate allocation requested.
                    Debug.Assert(false, "Error: Texture2DAtlasDynamic: Attempted to allocate a degenerate region. Please ensure width and height are >= 1");
                    return(-1);
                }

                // not a leaf node, try children
                // TODO: Rather than always going left, then right, we might want to always attempt to allocate in the smaller child, then larger.
                if (!IsLeafNode())
                {
                    Int16 node = pool.m_Nodes[m_LeftChild].Allocate(pool, width, height);
                    if (node == -1)
                    {
                        node = pool.m_Nodes[m_RightChild].Allocate(pool, width, height);
                    }
                    return(node);
                }

                // leaf node, check for fit
                if (IsOccupied())
                {
                    return(-1);
                }
                if (width > m_Rect.x || height > m_Rect.y)
                {
                    return(-1);
                }

                // perform the split
                Debug.Assert(m_LeftChild == -1);
                Debug.Assert(m_RightChild == -1);
                m_LeftChild  = pool.AtlasNodeCreate(m_Self);
                m_RightChild = pool.AtlasNodeCreate(m_Self);
                // Debug.Log("m_LeftChild = " + m_LeftChild);
                // Debug.Log("m_RightChild = " + m_RightChild);

                Debug.Assert(m_LeftChild >= 0 && m_LeftChild < pool.m_Nodes.Length);
                Debug.Assert(m_RightChild >= 0 && m_RightChild < pool.m_Nodes.Length);

                // Debug.Log("Rect = {" + m_Rect.x + ", " + m_Rect.y + ", " + m_Rect.z + ", " + m_Rect.w + "}");

                float deltaX = m_Rect.x - width;
                float deltaY = m_Rect.y - height;

                // Debug.Log("deltaX = " + deltaX);
                // Debug.Log("deltaY = " + deltaY);

                if (deltaX >= deltaY)
                {
                    // Debug.Log("Split horizontally");
                    //  +--------+------+
                    //  |        |      |
                    //  |        |      |
                    //  |        |      |
                    //  |        |      |
                    //  +--------+------+
                    pool.m_Nodes[m_LeftChild].m_Rect.x = width;
                    pool.m_Nodes[m_LeftChild].m_Rect.y = m_Rect.y;
                    pool.m_Nodes[m_LeftChild].m_Rect.z = m_Rect.z;
                    pool.m_Nodes[m_LeftChild].m_Rect.w = m_Rect.w;

                    pool.m_Nodes[m_RightChild].m_Rect.x = deltaX;
                    pool.m_Nodes[m_RightChild].m_Rect.y = m_Rect.y;
                    pool.m_Nodes[m_RightChild].m_Rect.z = m_Rect.z + width;
                    pool.m_Nodes[m_RightChild].m_Rect.w = m_Rect.w;

                    if (deltaY < 1)
                    {
                        pool.m_Nodes[m_LeftChild].SetIsOccupied();
                        return(m_LeftChild);
                    }
                    else
                    {
                        Int16 node = pool.m_Nodes[m_LeftChild].Allocate(pool, width, height);
                        if (node >= 0)
                        {
                            pool.m_Nodes[node].SetIsOccupied();
                        }
                        return(node);
                    }
                }
                else
                {
                    // Debug.Log("Split vertically.");
                    //  +---------------+
                    //  |               |
                    //  |---------------|
                    //  |               |
                    //  |               |
                    //  +---------------+
                    pool.m_Nodes[m_LeftChild].m_Rect.x = m_Rect.x;
                    pool.m_Nodes[m_LeftChild].m_Rect.y = height;
                    pool.m_Nodes[m_LeftChild].m_Rect.z = m_Rect.z;
                    pool.m_Nodes[m_LeftChild].m_Rect.w = m_Rect.w;

                    pool.m_Nodes[m_RightChild].m_Rect.x = m_Rect.x;
                    pool.m_Nodes[m_RightChild].m_Rect.y = deltaY;
                    pool.m_Nodes[m_RightChild].m_Rect.z = m_Rect.z;
                    pool.m_Nodes[m_RightChild].m_Rect.w = m_Rect.w + height;

                    if (deltaX < 1)
                    {
                        pool.m_Nodes[m_LeftChild].SetIsOccupied();
                        return(m_LeftChild);
                    }
                    else
                    {
                        Int16 node = pool.m_Nodes[m_LeftChild].Allocate(pool, width, height);
                        if (node >= 0)
                        {
                            pool.m_Nodes[node].SetIsOccupied();
                        }
                        return(node);
                    }
                }
            }