private AabbTreeNode <T> RebuildNode(List <AabbTreeNode <T> > leaves, AabbTreeNode <T> parent) { int expectedChildren = maxChildren - 1; if (leaves.Count <= expectedChildren) { var n = new AabbTreeNode <T> { children = leaves, depth = MaxDepth(leaves) + 1, parent = parent, }; foreach (var leaf in leaves) { leaf.parent = n; } return(n); } var unionrect = AaRects.MergeAll(leaves.Select(l => l.bounds)); if (unionrect.GetSize().x > unionrect.GetSize().y) { leaves.Sort(OrderNodeByX); } else { leaves.Sort(OrderNodeByY); } var result = new AabbTreeNode <T> { children = new List <AabbTreeNode <T> >(), parent = parent, }; for (int i = 0; i < expectedChildren; i++) { var i0 = i * leaves.Count / expectedChildren; var i1 = (i + 1) * leaves.Count / expectedChildren; result.children.Add(RebuildNode(leaves.GetRange(i0, i1 - i0), result)); } ShallowUpdateNode(result, true); return(result); }
private void ShallowUpdateNode(AabbTreeNode <T> node, bool recalculateBounds) { if (node.leaf) { return; } var maxnode = GetMaxDepthChild(node); if (node == null) { throw new InvalidOperationException(); } if (maxnode == null) { throw new InvalidOperationException(); } node.depth = maxnode.depth + 1; if (recalculateBounds) { node.bounds = AaRects.MergeAll(node.children.Select(c => c.bounds)); } }