public IItem AddItem(IsoRect bounds, T content)
 {
     if (bounds.x.size > 0.0f && bounds.y.size > 0.0f)
     {
         if (_rootNode == null)
         {
             var initial_side = IsoUtils.Vec2From(
                 IsoUtils.Vec2MaxF(bounds.size));
             var initial_bounds = new IsoRect(
                 bounds.center - initial_side * 2.0f,
                 bounds.center + initial_side * 2.0f);
             _rootNode = _nodePool.Take().Init(null, initial_bounds);
         }
         Item item;
         while (!_rootNode.AddItem(bounds, content, out item, _nodePool, _itemPool))
         {
             GrowUp(
                 bounds.center.x < _rootNode.SelfBounds.center.x,
                 bounds.center.y < _rootNode.SelfBounds.center.y);
         }
         return(item);
     }
     else
     {
         return(_itemPool.Take().Init(null, bounds, content));
     }
 }
 public bool AddItem(
     IsoRect bounds, T content, out Item item,
     IsoIPool <Node> node_pool, IsoIPool <Item> item_pool)
 {
     if (!SelfBounds.Contains(bounds))
     {
         item = null;
         return(false);
     }
     for (int i = 0, e = Nodes.Length; i < e; ++i)
     {
         var node = Nodes[i];
         if (node != null)
         {
             if (node.AddItem(bounds, content, out item, node_pool, item_pool))
             {
                 return(true);
             }
         }
         else if (Items.Count >= MinChildCountPerNode && NodeBounds[i].Contains(bounds))
         {
             Nodes[i] = node = node_pool.Take().Init(this, NodeBounds[i]);
             if (node.AddItem(bounds, content, out item, node_pool, item_pool))
             {
                 return(true);
             }
         }
     }
     item = item_pool.Take().Init(this, bounds, content);
     Items.Add(item);
     return(true);
 }
 public Item Init(Node owner, IsoRect bounds, T content)
 {
     Owner   = owner;
     Bounds  = bounds;
     Content = content;
     return(this);
 }
            //
            // Private
            //

            Node FillNodeBounds()
            {
                var size   = SelfBounds.size * 0.5f;
                var center = SelfBounds.center;

                {                 // LT
                    var rect = new IsoRect(center - size, center);
                    NodeBounds[0] = rect;
                }
                {                 // RT
                    var rect = new IsoRect(center - size, center);
                    rect.Translate(size.x, 0.0f);
                    NodeBounds[1] = rect;
                }
                {                 // LB
                    var rect = new IsoRect(center, center + size);
                    rect.Translate(-size.x, 0.0f);
                    NodeBounds[2] = rect;
                }
                {                 // RB
                    var rect = new IsoRect(center, center + size);
                    NodeBounds[3] = rect;
                }
                return(this);
            }
 public void VisitItemsByBounds(IsoRect bounds, IContentLookUpper look_upper)
 {
     if (look_upper == null)
     {
         throw new System.ArgumentNullException("look_upper");
     }
     if (_rootNode != null)
     {
         _rootNode.VisitItemsByBounds(bounds, look_upper);
     }
 }
 void BackwardVisitNodes(Node node, IsoRect bounds, IContentLookUpper loop_upper)
 {
     while (node != null)
     {
         for (int i = 0, e = node.Items.Count; i < e; ++i)
         {
             var item = node.Items[i];
             if (bounds.Overlaps(item.Bounds))
             {
                 loop_upper.LookUp(item.Content);
             }
         }
         node = node.Parent;
     }
 }
        public IItem MoveItem(IsoRect bounds, IItem iitem)
        {
            var item      = GetItemWithCast(iitem);
            var item_node = item.Owner;

            if (item_node != null)
            {
                if (item_node.SelfBounds.Contains(bounds) && item_node.Items.Count <= MinChildCountPerNode)
                {
                    item.Bounds = bounds;
                    return(item);
                }
                else
                {
                    var content = item.Content;
                    item_node.RemoveItem(item, _itemPool);
                    if (item_node.Items.Count == 0)
                    {
                        item_node = BackwardNodeCleanUp(item_node) ?? _rootNode;
                    }
                    while (item_node != null)
                    {
                        Item new_item;
                        if (item_node.SelfBounds.Contains(bounds))
                        {
                            if (item_node.AddItem(bounds, content, out new_item, _nodePool, _itemPool))
                            {
                                return(new_item);
                            }
                        }
                        item_node = item_node.Parent;
                    }
                    return(AddItem(bounds, content));
                }
            }
            else
            {
                var content = item.Content;
                _itemPool.Release(item.Clear());
                return(AddItem(bounds, content));
            }
        }
 public void VisitItemsByBounds(
     IsoRect bounds, IContentLookUpper look_upper)
 {
     if (bounds.Overlaps(SelfBounds))
     {
         for (int i = 0, e = Items.Count; i < e; ++i)
         {
             var item = Items[i];
             if (bounds.Overlaps(item.Bounds))
             {
                 look_upper.LookUp(item.Content);
             }
         }
         for (int i = 0, e = Nodes.Length; i < e; ++i)
         {
             var node = Nodes[i];
             if (node != null)
             {
                 node.VisitItemsByBounds(bounds, look_upper);
             }
         }
     }
 }
 public Node Init(Node parent, IsoRect bounds)
 {
     Parent     = parent;
     SelfBounds = bounds;
     return(FillNodeBounds());
 }