private void Init()
 {
     nodeMaxLevel = Mathf.FloorToInt(Mathf.Log(worldLength / objMinLength, 2f) + 1);
     InitGrid();
     BulidTree();
     rootNode = nodes[0][0];
 }
 private void InitGrid()
 {
     nodes = new GridQuadTreeNode <T> [nodeMaxLevel + 1][];
     for (int i = 0; i <= nodeMaxLevel; i++)
     {
         nodes[i] = new GridQuadTreeNode <T> [(int)Mathf.Pow(4, i)];
     }
 }
        private void ChangeAllParentChildrenItemCount(GridQuadTreeNode <T> node, int deltaVal)
        {
            int pIndex = node.ParentIndex;
            int pLevel = node.NodeLevel - 1;

            for ( ; pLevel >= 0; pLevel--)
            {
                nodes[pLevel][pIndex].ChildrenItemCount += deltaVal;
                pIndex = nodes[pLevel][pIndex].ParentIndex;
            }
        }
        private void BulidTree()
        {
            for (int i = 0; i <= nodeMaxLevel; i++)
            {
                int   sideNodeCount = (int)Mathf.Pow(2, i);
                float cellLength    = worldLength / sideNodeCount;

                for (int r = 0; r < sideNodeCount; r++)
                {
                    for (int c = 0; c < sideNodeCount; c++)
                    {
                        Rect nodeRect = new Rect(worldRect.min.x + c * cellLength, worldRect.min.y + r * cellLength, cellLength, cellLength);
                        nodes[i][r * sideNodeCount + c] = new GridQuadTreeNode <T>(this, nodeRect, i, i == nodeMaxLevel, ItemMove);
                    }
                }
            }
        }
        private void GetItems(GridQuadTreeNode <T> parentNode, Rect resultRect, ref List <GridQuadTreeItem <T> > itemsList)
        {
            parentNode.GetItems(resultRect, ref itemsList);

            if (parentNode.IsLeaf || parentNode.ChildrenItemCount == 0)
            {
                return;
            }

            var nodeTopLeft = nodes[parentNode.NodeLevel + 1][parentNode.TopLeftIndex];

            if (nodeTopLeft.looseRect.Overlaps(resultRect))
            {
                GetItems(nodeTopLeft, resultRect, ref itemsList);
            }

            var nodeTopRight = nodes[parentNode.NodeLevel + 1][parentNode.TopRightIndex];

            if (nodeTopRight.looseRect.Overlaps(resultRect))
            {
                GetItems(nodeTopRight, resultRect, ref itemsList);
            }

            var nodeBottomLeft = nodes[parentNode.NodeLevel + 1][parentNode.BottomLeftIndex];

            if (nodeBottomLeft.looseRect.Overlaps(resultRect))
            {
                GetItems(nodeBottomLeft, resultRect, ref itemsList);
            }

            var nodeBottomRight = nodes[parentNode.NodeLevel + 1][parentNode.BottomRightIndex];

            if (nodeBottomRight.looseRect.Overlaps(resultRect))
            {
                GetItems(nodeBottomRight, resultRect, ref itemsList);
            }
        }
 private void ItemMove(GridQuadTreeItem <T> item, GridQuadTreeNode <T> node)
 {
     ChangeAllParentChildrenItemCount(node, -1);
     Insert(item);
 }