4 int ray_triangle(cgm_ray *ray, struct triangle *tri, float tmax, struct rayhit *hit)
7 cgm_vec3 vdir, bc, pos;
9 if(fabs(ndotdir = cgm_vdot(&ray->dir, &tri->norm)) <= 1e-6) {
14 cgm_vsub(&vdir, &ray->origin);
16 if((t = cgm_vdot(&tri->norm, &vdir) / ndotdir) <= 1e-6 || t > tmax) {
20 cgm_raypos(&pos, ray, t);
21 cgm_bary(&bc, &tri->v[0].pos, &tri->v[1].pos, &tri->v[2].pos, &pos);
23 if(bc.x < 0.0f || bc.x > 1.0f) return 0;
24 if(bc.y < 0.0f || bc.y > 1.0f) return 0;
25 if(bc.z < 0.0f || bc.z > 1.0f) return 0;
34 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;
35 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;
36 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;
38 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;
39 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;
44 #define SLABCHECK(dim) \
46 invdir = 1.0f / ray->dir.dim; \
47 t0 = (box->vmin.dim - ray->origin.dim) * invdir; \
48 t1 = (box->vmax.dim - ray->origin.dim) * invdir; \
54 tmin = t0 > tmin ? t0 : tmin; \
55 tmax = t1 < tmax ? t1 : tmax; \
56 if(tmax <= tmin) return 0; \
59 int ray_aabox_any(cgm_ray *ray, struct aabox *box, float tmax)
61 float invdir, t0, t1, tmp;
71 void aabox_union(struct aabox *res, struct aabox *a, struct aabox *b)
73 res->vmin.x = a->vmin.x < b->vmin.x ? a->vmin.x : b->vmin.x;
74 res->vmax.x = a->vmax.x > b->vmax.x ? a->vmax.x : b->vmax.x;
75 res->vmin.y = a->vmin.y < b->vmin.y ? a->vmin.y : b->vmin.y;
76 res->vmax.y = a->vmax.y > b->vmax.y ? a->vmax.y : b->vmax.y;
77 res->vmin.z = a->vmin.z < b->vmin.z ? a->vmin.z : b->vmin.z;
78 res->vmax.z = a->vmax.z > b->vmax.z ? a->vmax.z : b->vmax.z;
81 float aabox_surf_area(struct aabox *box)
85 dx = box->vmax.x - box->vmin.x;
86 dy = box->vmax.y - box->vmin.y;
87 dz = box->vmax.z - box->vmin.z;
89 return surf_area(dx, dy, dz);
92 float surf_area(float dx, float dy, float dz)
94 if(dx <= 0 || dy <= 0 || dz <= 0) {
97 return (dx * dy + dx * dz + dy * dz) * 2.0f;