示例#1
0
        /// <summary>
        /// Adds the leaf node to the specified subtree.
        /// </summary>
        /// <param name="node">The root of the subtree.</param>
        /// <param name="leaf">The leaf node.</param>
        private void AddLeaf(Node node, Node leaf)
        {
            Debug.Assert(!node.IsLeaf);

            if (node.IsValid)
            {
                // Choose closest node among the children.
                int selection = AabbTreeHelper.SelectClosest(leaf.Aabb, node.LeftChild.Aabb, node.RightChild.Aabb);
                if (selection == 0)
                {
                    // Insert into left subtree.
                    if (node.LeftChild.IsLeaf)
                    {
                        // Invalidate the node above the leaf node. Insert the leaf node (see below) and
                        // re-split in next collision detection query as needed.
                        InvalidateSubtree(node);
                    }
                    else
                    {
                        // Recursively add leaf node to subtree.
                        AddLeaf(node.LeftChild, leaf);
                    }
                }
                else
                {
                    // Insert into right subtree.
                    if (node.RightChild.IsLeaf)
                    {
                        // Invalidate the node above the leaf node. Insert the leaf node (see below) and
                        // re-split in next collision detection query as needed.
                        InvalidateSubtree(node);
                    }
                    else
                    {
                        // Recursively add leaf node to subtree.
                        AddLeaf(node.RightChild, leaf);
                    }
                }
            }

            if (!node.IsValid)
            {
                // All nodes are stored locally.
                node.Leaves.Add(leaf);
            }

            RecomputeAabb(node);
        }
        /// <summary>
        /// Adds a leaf node to the given tree.
        /// </summary>
        /// <param name="root">The root of the tree (or subtree).</param>
        /// <param name="leaf">The leaf node to be added.</param>
        private void AddLeaf(Node root, Node leaf)
        {
            if (_root == null)
            {
                // Insert leaf as new root.
                _root = leaf;
            }
            else
            {
                // Search for leaf node that is closest to 'leaf'. This node that will become the new
                // sibling of 'leaf'.
                Node sibling = root;
                while (!sibling.IsLeaf)
                {
                    int selection = AabbTreeHelper.SelectClosest(leaf.Aabb, sibling.LeftChild.Aabb, sibling.RightChild.Aabb);
                    sibling = (selection == 0) ? sibling.LeftChild : sibling.RightChild;
                }

                // Add a new node as the parent of (sibling, leaf).
                Node parent = sibling.Parent;
                Node node   = Nodes.Obtain();
                node.Aabb       = Aabb.Merge(sibling.Aabb, leaf.Aabb);
                node.Parent     = parent;
                node.LeftChild  = sibling;
                node.RightChild = leaf;
                sibling.Parent  = node;
                leaf.Parent     = node;

                if (parent == null)
                {
                    // node is the new root.
                    _root = node;
                }
                else
                {
                    // node is an internal node.
                    if (parent.LeftChild == sibling)
                    {
                        parent.LeftChild = node;
                    }
                    else
                    {
                        parent.RightChild = node;
                    }

                    // Update AABBs of ancestor.
                    do
                    {
                        if (!parent.Aabb.Contains(node.Aabb))
                        {
                            parent.Aabb = Aabb.Merge(parent.LeftChild.Aabb, parent.RightChild.Aabb);
                        }
                        else
                        {
                            break;
                        }

                        node   = parent;
                        parent = parent.Parent;
                    } while (parent != null);
                }
            }
        }