/// <summary> /// Handles item movement /// </summary> /// <param name="item">The item that moved</param> public void ItemMove(QuadTreePositionItem <T> item) { //CreamXProfiler.StartProfiling("QuadTree: ItemMove"); // Find the item if (Items.Contains(item)) { int i = Items.IndexOf(item); // Try to push the item down to the child if (!PushItemDown(i)) { // otherwise, if not root, push up if (ParentNode != null) { PushItemUp(i); } else if (!ContainsRect(item.Rect)) { WorldResize(new FRect( Vector2.Min(Rect.TopLeft, item.Rect.TopLeft) * 2, Vector2.Max(Rect.BottomRight, item.Rect.BottomRight) * 2)); } } } else { // this node doesn't contain that item, stop notifying it about it //item.Move -= new QuadTreePositionItem<T>.MoveHandler(ItemMove); } //CreamXProfiler.StopProfiling("QuadTree: ItemMove"); }
/// <summary> /// Push an item up to this node's parent /// </summary> /// <param name="i">The index of the item to push up</param> public void PushItemUp(int i) { QuadTreePositionItem <T> m = Items[i]; RemoveItem(i); ParentNode.Insert(m); }
/// <summary> /// Inserts an item into one of this node's children /// </summary> /// <param name="item">The item to insert in a child</param> /// <returns>Whether or not the insert succeeded</returns> protected bool InsertInChild(QuadTreePositionItem <T> item) { if (!IsPartitioned) { return(false); } if (TopLeftNode.ContainsRect(item.Rect)) { TopLeftNode.Insert(item); } else if (TopRightNode.ContainsRect(item.Rect)) { TopRightNode.Insert(item); } else if (BottomLeftNode.ContainsRect(item.Rect)) { BottomLeftNode.Insert(item); } else if (BottomRightNode.ContainsRect(item.Rect)) { BottomRightNode.Insert(item); } else { return(false); // insert in child failed } return(true); }
/// <summary> /// Removes an item from this node /// </summary> /// <param name="item">The item to remove</param> public void RemoveItem(QuadTreePositionItem <T> item) { // Find and remove the item if (Items.Contains(item)) { //item.Move -= new QuadTreePositionItem<T>.MoveHandler(ItemMove); //item.Destroy -= new QuadTreePositionItem<T>.DestroyHandler(ItemDestroy); Items.Remove(item); } }
/// <summary> /// Inserts an item into the QuadTree /// </summary> /// <param name="item">The item to insert</param> /// <remarks>Checks to see if the world needs resizing and does so if needed</remarks> public void Insert(QuadTreePositionItem <T> item) { // check if the world needs resizing if (!headNode.ContainsRect(item.Rect)) { Resize(new FRect( Vector2.Min(headNode.Rect.TopLeft, item.Rect.TopLeft) * 2, Vector2.Max(headNode.Rect.BottomRight, item.Rect.BottomRight) * 2)); } item.node = null; item.quadTree = this; headNode.Insert(item); }
/// <summary> /// Insert an item in this node /// </summary> /// <param name="item">The item to insert</param> public void Insert(QuadTreePositionItem <T> item) { // If partitioned, try to find child node to add to if (!InsertInChild(item)) { //item.Destroy += new QuadTreePositionItem<T>.DestroyHandler(ItemDestroy); //item.Move += new QuadTreePositionItem<T>.MoveHandler(ItemMove); Items.Add(item); item.node = this; // Check if this node needs to be partitioned if (!IsPartitioned && Items.Count >= MaxItems) { Partition(); } } }
/// <summary> /// Inserts an item into the QuadTree /// </summary> /// <param name="parent">The parent of the new position item</param> /// <param name="position">The position of the new position item</param> /// <param name="size">The size of the new position item</param> /// <returns>A new position item</returns> /// <remarks>Checks to see if the world needs resizing and does so if needed</remarks> public QuadTreePositionItem <T> Insert(T parent, Vector2 position, Vector2 size) { QuadTreePositionItem <T> item = new QuadTreePositionItem <T>(parent, position, size); // check if the world needs resizing if (!headNode.ContainsRect(item.Rect)) { Resize(new FRect( Vector2.Min(headNode.Rect.TopLeft, item.Rect.TopLeft) * 2, Vector2.Max(headNode.Rect.BottomRight, item.Rect.BottomRight) * 2)); } item.node = null; item.quadTree = this; headNode.Insert(item); return(item); }
/// <summary> /// Finds the node containing a specified item /// </summary> /// <param name="Item">The item to find</param> /// <returns>The node containing the item</returns> public QuadTreeNode <T> FindItemNode(QuadTreePositionItem <T> Item) { if (Items.Contains(Item)) { return(this); } else if (IsPartitioned) { QuadTreeNode <T> n = null; // Check the nodes that could contain the item if (TopLeftNode.ContainsRect(Item.Rect)) { n = TopLeftNode.FindItemNode(Item); } if (n == null && TopRightNode.ContainsRect(Item.Rect)) { n = TopRightNode.FindItemNode(Item); } if (n == null && BottomLeftNode.ContainsRect(Item.Rect)) { n = BottomLeftNode.FindItemNode(Item); } if (n == null && BottomRightNode.ContainsRect(Item.Rect)) { n = BottomRightNode.FindItemNode(Item); } return(n); } else { return(null); } }
/// <summary> /// Handles item destruction /// </summary> /// <param name="item">The item that is being destroyed</param> public void ItemDestroy(QuadTreePositionItem <T> item) { RemoveItem(item); }