private void BuildSubTree(GIM_BVH_DATA_ARRAY primitive_boxes, int startIndex, int endIndex) { int curIndex = m_num_nodes; m_num_nodes++; Debug.Assert((endIndex - startIndex) > 0); if ((endIndex - startIndex) <= MAX_INDICES_PER_NODE) { //We have a leaf node int count = endIndex - startIndex; int[] indices = new int[count]; AABB bounds = new AABB(); bounds.Invalidate(); for (int i = 0; i < count; i++) { indices[i] = primitive_boxes[startIndex + i].m_data; bounds.Merge(primitive_boxes.GetRawArray()[startIndex + i].m_bound); } SetNodeBound(curIndex, ref bounds); m_node_array[curIndex].SetDataIndices(indices); return; } //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. //split axis int splitIndex = CalcSplittingAxis(primitive_boxes, startIndex, endIndex); splitIndex = SortAndCalcSplittingIndex( primitive_boxes, startIndex, endIndex, splitIndex //split axis ); //calc this node bounding box AABB node_bound = new AABB(); node_bound.Invalidate(); for (int i = startIndex; i < endIndex; i++) { node_bound.Merge(ref primitive_boxes.GetRawArray()[i].m_bound); } SetNodeBound(curIndex, ref node_bound); //build left branch BuildSubTree(primitive_boxes, startIndex, splitIndex); //build right branch BuildSubTree(primitive_boxes, splitIndex, endIndex); m_node_array.GetRawArray()[curIndex].SetEscapeIndex(m_num_nodes - curIndex); }
protected void BuildSubTree(GIM_BVH_DATA_ARRAY primitive_boxes, int startIndex, int endIndex) { int curIndex = m_num_nodes; m_num_nodes++; Debug.Assert((endIndex - startIndex) > 0); if ((endIndex - startIndex) == 1) { //We have a leaf node SetNodeBound(curIndex, ref primitive_boxes.GetRawArray()[startIndex].m_bound); m_node_array[curIndex].SetDataIndex(primitive_boxes[startIndex].m_data); #if DEBUG if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactBVH) { BulletGlobals.g_streamWriter.WriteLine("bst curIndex[{0}] dataIndex[{1}]", curIndex, primitive_boxes[startIndex].m_data); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, "bst min", primitive_boxes[startIndex].m_bound.m_min); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, "bst max", primitive_boxes[startIndex].m_bound.m_max); } #endif return; } //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. //split axis int splitIndex = CalcSplittingAxis(primitive_boxes, startIndex, endIndex); splitIndex = SortAndCalcSplittingIndex( primitive_boxes, startIndex, endIndex, splitIndex //split axis ); //calc this node bounding box AABB node_bound = new AABB(); node_bound.Invalidate(); for (int i = startIndex; i < endIndex; i++) { node_bound.Merge(ref primitive_boxes.GetRawArray()[i].m_bound); } SetNodeBound(curIndex, ref node_bound); //build left branch BuildSubTree(primitive_boxes, startIndex, splitIndex); //build right branch BuildSubTree(primitive_boxes, splitIndex, endIndex); m_node_array.GetRawArray()[curIndex].SetEscapeIndex(m_num_nodes - curIndex); #if DEBUG if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugGimpactBVH) { BulletGlobals.g_streamWriter.WriteLine("bst curIndex[{0}] escapeIndex[{1}]", curIndex, m_node_array.GetRawArray()[curIndex].GetEscapeIndex()); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, "bst node min", node_bound.m_min); MathUtil.PrintVector3(BulletGlobals.g_streamWriter, "bst node max", node_bound.m_max); } #endif }