4 void free_bvh_tree(struct bvhnode *tree)
6 struct bvhnode *node, *tmp;
10 free_bvh_tree(tree->left);
11 free_bvh_tree(tree->right);
15 int ray_triangle(cgm_ray *ray, struct triangle *tri, float tmax, struct rayhit *hit)
18 cgm_vec3 vdir, bc, pos;
20 if(fabs(ndotdir = cgm_vdot(&ray->dir, &tri->norm)) <= 1e-6) {
25 cgm_vsub(&vdir, &ray->origin);
27 if((t = cgm_vdot(&tri->norm, &vdir) / ndotdir) <= 1e-6 || t > tmax) {
31 cgm_raypos(&pos, ray, t);
32 cgm_bary(&bc, &tri->v[0].pos, &tri->v[1].pos, &tri->v[2].pos, &pos);
34 if(bc.x < 0.0f || bc.x > 1.0f) return 0;
35 if(bc.y < 0.0f || bc.y > 1.0f) return 0;
36 if(bc.z < 0.0f || bc.z > 1.0f) return 0;
45 hit->v.norm.x = tri->v[0].norm.x * bc.x + tri->v[1].norm.x * bc.y + tri->v[2].norm.x * bc.z;
46 hit->v.norm.y = tri->v[0].norm.y * bc.x + tri->v[1].norm.y * bc.y + tri->v[2].norm.y * bc.z;
47 hit->v.norm.z = tri->v[0].norm.z * bc.x + tri->v[1].norm.z * bc.y + tri->v[2].norm.z * bc.z;
49 hit->v.tex.x = tri->v[0].tex.x * bc.x + tri->v[1].tex.x * bc.y + tri->v[2].tex.x * bc.z;
50 hit->v.tex.y = tri->v[0].tex.y * bc.x + tri->v[1].tex.y * bc.y + tri->v[2].tex.y * bc.z;
55 #define SLABCHECK(dim) \
57 invdir = 1.0f / ray->dir.dim; \
58 t0 = (box->vmin.dim - ray->origin.dim) * invdir; \
59 t1 = (box->vmax.dim - ray->origin.dim) * invdir; \
65 tmin = t0 > tmin ? t0 : tmin; \
66 tmax = t1 < tmax ? t1 : tmax; \
67 if(tmax <= tmin) return 0; \
70 int ray_aabox_any(cgm_ray *ray, struct aabox *box, float tmax)
72 float invdir, t0, t1, tmp;
82 int ray_bvhnode(cgm_ray *ray, struct bvhnode *bn, float tmax, struct rayhit *hit)
87 if(!ray_aabox_any(ray, &bn->aabb, tmax)) {
92 for(i=0; i<bn->num_faces; i++) {
93 if(ray_triangle(ray, bn->faces + i, tmax, 0)) {
101 for(i=0; i<bn->num_faces; i++) {
102 if(ray_triangle(ray, bn->faces + i, tmax, hit) && hit->t < hit0.t) {