/// <summary>
        /// Builds the AABB tree.
        /// </summary>
        private void Build()
        {
            if (_root != null)
            {
                // Recycle old nodes.
                RecycleNodes(_root);

                _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(item, _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(item, 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();

                foreach (var leaf in _leaves.Values)
                {
                    leaves.Add(leaf);
                }

                // Build tree.
                _root = (Node)AabbTreeBuilder.Build(leaves, () => Nodes.Obtain(), BottomUpBuildThreshold);

                // Recycle temporary lists.
                DigitalRune.ResourcePools <IAabbTreeNode <T> > .Lists.Recycle(leaves);
            }
        }
Exemplo n.º 2
0
        /// <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);
            }
        }
        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;
        }