Пример #1
0
 public DBVHNode GetRightChild(DBVHNode node)
 {
     if (node == null) return null;
     if (NodeExists(node.Right))
     return nodes[node.Right];
     return null;
 }
Пример #2
0
 public DBVHNode GetLeftChild(DBVHNode node)
 {
     if (node == null) return null;
     if (NodeExists(node.Left))
     return nodes[node.Left];
     return null;
 }
Пример #3
0
        /**
         * Inserts a new GameObject into the DBVH. The node bounds are supposed to be up to date.
         */
        public bool Insert(ObiActor actor)
        {
            // If no gameobject at all, we can't insert it.
            if (actor == null) return false;

            // Create a new node.
            DBVHNode node = new DBVHNode(actor);
            node.UpdateBounds(nodes);

            // If there are no nodes in the tree, this is the root.
            if (nodes.Count == 0){
            node.Index = 0;
            nodes.Add(node);
            }else{
            InsertNode(node,nodes[0]);
            }

            return true;
        }
Пример #4
0
        /**
         * Transplants a whole subtree to a new index, and updates all indices down the subtree.
         */
        private void TransplantTree(DBVHNode node, int index)
        {
            if (node != null) {

            Queue<DBVHNode> fromQueue = new Queue<DBVHNode>();
            fromQueue.Enqueue(node);
            Queue<int> toQueue = new Queue<int>();
            toQueue.Enqueue(index);
            DBVHNode fromNode;
            int toNode;

            while (fromQueue.Count > 0) {

                fromNode = fromQueue.Dequeue();
                toNode = toQueue.Dequeue();

                // enqueue left and right nodes:
                if (NodeExists(fromNode.Left)){
                    fromQueue.Enqueue(nodes[fromNode.Left]);
                    toQueue.Enqueue(2*toNode+1);
                }
                if (NodeExists(fromNode.Right)){
                    fromQueue.Enqueue(nodes[fromNode.Right]);
                    toQueue.Enqueue(2*toNode+2);
                }

                // move the from node to the "to" index.
                nodes[fromNode.Index] = null;
                PutNode(fromNode,toNode);

            }

            }
        }
Пример #5
0
 /**
  * Places a node at a certain index in the tree. If the destination index is not null,
  * the node there gets overwritten.
  */
 private void PutNode(DBVHNode node, int index)
 {
     while (nodes.Count <= index)
     nodes.Add(null);
     node.Index = index;
     nodes[index] = node;
 }
Пример #6
0
        /**
         * Reursively inserts a node into the tree, starting at the provided parent node.
         */
        private void InsertNode(DBVHNode node, DBVHNode parent)
        {
            if (parent.content != null){ //parent is a leaf.

            // create a new parent for both the old leaf and the new leaf.
            DBVHNode branch = new DBVHNode();

            // our branch node is the new parent.
            PutNode(branch,parent.Index);
            PutNode(parent,branch.Left);
            PutNode(node,branch.Right);

            parent = branch;

            }else{ // parent is a branch node, go down the child that will suffer less volume increase.

            Bounds bL = nodes[parent.Left].bounds;
            Bounds bR = nodes[parent.Right].bounds;

            bL.Encapsulate(node.bounds);
            bR.Encapsulate(node.bounds);

            float volumeDiffL =	bL.Volume() - nodes[parent.Left].bounds.Volume();
            float volumeDiffR = bR.Volume() - nodes[parent.Right].bounds.Volume();

            if (volumeDiffL < volumeDiffR)
                InsertNode(node,nodes[parent.Left]);
            else
                InsertNode(node,nodes[parent.Right]);

            }

            // Update parent bounds on our way up the recursion stack.
            parent.UpdateBounds(nodes);
        }
Пример #7
0
 /**
  * Returns a list of nodes in the tree that need to be updated.
  */
 private void GetInvalidNodes(DBVHNode node, ref List<DBVHNode> invalidNodes)
 {
     if (node.content != null) //leaf
     {
     // check if fat node bounds still contain the actor bounds or not.
     if (!node.bounds.Contains(node.content.bounds.max) ||
         !node.bounds.Contains(node.content.bounds.min))
         invalidNodes.Add(node);
     }
     else
     {
     if (NodeExists(node.Left))
     GetInvalidNodes(nodes[node.Left], ref invalidNodes);
     if (NodeExists(node.Right))
     GetInvalidNodes(nodes[node.Right], ref invalidNodes);
     }
 }