started on the BVH build
[cyberay] / src / bvh.c
1 #include <stdlib.h>
2 #include <float.h>
3 #include "bvh.h"
4
5 int build_bvh_sah(struct bvhnode *tree)
6 {
7         int i, j;
8         float sarea;
9
10         if(tree->num_faces < 5 || tree->left || tree->right) return 0;
11
12         dx = tree->aabb.vmax.x - tree->aabb.vmin.x;
13         dy = tree->aabb.vmax.y - tree->aabb.vmin.y;
14         dz = tree->aabb.vmax.z - tree->aabb.vmin.z;
15
16         if((sarea = surf_area(dx, dy, dz)) <= 0.0f) return 0;
17
18         tree->axis = dx > dy ? (dx > dz ? dx : dz) : (dy > dz ? dy : dz);
19
20         /* TODO */
21 }
22
23 void free_bvh_tree(struct bvhnode *tree)
24 {
25         free(tree->faces);
26         free_bvh_tree(tree->left);
27         free_bvh_tree(tree->right);
28         free(tree);
29 }
30
31 int ray_bvhnode(cgm_ray *ray, struct bvhnode *bn, float tmax, struct rayhit *hit)
32 {
33         int i, res = 0;
34         struct rayhit hit0;
35
36         if(!ray_aabox_any(ray, &bn->aabb, tmax)) {
37                 return 0;
38         }
39
40         if(!hit) {
41                 for(i=0; i<bn->num_faces; i++) {
42                         if(ray_triangle(ray, bn->faces + i, tmax, 0)) {
43                                 return 1;
44                         }
45                 }
46                 return 0;
47         }
48
49         hit0.t = FLT_MAX;
50         for(i=0; i<bn->num_faces; i++) {
51                 if(ray_triangle(ray, bn->faces + i, tmax, hit) && hit->t < hit0.t) {
52                         hit0 = *hit;
53                         res = 1;
54                 }
55         }
56         *hit = hit0;
57         return res;
58 }