started on the BVH build
[cyberay] / src / bvh.c
diff --git a/src/bvh.c b/src/bvh.c
new file mode 100644 (file)
index 0000000..dced9d9
--- /dev/null
+++ b/src/bvh.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <float.h>
+#include "bvh.h"
+
+int build_bvh_sah(struct bvhnode *tree)
+{
+       int i, j;
+       float sarea;
+
+       if(tree->num_faces < 5 || tree->left || tree->right) return 0;
+
+       dx = tree->aabb.vmax.x - tree->aabb.vmin.x;
+       dy = tree->aabb.vmax.y - tree->aabb.vmin.y;
+       dz = tree->aabb.vmax.z - tree->aabb.vmin.z;
+
+       if((sarea = surf_area(dx, dy, dz)) <= 0.0f) return 0;
+
+       tree->axis = dx > dy ? (dx > dz ? dx : dz) : (dy > dz ? dy : dz);
+
+       /* TODO */
+}
+
+void free_bvh_tree(struct bvhnode *tree)
+{
+       free(tree->faces);
+       free_bvh_tree(tree->left);
+       free_bvh_tree(tree->right);
+       free(tree);
+}
+
+int ray_bvhnode(cgm_ray *ray, struct bvhnode *bn, float tmax, struct rayhit *hit)
+{
+       int i, res = 0;
+       struct rayhit hit0;
+
+       if(!ray_aabox_any(ray, &bn->aabb, tmax)) {
+               return 0;
+       }
+
+       if(!hit) {
+               for(i=0; i<bn->num_faces; i++) {
+                       if(ray_triangle(ray, bn->faces + i, tmax, 0)) {
+                               return 1;
+                       }
+               }
+               return 0;
+       }
+
+       hit0.t = FLT_MAX;
+       for(i=0; i<bn->num_faces; i++) {
+               if(ray_triangle(ray, bn->faces + i, tmax, hit) && hit->t < hit0.t) {
+                       hit0 = *hit;
+                       res = 1;
+               }
+       }
+       *hit = hit0;
+       return res;
+}