コード例 #1
0
        /// <summary>
        /// This is a recursive method which is responsible for integration the specified
        /// node inside the tree.
        /// </summary>
        private void IntegrateTerminalNodeRecurse(SphereTreeNode <T> nodeToIntegrate, SphereTreeNode <T> parentNode)
        {
            // If this node still has room for children, we will add the integration node here. This 'if' statement
            // will also handle the special case in which only the root node currently exists inside the tree.
            if (parentNode.NumberOfChildren < _numberOfChildNodesPerNode)
            {
                // Add the node as a child of the parent node and ensure that the root node encapsulates it
                parentNode.AddChild(nodeToIntegrate);
                //parentNode.EncapsulateChildNode(nodeToIntegrate);
                parentNode.RecomputeCenterAndRadius();
            }
            else
            {
                // If there is no more room, we will proceed by choosing one of the parent's children which
                // is closest to the node that we want to integrate. We choose the closest node because when
                // the node will be added as a child of it, we want the parent to grow as little as possible.
                List <SphereTreeNode <T> > children     = parentNode.Children;
                SphereTreeNode <T>         closestChild = FindClosestNode(children, nodeToIntegrate);
                if (closestChild == null)
                {
                    return;
                }

                // If the closest child is not a terminal node, recurse.
                if (!closestChild.IsTerminal)
                {
                    IntegrateTerminalNodeRecurse(nodeToIntegrate, closestChild);
                }
                else
                {
                    SphereTreeNode <T> newParentNode = new SphereTreeNode <T>(closestChild.Sphere, this, default(T));
                    newParentNode.SetFlag(SphereTreeNodeFlags.SuperSphere);

                    // Replace 'closestChild' with the new parent node and add both 'closestChild' and 'nodeToIntegrate' as children of it
                    parentNode.RemoveChild(closestChild);
                    parentNode.AddChild(newParentNode);
                    newParentNode.AddChild(nodeToIntegrate);
                    newParentNode.AddChild(closestChild);

                    // Encapsulate the children inside the new node
                    //newParentNode.EncapsulateChildNode(closestChild);
                    //newParentNode.EncapsulateChildNode(nodeToIntegrate);

                    // Ensure that the new node is fully contained inside the parent node
                    //parentNode.EncapsulateChildNode(newParentNode);

                    newParentNode.RecomputeCenterAndRadius();
                    parentNode.RecomputeCenterAndRadius();
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// The client code must call this function during each frame update in order
        /// to ensure that any pending node updates are performed.
        /// </summary>
        public void PerformPendingUpdates()
        {
            // First, ensure that all nodes are recomputed accordingly
            while (_nodesPendingRecomputation.Count != 0)
            {
                SphereTreeNode <T> node = _nodesPendingRecomputation.Dequeue();

                // Note: If the node has any children left, we will recompute its volume. Otherwise,
                //       we will remove the node from the tree.
                if (node.HasChildren)
                {
                    node.RecomputeCenterAndRadius();
                }
                else
                {
                    RemoveNode(node);
                }
            }

            // At this point, all super sphere nodes have had their volume updated accordingly.
            // In the next step, we will integrate any necessary terminal nodes.
            while (_terminalNodesPendingIntegration.Count != 0)
            {
                SphereTreeNode <T> node = _terminalNodesPendingIntegration.Dequeue();
                IntegrateTerminalNode(node);
            }
        }