()
| 756 | } |
| 757 | |
| 758 | func (tree *B2DynamicTree) RebuildBottomUp() { |
| 759 | //int* nodes = (int*)b2Alloc(m_nodeCount * sizeof(int)); |
| 760 | nodes := make([]int, tree.M_nodeCount) |
| 761 | count := 0 |
| 762 | |
| 763 | // Build array of leaves. Free the rest. |
| 764 | for i := 0; i < tree.M_nodeCapacity; i++ { |
| 765 | if tree.M_nodes[i].Height < 0 { |
| 766 | // free node in pool |
| 767 | continue |
| 768 | } |
| 769 | |
| 770 | if tree.M_nodes[i].IsLeaf() { |
| 771 | tree.M_nodes[i].Parent = B2_nullNode |
| 772 | nodes[count] = i |
| 773 | count++ |
| 774 | } else { |
| 775 | tree.FreeNode(i) |
| 776 | } |
| 777 | } |
| 778 | |
| 779 | for count > 1 { |
| 780 | minCost := B2_maxFloat |
| 781 | iMin := -1 |
| 782 | jMin := -1 |
| 783 | |
| 784 | for i := 0; i < count; i++ { |
| 785 | aabbi := tree.M_nodes[nodes[i]].Aabb |
| 786 | |
| 787 | for j := i + 1; j < count; j++ { |
| 788 | aabbj := tree.M_nodes[nodes[j]].Aabb |
| 789 | b := NewB2AABB() |
| 790 | b.CombineTwoInPlace(aabbi, aabbj) |
| 791 | cost := b.GetPerimeter() |
| 792 | if cost < minCost { |
| 793 | iMin = i |
| 794 | jMin = j |
| 795 | minCost = cost |
| 796 | } |
| 797 | } |
| 798 | } |
| 799 | |
| 800 | index1 := nodes[iMin] |
| 801 | index2 := nodes[jMin] |
| 802 | child1 := &tree.M_nodes[index1] |
| 803 | child2 := &tree.M_nodes[index2] |
| 804 | |
| 805 | parentIndex := tree.AllocateNode() |
| 806 | parent := &tree.M_nodes[parentIndex] |
| 807 | parent.Child1 = index1 |
| 808 | parent.Child2 = index2 |
| 809 | parent.Height = 1 + MaxInt(child1.Height, child2.Height) |
| 810 | parent.Aabb.CombineTwoInPlace(child1.Aabb, child2.Aabb) |
| 811 | parent.Parent = B2_nullNode |
| 812 | |
| 813 | child1.Parent = parentIndex |
| 814 | child2.Parent = parentIndex |
| 815 |
nothing calls this directly
no test coverage detected