| 695 | } |
| 696 | |
| 697 | void b2DynamicTree::RebuildBottomUp() |
| 698 | { |
| 699 | int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32)); |
| 700 | int32 count = 0; |
| 701 | |
| 702 | // Build array of leaves. Free the rest. |
| 703 | for (int32 i = 0; i < m_nodeCapacity; ++i) |
| 704 | { |
| 705 | if (m_nodes[i].height < 0) |
| 706 | { |
| 707 | // free node in pool |
| 708 | continue; |
| 709 | } |
| 710 | |
| 711 | if (m_nodes[i].IsLeaf()) |
| 712 | { |
| 713 | m_nodes[i].parent = b2_nullNode; |
| 714 | nodes[count] = i; |
| 715 | ++count; |
| 716 | } |
| 717 | else |
| 718 | { |
| 719 | FreeNode(i); |
| 720 | } |
| 721 | } |
| 722 | |
| 723 | while (count > 1) |
| 724 | { |
| 725 | float32 minCost = b2_maxFloat; |
| 726 | int32 iMin = -1, jMin = -1; |
| 727 | for (int32 i = 0; i < count; ++i) |
| 728 | { |
| 729 | b2AABB aabbi = m_nodes[nodes[i]].aabb; |
| 730 | |
| 731 | for (int32 j = i + 1; j < count; ++j) |
| 732 | { |
| 733 | b2AABB aabbj = m_nodes[nodes[j]].aabb; |
| 734 | b2AABB b; |
| 735 | b.Combine(aabbi, aabbj); |
| 736 | float32 cost = b.GetPerimeter(); |
| 737 | if (cost < minCost) |
| 738 | { |
| 739 | iMin = i; |
| 740 | jMin = j; |
| 741 | minCost = cost; |
| 742 | } |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | int32 index1 = nodes[iMin]; |
| 747 | int32 index2 = nodes[jMin]; |
| 748 | b2TreeNode* child1 = m_nodes + index1; |
| 749 | b2TreeNode* child2 = m_nodes + index2; |
| 750 | |
| 751 | int32 parentIndex = AllocateNode(); |
| 752 | b2TreeNode* parent = m_nodes + parentIndex; |
| 753 | parent->child1 = index1; |
| 754 | parent->child2 = index2; |
nothing calls this directly
no test coverage detected