private BIHNode createNode(int l, int r, BoundingBox nodeBbox, int depth) {
if ((r - l) < maxTrisPerNode || depth > MAX_TREE_DEPTH) {
return new BIHNode(l, r);
}
BoundingBox currentBox = createBox(l, r);
Vector3f exteriorExt = nodeBbox.getExtent(null);
Vector3f interiorExt = currentBox.getExtent(null);
exteriorExt.subtractLocal(interiorExt);
int axis = 0;
if (exteriorExt.x > exteriorExt.y) {
if (exteriorExt.x > exteriorExt.z) {
axis = 0;
} else {
axis = 2;
}
} else {
if (exteriorExt.y > exteriorExt.z) {
axis = 1;
} else {
axis = 2;
}
}
if (exteriorExt.equals(Vector3f.ZERO)) {
axis = 0;
}
// Arrays.sort(tris, l, r, comparators[axis]);
float split = currentBox.getCenter().get(axis);
int pivot = sortTriangles(l, r, split, axis);
if (pivot == l || pivot == r) {
pivot = (r + l) / 2;
}
//If one of the partitions is empty, continue with recursion: same level but different bbox
if (pivot < l) {
//Only right
BoundingBox rbbox = new BoundingBox(currentBox);
setMinMax(rbbox, true, axis, split);
return createNode(l, r, rbbox, depth + 1);
} else if (pivot > r) {
//Only left
BoundingBox lbbox = new BoundingBox(currentBox);
setMinMax(lbbox, false, axis, split);
return createNode(l, r, lbbox, depth + 1);
} else {
//Build the node
BIHNode node = new BIHNode(axis);
//Left child
BoundingBox lbbox = new BoundingBox(currentBox);
setMinMax(lbbox, false, axis, split);
//The left node right border is the plane most right
node.setLeftPlane(getMinMax(createBox(l, max(l, pivot - 1)), false, axis));
node.setLeftChild(createNode(l, max(l, pivot - 1), lbbox, depth + 1)); //Recursive call
//Right Child
BoundingBox rbbox = new BoundingBox(currentBox);
setMinMax(rbbox, true, axis, split);
//The right node left border is the plane most left
node.setRightPlane(getMinMax(createBox(pivot, r), true, axis));
node.setRightChild(createNode(pivot, r, rbbox, depth + 1)); //Recursive call