| 21 | static_assert(sizeof(GPUBVH) == sizeof(Float4) * 2, "Invalid BVH structure size for GPU."); |
| 22 | |
| 23 | void MeshAccelerationStructure::BuildBVH(int32 node, BVHBuild& build) |
| 24 | { |
| 25 | auto* root = &_bvh[node]; |
| 26 | ASSERT_LOW_LAYER(root->Leaf.IsLeaf); |
| 27 | if (build.MaxLeafSize > 0 && root->Leaf.TriangleCount <= build.MaxLeafSize) |
| 28 | return; |
| 29 | if (build.MaxDepth > 0 && build.NodeDepth >= build.MaxDepth) |
| 30 | return; |
| 31 | |
| 32 | // Spawn two leaves |
| 33 | const int32 childIndex = _bvh.Count(); |
| 34 | _bvh.AddDefault(2); |
| 35 | root = &_bvh[node]; |
| 36 | auto& left = _bvh.Get()[childIndex]; |
| 37 | auto& right = _bvh.Get()[childIndex + 1]; |
| 38 | left.Leaf.IsLeaf = 1; |
| 39 | right.Leaf.IsLeaf = 1; |
| 40 | left.Leaf.MeshIndex = root->Leaf.MeshIndex; |
| 41 | right.Leaf.MeshIndex = root->Leaf.MeshIndex; |
| 42 | |
| 43 | // Mid-point splitting based on the largest axis |
| 44 | const Float3 boundsSize = root->Bounds.GetSize(); |
| 45 | int32 axisCount = 0; |
| 46 | int32 axis = 0; |
| 47 | RETRY: |
| 48 | if (axisCount == 0) |
| 49 | { |
| 50 | // Pick the highest axis |
| 51 | axis = 0; |
| 52 | if (boundsSize.Y > boundsSize.X && boundsSize.Y >= boundsSize.Z) |
| 53 | axis = 1; |
| 54 | else if (boundsSize.Z > boundsSize.X) |
| 55 | axis = 2; |
| 56 | } |
| 57 | else if (axisCount == 3) |
| 58 | { |
| 59 | // Failed to split |
| 60 | _bvh.Resize(childIndex); |
| 61 | return; |
| 62 | } |
| 63 | else |
| 64 | { |
| 65 | // Go to the next axis |
| 66 | axis = (axis + 1) % 3; |
| 67 | } |
| 68 | const float midPoint = (float)(root->Bounds.Minimum.Raw[axis] + boundsSize.Raw[axis] * 0.5f); |
| 69 | const Mesh& meshData = _meshes[root->Leaf.MeshIndex]; |
| 70 | const Float3* vb = meshData.VertexBuffer.Get<Float3>(); |
| 71 | int32 indexStart = root->Leaf.TriangleIndex * 3; |
| 72 | int32 indexEnd = indexStart + root->Leaf.TriangleCount * 3; |
| 73 | left.Leaf.TriangleCount = 0; |
| 74 | right.Leaf.TriangleCount = 0; |
| 75 | if (meshData.Use16BitIndexBuffer) |
| 76 | { |
| 77 | struct Tri |
| 78 | { |
| 79 | uint16 I0, I1, I2; |
| 80 | }; |
no test coverage detected