public DBVHNode GetRightChild(DBVHNode node) { if (node == null) return null; if (NodeExists(node.Right)) return nodes[node.Right]; return null; }
public DBVHNode GetLeftChild(DBVHNode node) { if (node == null) return null; if (NodeExists(node.Left)) return nodes[node.Left]; return null; }
/** * 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; }
/** * 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); } } }
/** * 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; }
/** * 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); }
/** * 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); } }