5 #define SPLIT_BUCKETS 8
7 int build_bvh_sah(struct bvhnode *tree)
10 float sp, sp0, spgap, area, ext[3];
11 float spcost[SPLIT_BUCKETS];
12 int part[SPLIT_BUCKETS];
13 struct triangle **tribuf, **src;
15 if(tree->num_faces < 16 || tree->left || tree->right) return 0;
17 ext[0] = tree->aabb.vmax.x - tree->aabb.vmin.x;
18 ext[1] = tree->aabb.vmax.y - tree->aabb.vmin.y;
19 ext[2] = tree->aabb.vmax.z - tree->aabb.vmin.z;
21 if((area = surf_area(ext[0], ext[1], ext[2])) <= 0.0f) return 0;
23 tree->axis = ext[0] > ext[1] ? (ext[0] > ext[2] ? 0 : 2) : (ext[1] > ext[2] ? 1 : 2);
25 spgap = ext[tree->axis] / SPLIT_BUCKETS;
26 sp0 = cgm_velem(&tree->aabb.vmin, tree->axis) + spgap / 2.0f;
28 /* allocate N arrays worth of triangle pointers, one for each bucket */
29 if(!(tribuf = malloc(tree->num_faces * SPLIT_BUCKETS * sizeof *tribuf))) {
30 fprintf(stderr, "failed to allocate buffer for BVH construction\n");
34 for(i=0; i<SPLIT_BUCKETS; i++) {
36 spcost[i] = eval_cost(tree, area, sp, tribuf + i * tree->num_faces, part + i);
40 for(i=1; i<SPLIT_BUCKETS; i++) {
41 if(spcost[i] < spcost[best]) {
46 /* found the best split, allocate child nodes, split the original array and copy
47 * the pointers from tribuf to each part
49 if(!(tree->left = calloc(1, sizeof *tree->left)) || !(tree->right = calloc(1, sizeof *tree->right))) {
50 fprintf(stderr, "failed to allocate tree nodes during BVH construction\n");
56 memcpy(tree->faces, tribuf + best * tree->num_faces, tree->num_faces * sizeof *tribuf);
58 tree->left->faces = tree->faces;
59 tree->left->num_faces = part[best];
60 tree->right->faces = tree->faces + part[best];
61 tree->right->num_faces = tree->faces - tree->left->faces;
63 /* TODO: calc aabox for each child node */
67 static float eval_cost(struct bvhnode *node, float area, float sp, struct triangle **tribuf, int *part)
72 struct triangle **pleft, **pright;
76 pright = tribuf + node->num_faces - 1;
78 for(i=0; i<node->num_faces; i++) {
80 if(cgm_velem(tri->v, node->axis) < sp) {
89 *part = pleft - tribuf;
93 void free_bvh_tree(struct bvhnode *tree)
98 /* only nodes with max_faces != 0 have ownership of the faces array. all
99 * the rest of the nodes only have pointers in the same array belonging
100 * to an ancestor node
104 free_bvh_tree(tree->left);
105 free_bvh_tree(tree->right);
109 int ray_bvhnode(cgm_ray *ray, struct bvhnode *bn, float tmax, struct rayhit *hit)
114 if(!ray_aabox_any(ray, &bn->aabb, tmax)) {
119 for(i=0; i<bn->num_faces; i++) {
120 if(ray_triangle(ray, bn->faces[i], tmax, 0)) {
128 for(i=0; i<bn->num_faces; i++) {
129 if(ray_triangle(ray, bn->faces[i], tmax, hit) && hit->t < hit0.t) {