public Node(Quadtree <T> quadtree, Node parent, Node createrChild, object newObjectBounding) { this.quadtree = quadtree; Vector2 minPoint; var bb = Boundings.BoundingToBox(newObjectBounding); var rootBB = (BoundingBox)createrChild.bounding; var oldOrientation = FindNewNodeMinPoint(rootBB, bb, out minPoint); float childWidth = rootBB.Maximum.X - rootBB.Minimum.X; float childHeight = rootBB.Maximum.Y - rootBB.Minimum.Y; bounding = new BoundingBox(new Vector3(minPoint.X, minPoint.Y, float.MaxValue), new Vector3(minPoint.X + 2 * childWidth, minPoint.Y + 2 * childHeight, float.MinValue)); this.parent = parent; this.depth = createrChild.depth + 1; createrChild.parent = this; for (int i = 0; i < 4; i++) { int r = i % 2; int t = i / 2; if (oldOrientation.Right == (r == 1) && (oldOrientation.Top == (t == 1))) { children[i] = createrChild; } else { children[i] = new Node(quadtree, this, minPoint.X + r * childWidth, minPoint.Y + t * childHeight, childWidth, childHeight, depth - 1); // recalculate depth later } } }
public void Insert(T objct, object bounding) { UpdateNodeHeight(objct, Boundings.BoundingToBox(bounding)); objct_to_boundings[objct] = bounding; #if DEBUGQT CheckInsertedObject(objct, this, null); #endif }
void InitLeafBounding() { var v = Boundings.BoundingToBox(objects[0].Second); Vector3 min = v.Minimum; Vector3 max = v.Maximum; for (int i = 1; i < objects.Count; i++) { v = Boundings.BoundingToBox(objects[i].Second); min = Math.Min(min, v.Minimum); max = Math.Max(max, v.Maximum); } bounding = new BoundingBox(min, max); }
private void InitFromInsert(object bounding) { var bb = Boundings.BoundingToBox(bounding); Vector2 diff = Common.Math.ToVector2(bb.Maximum - bb.Minimum); float of = 0.00001f; // slight offset so the inserted object actually ends up inside the cell float cellSize = System.Math.Max(FindOrigoCoveringCellSize(diff, nodeSize), nodeSize); Vector2 farPoint = new Vector2(bb.Minimum.X + bb.Maximum.X < 0 ? bb.Minimum.X - of : bb.Maximum.X + of, bb.Minimum.Y + bb.Maximum.Y < 0 ? bb.Minimum.Y - of : bb.Maximum.Y + of); float origoCellSize = System.Math.Max(FindOrigoCoveringCellSize(farPoint, cellSize), cellSize); int depth = System.Math.Max(0, (int)System.Math.Log(origoCellSize / nodeSize, 2f)); root = new Node( this, null, farPoint.X < 0 ? farPoint.X : farPoint.X - origoCellSize, farPoint.Y < 0 ? farPoint.Y : farPoint.Y - origoCellSize, origoCellSize, origoCellSize, depth); }
private void UpdateHeightBounding(T removedObject) { bool wasMinObject = removedObject.Equals(minObject); bool wasMaxObject = removedObject.Equals(maxObject); if (wasMinObject || wasMaxObject) { if (wasMinObject) { minObject = default(T); bounding.Minimum.Z = float.MaxValue; } if (wasMaxObject) { maxObject = default(T); bounding.Maximum.Z = float.MinValue; } foreach (var c in children) { if (c != null) { // set to childrens min/maxobject if that is what spans the box if (wasMinObject && c.bounding.Minimum.Z < bounding.Minimum.Z) { bounding.Minimum.Z = c.bounding.Minimum.Z; minObject = c.minObject; } if (wasMaxObject && c.bounding.Maximum.Z > bounding.Maximum.Z) { bounding.Maximum.Z = c.bounding.Maximum.Z; maxObject = c.maxObject; } } } foreach (var o in objct_to_boundings.Keys) { BoundingBox bb = Boundings.BoundingToBox(objct_to_boundings[o]); if (wasMinObject && bb.Minimum.Z < bounding.Minimum.Z) { bounding.Minimum.Z = bb.Minimum.Z; minObject = o; } if (wasMaxObject && bb.Maximum.Z > bounding.Maximum.Z) { bounding.Maximum.Z = bb.Maximum.Z; maxObject = o; } } #if DEBUGQT if ((minObject != null || maxObject != null) && !(minObject != null && maxObject != null)) { System.Diagnostics.Debugger.Break(); // this should not happen } #endif if (parent != null) { parent.UpdateHeightBounding(removedObject); } } }