| 838 | } |
| 839 | |
| 840 | std::shared_ptr<BVHBuildNode> BoundingVolumeHierarchy::recursiveBuild( |
| 841 | std::vector<BVHPrimitiveInfo>& buildData, |
| 842 | uint32_t start, |
| 843 | uint32_t end, |
| 844 | uint32_t* totalNodes, |
| 845 | std::vector<fd_t>& orderedPrims) |
| 846 | { |
| 847 | (*totalNodes)++; |
| 848 | |
| 849 | std::shared_ptr<BVHBuildNode> node = std::make_shared<BVHBuildNode>(); |
| 850 | |
| 851 | // Compute bounds of all primitives in BVH node |
| 852 | uint32_t nPrimitives = end - start; |
| 853 | MCUT_ASSERT((nPrimitives - 1) < (uint32_t)mesh->number_of_faces()); |
| 854 | |
| 855 | BBox bbox; |
| 856 | for (uint32_t i = start; i < end; ++i) { |
| 857 | MCUT_ASSERT(i < buildData.size()); |
| 858 | bbox = Union(bbox, buildData[i].bounds); |
| 859 | } |
| 860 | if (nPrimitives == 1) { |
| 861 | // Create leaf BVHBuildNode |
| 862 | uint32_t firstPrimOffset = orderedPrims.size(); |
| 863 | for (uint32_t i = start; i < end; ++i) { |
| 864 | MCUT_ASSERT(i < buildData.size()); |
| 865 | uint32_t primNum = buildData[i].primitiveNumber; |
| 866 | orderedPrims.push_back(primitives[primNum]); |
| 867 | } |
| 868 | node->InitLeaf(firstPrimOffset, nPrimitives, bbox); |
| 869 | } else { |
| 870 | // Compute bound of primitive centroids, choose split dimension dim |
| 871 | BBox centroidBounds; |
| 872 | for (uint32_t i = start; i < end; ++i) { |
| 873 | MCUT_ASSERT(i < buildData.size()); |
| 874 | centroidBounds = Union(centroidBounds, buildData[i].centroid); |
| 875 | } |
| 876 | |
| 877 | int dim = centroidBounds.MaximumExtent(); |
| 878 | MCUT_ASSERT(dim < 3); |
| 879 | |
| 880 | // |
| 881 | // Partition primitives into two sets and build children |
| 882 | // |
| 883 | uint32_t mid = (start + end) / 2; |
| 884 | switch (this->splitMethod) { |
| 885 | case SplitMethod::SPLIT_MIDDLE: { |
| 886 | // Partition primitives through node’s midpoint |
| 887 | fixed_precision_number_t pmid = (centroidBounds.minimum()[dim] + centroidBounds.maximum()[dim]) * .5; |
| 888 | #if 1 |
| 889 | MCUT_ASSERT(start < buildData.size()); |
| 890 | BVHPrimitiveInfo* midPtr = std::partition(&buildData[start], |
| 891 | &buildData[end - 1] + 1, |
| 892 | /*CompareToMid(dim, pmid)*/ |
| 893 | [dim, pmid](const BVHPrimitiveInfo& pi) { |
| 894 | return pi.centroid[dim] < pmid; |
| 895 | }); |
| 896 | mid = midPtr - &buildData[0]; |
| 897 | #else |
nothing calls this directly
no test coverage detected