/// <summary> /// Inserts object to given node or either one of it's childs. /// </summary> /// <param name="node">The node.</param> /// <param name="object">The object to be inserted.</param> private void InsertNodeObject(QuadNode node, WorldObject @object) { if (!node.Bounds.Contains(@object.Bounds)) { throw new Exception( "QuadTree:InsertNodeObject(): This should not happen, child does not fit within node bounds"); } // If there's no child-nodes and when new object is insertedi if node's object count will be bigger then MaximumObjectsPerLeaf, force a split. if (!node.HasChildNodes() && node.ContainedObjects.Count + 1 > this.MaximumObjectsPerLeaf) { this.SetupChildNodes(node); var childObjects = new List <WorldObject>(node.ContainedObjects.Values); // node's child objects. var childrenToRelocate = new List <WorldObject>(); // child object to be relocated. foreach (WorldObject childObject in childObjects) { foreach (QuadNode childNode in node.Nodes) { if (childNode == null) { continue; } if (childNode.Bounds.Contains(childObject.Bounds)) { childrenToRelocate.Add(childObject); } } } foreach (WorldObject childObject in childrenToRelocate) // relocate the child objects we marked. { this.RemoveObjectFromNode(childObject); this.InsertNodeObject(node, childObject); } } // Find a child-node that the object can be inserted. foreach (QuadNode childNode in node.Nodes) { if (childNode == null) { continue; } if (!childNode.Bounds.Contains(@object.Bounds)) { continue; } this.InsertNodeObject(childNode, @object); return; } this.AddObjectToNode(node, @object); // add the object to current node. }
private void ObjectPositionChanged(object sender, EventArgs e) { var @object = sender as WorldObject; if (@object == null) { return; } QuadNode node = this._objectToNodeLookup[@object]; if (node.Bounds.Contains(@object.Bounds) && !node.HasChildNodes()) { return; } this.RemoveObjectFromNode(@object); Insert(@object); if (node.Parent != null) { CheckChildNodes(node.Parent); } }