void BVH4BuilderFast::recurseSAH(BuildRecord& current, Allocator& nodeAlloc, Allocator& leafAlloc, const size_t mode, const size_t threadID, const size_t numThreads) { __aligned(64) BuildRecord children[BVH4::N]; /* create leaf node */ if (current.depth >= BVH4::maxBuildDepth || current.isLeaf()) { assert(mode != BUILD_TOP_LEVEL); createLeaf(current,nodeAlloc,leafAlloc,threadID,numThreads); return; } /* fill all 4 children by always splitting the one with the largest surface area */ unsigned int numChildren = 1; children[0] = current; do { /* find best child with largest bounding box area */ int bestChild = -1; float bestArea = neg_inf; for (unsigned int i=0; i<numChildren; i++) { /* ignore leaves as they cannot get split */ if (children[i].isLeaf()) continue; /* remember child with largest area */ if (children[i].sceneArea() > bestArea) { bestArea = children[i].sceneArea(); bestChild = i; } } if (bestChild == -1) break; /*! split best child into left and right child */ __aligned(64) BuildRecord left, right; if (!split(children[bestChild],left,right,mode,threadID,numThreads)) continue; /* add new children left and right */ left.depth = right.depth = current.depth+1; children[bestChild] = children[numChildren-1]; children[numChildren-1] = left; children[numChildren+0] = right; numChildren++; } while (numChildren < BVH4::N); /* create leaf node if no split is possible */ if (numChildren == 1) { assert(mode != BUILD_TOP_LEVEL); createLeaf(current,nodeAlloc,leafAlloc,threadID,numThreads); return; } /* allocate node */ Node* node = (Node*) nodeAlloc.malloc(sizeof(Node)); node->clear(); *(NodeRef*)current.parentNode = bvh->encodeNode(node); /* recurse into each child */ for (unsigned int i=0; i<numChildren; i++) { node->set(i,children[i].bounds.geometry); children[i].parentNode = (size_t)&node->child(i); children[i].depth = current.depth+1; recurse(children[i],nodeAlloc,leafAlloc,mode,threadID,numThreads); } }