Insert a leaf node in the tree. The process of inserting a new leaf node in the dynamic tree is described in the book "Introduction to Game Physics with Box2D" by Ian Parberry.
| 217 | // in the dynamic tree is described in the book "Introduction to Game Physics |
| 218 | // with Box2D" by Ian Parberry. |
| 219 | void DynamicAABBTree::insertLeafNode(int nodeID) { |
| 220 | |
| 221 | // If the tree is empty |
| 222 | if (mRootNodeID == TreeNode::NULL_TREE_NODE) { |
| 223 | mRootNodeID = nodeID; |
| 224 | mNodes[mRootNodeID].parentID = TreeNode::NULL_TREE_NODE; |
| 225 | return; |
| 226 | } |
| 227 | |
| 228 | assert(mRootNodeID != TreeNode::NULL_TREE_NODE); |
| 229 | |
| 230 | // Find the best sibling node for the new node |
| 231 | AABB newNodeAABB = mNodes[nodeID].aabb; |
| 232 | int currentNodeID = mRootNodeID; |
| 233 | while (!mNodes[currentNodeID].isLeaf()) { |
| 234 | |
| 235 | int leftChild = mNodes[currentNodeID].children[0]; |
| 236 | int rightChild = mNodes[currentNodeID].children[1]; |
| 237 | |
| 238 | // Compute the merged AABB |
| 239 | decimal volumeAABB = mNodes[currentNodeID].aabb.getVolume(); |
| 240 | AABB mergedAABBs; |
| 241 | mergedAABBs.mergeTwoAABBs(mNodes[currentNodeID].aabb, newNodeAABB); |
| 242 | decimal mergedVolume = mergedAABBs.getVolume(); |
| 243 | |
| 244 | // Compute the cost of making the current node the sibbling of the new node |
| 245 | decimal costS = decimal(2.0) * mergedVolume; |
| 246 | |
| 247 | // Compute the minimum cost of pushing the new node further down the tree (inheritance cost) |
| 248 | decimal costI = decimal(2.0) * (mergedVolume - volumeAABB); |
| 249 | |
| 250 | // Compute the cost of descending into the left child |
| 251 | decimal costLeft; |
| 252 | AABB currentAndLeftAABB; |
| 253 | currentAndLeftAABB.mergeTwoAABBs(newNodeAABB, mNodes[leftChild].aabb); |
| 254 | if (mNodes[leftChild].isLeaf()) { // If the left child is a leaf |
| 255 | costLeft = currentAndLeftAABB.getVolume() + costI; |
| 256 | } |
| 257 | else { |
| 258 | decimal leftChildVolume = mNodes[leftChild].aabb.getVolume(); |
| 259 | costLeft = costI + currentAndLeftAABB.getVolume() - leftChildVolume; |
| 260 | } |
| 261 | |
| 262 | // Compute the cost of descending into the right child |
| 263 | decimal costRight; |
| 264 | AABB currentAndRightAABB; |
| 265 | currentAndRightAABB.mergeTwoAABBs(newNodeAABB, mNodes[rightChild].aabb); |
| 266 | if (mNodes[rightChild].isLeaf()) { // If the right child is a leaf |
| 267 | costRight = currentAndRightAABB.getVolume() + costI; |
| 268 | } |
| 269 | else { |
| 270 | decimal rightChildVolume = mNodes[rightChild].aabb.getVolume(); |
| 271 | costRight = costI + currentAndRightAABB.getVolume() - rightChildVolume; |
| 272 | } |
| 273 | |
| 274 | // If the cost of making the current node a sibbling of the new node is smaller than |
| 275 | // the cost of going down into the left or right child |
| 276 | if (costS < costLeft && costS < costRight) break; |
nothing calls this directly
no test coverage detected