void Split(StaticBinaryTreePartition parent, ushort index) { ushort left = parent.GetNewNodeIndex(this.firstChild); ushort right = parent.GetNewNodeIndex(parent.GetNewChildArrayBaseIndex()); parent.allNodes[index].left = left; parent.allNodes[index].right = right; //parent.allNodes may be reallocated in GetNewNodeIndex... this = parent.allNodes[index]; parent.ReAddChildren(this.firstChild); }
//add an item to this node public void Add(IDraw item, float[] itemMin, float[] itemMax, int axis, StaticBinaryTreePartition parent, ushort thisIndex) { if (this.min == 0 && this.max == 0) { this.min = itemMin[axis]; this.max = itemMax[axis]; } else { this.min = Math.Min(itemMin[axis], this.min); this.max = Math.Max(itemMax[axis], this.max); } if (left == 0) { if (childCount != ChildCount) { parent.allChildren[(((uint)firstChild) << ChildCountShift) + childCount] = item; childCount++; return; } Split(parent, thisIndex); } float itemCentre = itemMin[axis] + itemMax[axis]; float nodeSplit = this.min + this.max; ushort goToNode = itemCentre > nodeSplit ? left : right; //if itemCentre and nodeSplit are equal, then itemCentre > nodeSplit is always false, which //will mean goToNode == right, so the item will always be added to the right... //so... If there are more than 'ChildCount' items in the same place, then this can //cause a stack overflow, because right will keep expanding. //the solution isn't fast.. but is should keep things ballanced. if (itemCentre == nodeSplit) { //go to the node with fewer children goToNode = parent.allNodes[left].CountChildren(parent.allNodes) > parent.allNodes[right].CountChildren(parent.allNodes) ? right : left; } parent.allNodes[goToNode].Add(item, itemMin, itemMax, axis == 2 ? 0 : axis + 1, parent, goToNode); }