コード例 #1
0
 /// <summary>
 /// Creates the root node of the tree.
 /// </summary>
 private void CreateRootNode()
 {
     // Create the root node with some sensible default values. It doesn't really matter what
     // initial size the root node has. It will grow as needed when new nodes are added to the
     // tree.
     _rootNode = new SphereTreeNode <T>(Vector3.zero, 10.0f, this);
     _rootNode.SetFlag(SphereTreeNodeFlags.Root | SphereTreeNodeFlags.SuperSphere);
 }
コード例 #2
0
        /// <summary>
        /// Adds a terminal node to the tree.
        /// </summary>
        /// <remarks>
        /// The function does not integrate the node inside the sphere hierarchy. It
        /// will only add it to the integration pending queue. The actual integration
        /// process will be performed inside 'PerformPendingUpdates'.
        /// </remarks>
        /// <param name="sphere">
        /// The node's sphere.
        /// </param>
        /// <param name="data">
        /// The node's data.
        /// </param>
        /// <returns>
        /// The node which was added to the tree.
        /// </returns>
        public SphereTreeNode <T> AddTerminalNode(Sphere3D sphere, T data)
        {
            // Create a new node and mark it as terminal
            var newTerminalNode = new SphereTreeNode <T>(sphere, this, data);

            newTerminalNode.SetFlag(SphereTreeNodeFlags.Terminal);

            // Add the node to the integration queue
            AddNodeToIntegrationQueue(newTerminalNode);

            return(newTerminalNode);
        }
コード例 #3
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();
                }
            }
        }
コード例 #4
0
 /// <summary>
 /// Adds the specified node to the integration queue.
 /// </summary>
 private void AddNodeToIntegrationQueue(SphereTreeNode <T> node)
 {
     // Only terminal, non-root nodes are allowed. We also have to ensure that
     // the node hasn't already been added to the integration queue.
     if (node.IsSuperSphere || node.IsRoot || node.MustIntegrate)
     {
         return;
     }
     if (node.IsTerminal)
     {
         node.SetFlag(SphereTreeNodeFlags.MustIntegrate);
         _terminalNodesPendingIntegration.Enqueue(node);
     }
 }