/// <summary> /// Builds the complete AABB tree. /// </summary> private void Build() { if (_root != null) { // Recycle old nodes. RemoveSubtree(_root, null); _root = null; _leaves.Clear(); } int numberOfItems = Count; // No items? if (numberOfItems == 0) { // Nothing to do. return; } if (numberOfItems == 1) { // AABB tree contains exactly one item. (One leaf, no internal nodes.) T item = Items.First(); _root = Nodes.Obtain(); _root.Aabb = GetAabbForItem(item); _root.Item = item; _leaves.Add(_root); } else { // Default case: Several items. (Data is stored in the leaves.) foreach (T item in Items) { Node node = Nodes.Obtain(); node.Aabb = GetAabbForItem(item); node.Item = item; _leaves.Add(node); } // (Fix for Xbox 360: Create a temporary list of leaves and pass the temporary list to the // AabbTreeBuilder. Cannot use the leaves array directly, because, the .NET CF has troubles // with arrays that are cast to IList<T>.) List <IAabbTreeNode <T> > leaves = DigitalRune.ResourcePools <IAabbTreeNode <T> > .Lists.Obtain(); for (int i = 0; i < numberOfItems; i++) { leaves.Add(_leaves[i]); } // Build tree. _root = (Node)AabbTreeBuilder.Build(leaves, () => Nodes.Obtain(), BottomUpBuildThreshold); // Recycle temporary lists. DigitalRune.ResourcePools <IAabbTreeNode <T> > .Lists.Recycle(leaves); } }
private void Build() { Debug.Assert(_items != null && _items.Count > 0, "Build should not be called for empty CompressedAabbTree."); if (GetAabbForItem == null) { throw new GeometryException("Cannot build AABB tree. The property GetAabbForItem of the spatial partition is not set."); } if (_items.Count == 1) { // AABB tree contains exactly one item. (One leaf, no internal nodes.) int item = _items[0]; // Determine AABB of spatial partition and prepare factors for quantization. Aabb aabb = GetAabbForItem(item); SetQuantizationValues(aabb); // Create node. Node node = new Node(); node.Item = _items[0]; SetAabb(ref node, _aabb); _nodes = new[] { node }; _numberOfItems = 1; } else { // Default case: Several items. (Data is stored in the leaves.) // First create a normal AabbTree<int> which is then compressed. _numberOfItems = _items.Count; List <IAabbTreeNode <int> > leaves = DigitalRune.ResourcePools <IAabbTreeNode <int> > .Lists.Obtain(); for (int i = 0; i < _numberOfItems; i++) { int item = _items[i]; Aabb aabb = GetAabbForItem(item); leaves.Add(new AabbTree <int> .Node { Aabb = aabb, Item = item }); } // Build tree. AabbTree <int> .Node root = (AabbTree <int> .Node)AabbTreeBuilder.Build(leaves, () => new AabbTree <int> .Node(), BottomUpBuildThreshold); // Set AABB of spatial partition and prepare the factors for quantization. SetQuantizationValues(root.Aabb); // Compress AABB tree. var nodes = DigitalRune.ResourcePools <Node> .Lists.Obtain(); CompressTree(nodes, root); _nodes = nodes.ToArray(); // Recycle temporary lists. DigitalRune.ResourcePools <IAabbTreeNode <int> > .Lists.Recycle(leaves); DigitalRune.ResourcePools <Node> .Lists.Recycle(nodes); } // Recycle items list, now that we have a valid tree. DigitalRune.ResourcePools <int> .Lists.Recycle(_items); _items = null; }
/// <summary> /// Builds the AABB tree. /// </summary> private void Build() { _root = null; _leaves = null; _height = -1; int numberOfItems = Count; // No items? if (numberOfItems == 0) { // Nothing to do. return; } if (numberOfItems == 1) { // AABB tree contains exactly one item. (One leaf, no internal nodes.) T item = Items.First(); _root = new Node { Aabb = GetAabbForItem(item), Item = item, }; _leaves = new[] { _root }; _height = 0; } else { // Default case: Several items. (Data is stored in the leaves.) // (Fix for Xbox 360: Create a temporary list of leaves and pass the temporary list to the // AabbTreeBuilder. Cannot use the leaves array directly, because, the .NET CF has troubles // with arrays that are cast to IList<T>.) var leaves = DigitalRune.ResourcePools <IAabbTreeNode <T> > .Lists.Obtain(); foreach (T item in Items) { Aabb aabb = GetAabbForItem(item); leaves.Add(new Node { Aabb = aabb, Item = item }); } // Build tree. _root = (Node)AabbTreeBuilder.Build(leaves, () => new Node(), BottomUpBuildThreshold); //_root = CompactNodes(_root, null); //GC.Collect(0); // Copy leaves from temporary list. _leaves = new Node[numberOfItems]; for (int i = 0; i < numberOfItems; i++) { _leaves[i] = (Node)leaves[i]; } _height = GetHeight(_root); // Recycle temporary list. DigitalRune.ResourcePools <IAabbTreeNode <T> > .Lists.Recycle(leaves); } }