1.3.72
 
Loading...
Searching...
No Matches
BVHBuilder.h
Go to the documentation of this file.
1
16#ifndef BVH_BUILDER_H
17#define BVH_BUILDER_H
18
19#include "RayTracingTypes.h"
20#include "global.h"
21#include <vector>
22#include <cstdint>
23
24namespace helios {
25
33 struct BVHNode {
34 float aabb_min[3];
35 float aabb_max[3];
36 uint32_t left_child;
37 uint32_t right_child;
38 uint32_t prim_count;
39 uint32_t prim_type;
40 uint32_t first_prim;
41 uint32_t split_axis;
42 };
43
44 static_assert(sizeof(BVHNode) == 48, "BVHNode must be exactly 48 bytes");
45
59 struct CWBVH_Node {
60 float p[3];
61 uint32_t e_packed;
62
63 // Quantized child AABBs (48 bytes total)
64 uint8_t qmin_x[8];
65 uint8_t qmin_y[8];
66 uint8_t qmin_z[8];
67 uint8_t qmax_x[8];
68 uint8_t qmax_y[8];
69 uint8_t qmax_z[8];
70
71 // Metadata (16 bytes)
72 uint8_t imask;
73 uint8_t meta[7];
76
77 // Extended leaf data (48 bytes) - per-child primitive info
78 uint32_t child_first_prim[8];
79 uint8_t child_prim_count[8];
80 uint8_t child_prim_type[8];
81 };
82
83 static_assert(sizeof(CWBVH_Node) == 128, "CWBVH_Node must be exactly 128 bytes");
84
88 struct AABB {
89 helios::vec3 min;
90 helios::vec3 max;
91
95 void expand(const AABB &other) {
96 min.x = std::min(min.x, other.min.x);
97 min.y = std::min(min.y, other.min.y);
98 min.z = std::min(min.z, other.min.z);
99 max.x = std::max(max.x, other.max.x);
100 max.y = std::max(max.y, other.max.y);
101 max.z = std::max(max.z, other.max.z);
102 }
103
107 float surfaceArea() const {
108 helios::vec3 d = max - min;
109 return 2.0f * (d.x * d.y + d.y * d.z + d.z * d.x);
110 }
111
116 return (min + max) * 0.5f;
117 }
118 };
119
127 uint32_t prim_index;
128 uint32_t prim_type;
130 };
131
141 public:
153 std::vector<BVHNode> build(const RayTracingGeometry &geometry);
154
163 const std::vector<uint32_t> &getPrimitiveIndices() const {
164 return primitive_indices;
165 }
166
182 std::vector<CWBVH_Node> convertToCWBVH(const std::vector<BVHNode> &bvh2_nodes);
183
184 private:
188 struct BuildNode {
189 AABB bounds;
190 BuildNode *left = nullptr;
191 BuildNode *right = nullptr;
192 uint32_t first_prim_offset = 0;
193 uint32_t prim_count = 0;
194 uint32_t prim_type = 0;
195 uint32_t split_axis = 0;
196 };
197
198 // Temporary data during construction
199 std::vector<PrimitiveRef> primitive_refs;
200 std::vector<uint32_t> primitive_indices;
201 std::vector<BuildNode *> allocated_nodes;
202
203 const RayTracingGeometry *geometry = nullptr;
204 std::vector<uint32_t> type_offsets;
205
206 // BVH construction parameters
207 static constexpr uint32_t MAX_PRIMS_PER_LEAF = 4;
208 static constexpr uint32_t MAX_DEPTH = 32;
209 static constexpr uint32_t NUM_BINS = 16;
210
218 AABB computePrimitiveAABB(uint32_t prim_index, uint32_t prim_type) const;
219
223 AABB computePatchAABB(uint32_t prim_index) const;
224
228 AABB computeTriangleAABB(uint32_t prim_index) const;
229
233 AABB computeDiskAABB(uint32_t prim_index) const;
234
238 AABB computeTileAABB(uint32_t prim_index) const;
239
243 AABB computeVoxelAABB(uint32_t prim_index) const;
244
248 AABB computeBBoxAABB(uint32_t prim_index) const;
249
262 helios::vec3 transformPoint(const float *transform, const helios::vec3 &point) const;
263
273 BuildNode *recursiveBuild(std::vector<PrimitiveRef> &refs, uint32_t start, uint32_t end, uint32_t depth);
274
286 bool partitionSAH(std::vector<PrimitiveRef> &refs, uint32_t start, uint32_t end, const AABB &bounds, uint32_t &mid, uint32_t &axis);
287
291 BuildNode *createLeaf(std::vector<PrimitiveRef> &refs, uint32_t start, uint32_t end);
292
300 uint32_t flattenTree(BuildNode *node, std::vector<BVHNode> &nodes);
301
305 void cleanup();
306
307 // ========== CWBVH Conversion Methods ==========
308
314 BuildNode *reconstructTree(const std::vector<BVHNode> &bvh2_nodes, uint32_t node_idx = 0);
315
321 struct BVH8Node {
322 AABB aabb;
323 BuildNode *children[8]; // Points to BVH2 BuildNodes
324 bool is_leaf[8];
325 uint32_t first_prim[8];
326 uint32_t prim_count[8];
327 uint32_t prim_type[8];
328
329 BVH8Node() {
330 for (int i = 0; i < 8; i++) {
331 children[i] = nullptr;
332 is_leaf[i] = false;
333 first_prim[i] = 0;
334 prim_count[i] = 0;
335 prim_type[i] = 0;
336 }
337 }
338 };
339
340 BVH8Node *collapseToBVH8(BuildNode *bvh2_node, int depth = 0);
341
347 void assignChildrenToOctants(BVH8Node *node8, std::vector<BuildNode *> &children);
348
354 void compressNode(const BVH8Node *src, CWBVH_Node &dst);
355
362 uint32_t flattenBVH8(BVH8Node *root, std::vector<CWBVH_Node> &cwbvh_nodes);
363
364 // Temporary storage for CWBVH conversion
365 std::vector<BVH8Node *> allocated_bvh8_nodes;
366 };
367
368} // namespace helios
369
370#endif // BVH_BUILDER_H