/// <summary> /// Generates the hierarchy. http://devblogs.nvidia.com/parallelforall/wp-content/uploads/sites/3/2012/11/karras2012hpg_paper.pdf /// </summary> /// <param name="boxes">The boxes.</param> void BVH::generateHierarchyFullParallel(std::vector<AABBox>& boxes) { ProgressBar progressBar; #if !_DEBUG #pragma omp parallel for schedule(dynamic,1) #endif for (int i = 0; i < (boxes.size() - 1); i++) { //first, find the range this node corresponds to //d == -1 means range ends at i, d == +1 means range starts at i int d = sign(commonPrefix(boxes, i, i + 1) - commonPrefix(boxes, i, i - 1)); //find a maximum and minimum value for the range this node covers. Must be a power of two for easy binary searching int min = commonPrefix(boxes, i, i - d); int max = 128; while (commonPrefix(boxes, i, i + (max * d)) > min) { max *= 4; } //use binary serach to find the farthest common prefis that is greater than min int l = 0; for (int t = max >> 1; t >= 1; t = t >> 1) { if (commonPrefix(boxes, i, i + (l + t) * d) > min) { //serach to the right of this value l += t; } } //end of range int j = i + l * d; int first = i; if (d < 0) { first = j; j = i; } // Determine where to split the range. int split = findSplit(boxes, first, j); Node* rightChild; if (split == first) { rightChild = &m_leafNodes[split]; } else { rightChild = &m_branchNodes[split]; } Node* leftChild; if (split + 1 == j) { leftChild = &m_leafNodes[split + 1]; } else { leftChild = &m_branchNodes[split + 1]; } // m_branchNodes[i].m = max; // m_branchNodes[i].re = first; // m_branchNodes[i].rs = j; // m_branchNodes[i].s = split; m_branchNodes[i].rightChild = rightChild; m_branchNodes[i].leftChild = leftChild; // leftChild->parent = &m_branchNodes[i]; // rightChild->parent = &m_branchNodes[i]; #pragma omp critical { progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100)); } } progressBar.end(); }
void BVH::generateHierarchyStackLinear(std::vector<AABBox>& boxes) { std::stack<constructData *> dataStack; dataStack.push(new constructData(&m_branchNodes[0], 0, static_cast<int>(boxes.size() - 1))); // constructData *dataStackArray = new constructData[1024]; // dataStackArray[0] = constructData(&m_branchNodes[0], 0, static_cast<int>(boxes.size() - 1)); // uint32_t stackSize = 1; int i = 0; ProgressBar progressBar; do { constructData* data = dataStack.top(); dataStack.pop(); // --stackSize; // constructData data = dataStackArray[stackSize]; // Determine where to split the range. int split = findSplit(boxes, data->first, data->last); Node* rightChild; if (split == data->first) { rightChild = &m_leafNodes[split]; } else { rightChild = &m_branchNodes[split]; //push next node dataStack.push(new constructData(rightChild, data->first, split)); // dataStackArray[stackSize] = constructData(rightChild, data.first, split); // ++stackSize; } Node* leftChild; if (split + 1 == data->last) { leftChild = &m_leafNodes[split + 1]; } else { leftChild = &m_branchNodes[split + 1]; //push next node dataStack.push(new constructData(leftChild, split + 1, data->last)); // dataStackArray[stackSize] = constructData(leftChild, split + 1, data.last); // ++stackSize; } // m_branchNodes[i].m = max; // data.node->re = data.last; // data.node->rs = data.first; // data.node->s = split; data->node->rightChild = rightChild; data->node->leftChild = leftChild; // leftChild->parent = data.node; // rightChild->parent = data.node; delete data; i++; progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100)); } while (!dataStack.empty()); progressBar.end(); }