unsafe void CollapseTree(int depthRemaining, TempNode *tempNodes, int tempNodeIndex, int *nodeChildren, ref int childCount, BoundingBox *nodeBounds, int *leafCounts)
        {
            var tempNode = tempNodes + tempNodeIndex;

            if (tempNode->A >= 0)
            {
                //Internal node.
                if (depthRemaining > 0)
                {
                    depthRemaining -= 1;
                    CollapseTree(depthRemaining, tempNodes, tempNode->A, nodeChildren, ref childCount, nodeBounds, leafCounts);
                    CollapseTree(depthRemaining, tempNodes, tempNode->B, nodeChildren, ref childCount, nodeBounds, leafCounts);
                }
                else
                {
                    //Reached the bottom of the recursion. Add the collected children.
                    int a = childCount++;
                    int b = childCount++;

                    nodeBounds[a] = tempNodes[tempNode->A].BoundingBox;
                    nodeBounds[b] = tempNodes[tempNode->B].BoundingBox;
                    //If the child is a leaf, collapse it. Slightly less annoying to handle it here than later.
                    //This is a byproduct of the awkward data layout for tempnodes...
                    if (tempNodes[tempNode->A].A >= 0)
                    {
                        nodeChildren[a] = tempNode->A;
                    }
                    else
                    {
                        nodeChildren[a] = tempNodes[tempNode->A].A; //It's a leaf.
                    }
                    if (tempNodes[tempNode->B].A >= 0)
                    {
                        nodeChildren[b] = tempNode->B;
                    }
                    else
                    {
                        nodeChildren[b] = tempNodes[tempNode->B].A; //It's a leaf. Leaf index is always stored in A...
                    }
                    leafCounts[a] = tempNodes[tempNode->A].LeafCount;
                    leafCounts[b] = tempNodes[tempNode->B].LeafCount;
                }
            }
            else
            {
                //Leaf node.
                var index = childCount++;
                nodeBounds[index]   = tempNode->BoundingBox;
                nodeChildren[index] = tempNode->A;
                leafCounts[index]   = tempNode->LeafCount;
            }
        }
        unsafe int BuildStagingChild(int parent, int indexInParent, TempNode *tempNodes, int tempNodeIndex, int collapseCount,
                                     Node *stagingNodes, ref int stagingNodeCount, out float treeletCost)
        {
            //Get ready to build a staging node out of this.

            var internalNodeIndex = stagingNodeCount++;
            var internalNode      = stagingNodes + internalNodeIndex;

            internalNode->Parent        = parent;
            internalNode->IndexInParent = indexInParent;
            internalNode->ChildCount    = 0;


            var internalNodeChildren = &internalNode->ChildA;
            var internalNodeBounds   = &internalNode->A;

            CollapseTree(collapseCount, tempNodes, tempNodeIndex, internalNodeChildren, ref internalNode->ChildCount, internalNodeBounds, &internalNode->LeafCountA);

            treeletCost = 0;
            //ValidateLeafNodeIndices();

            //The node now contains valid bounding boxes, but the children indices are not yet valid. They're pointing into the tempnodes.
            //Reify each one in sequence.
            for (int i = 0; i < internalNode->ChildCount; ++i)
            {
                treeletCost += ComputeBoundsMetric(ref internalNodeBounds[i]);
                //The internalNodeChildren[i] can be negative, as a result of a subtree being encountered in CollapseTree.
                //tempNodes[internalNodeChildren[i]].A is never negative for any internal node (internalNodeChildren[i] >= 0),
                //because we pre-collapsed that reference in CollapseTree for convenience.

                if (internalNodeChildren[i] >= 0)
                {
                    //It's still an internal node.
                    float childTreeletCost;
                    var   childIndex = BuildStagingChild(internalNodeIndex, i, tempNodes, internalNodeChildren[i], collapseCount, stagingNodes, ref stagingNodeCount, out childTreeletCost);
                    treeletCost += childTreeletCost;

                    internalNodeChildren[i] = childIndex;
                }
                //If it's a subtree, then we don't need to change it at all.
            }
            return(internalNodeIndex);
        }
 public static int Add(ref TempNode newNode, TempNode *tempNodes, ref int count)
 {
     tempNodes[count] = newNode;
     return(count++);
 }