7 /* TODO custom hit allocator */
8 struct hit *alloc_hit(void)
10 struct hit *hit = calloc(sizeof *hit, 1);
12 perror("failed to allocate ray hit node");
18 void free_hit(struct hit *hit)
23 void free_hit_list(struct hit *hit)
26 struct hit *tmp = hit;
32 struct hit *ray_intersect(struct ray *ray, csg_object *o)
36 return ray_sphere(ray, o);
38 return ray_cylinder(ray, o);
40 return ray_plane(ray, o);
42 return ray_csg_un(ray, o);
44 return ray_csg_isect(ray, o);
46 return ray_csg_sub(ray, o);
53 struct hit *ray_sphere(struct ray *ray, csg_object *o)
55 float a, b, c, d, sqrt_d, t0, t1, t, sq_rad;
57 struct ray locray = *ray;
59 if(o->sph.rad == 0.0f) {
62 sq_rad = o->sph.rad * o->sph.rad;
64 xform_ray(&locray, o->ob.inv_xform);
66 a = locray.dx * locray.dx + locray.dy * locray.dy + locray.dz * locray.dz;
67 b = 2.0f * (locray.dx * locray.x + locray.dy * locray.y + locray.dz * locray.z);
68 c = (locray.x * locray.x + locray.y * locray.y + locray.z * locray.z) - sq_rad;
70 d = b * b - 4.0f * a * c;
71 if(d < 1e-6) return 0;
74 t0 = (-b + sqrt_d) / (2.0f * a);
75 t1 = (-b - sqrt_d) / (2.0f * a);
77 if(t0 < 1e-6) t0 = t1;
78 if(t1 < 1e-6) t1 = t0;
79 t = t0 < t1 ? t0 : t1;
80 if(t < 1e-6) return 0;
84 hit->x = ray->x + ray->dx * t;
85 hit->y = ray->y + ray->dy * t;
86 hit->z = ray->z + ray->dz * t;
87 hit->nx = hit->x / o->sph.rad;
88 hit->ny = hit->y / o->sph.rad;
89 hit->nz = hit->z / o->sph.rad;
94 struct hit *ray_cylinder(struct ray *ray, csg_object *o)
96 struct ray locray = *ray;
98 xform_ray(&locray, o->ob.inv_xform);
102 struct hit *ray_plane(struct ray *ray, csg_object *o)
104 float vx, vy, vz, ndotv, ndotr, t;
106 struct ray locray = *ray;
108 xform_ray(&locray, o->ob.inv_xform);
110 vx = o->plane.nx * o->plane.d - locray.x;
111 vy = o->plane.ny * o->plane.d - locray.y;
112 vz = o->plane.nz * o->plane.d - locray.z;
114 ndotv = o->plane.nx * vx + o->plane.ny * vy + o->plane.nz * vz;
115 if(fabs(ndotv) < 1e-6) return 0;
117 ndotr = o->plane.nx * locray.dx + o->plane.ny * locray.dy + o->plane.nz * locray.dz;
123 hit->x = ray->x + ray->dx * t;
124 hit->y = ray->y + ray->dy * t;
125 hit->z = ray->z + ray->dz * t;
126 hit->nx = o->plane.nx;
127 hit->ny = o->plane.ny;
128 hit->nz = o->plane.nz;
134 struct hit *ray_csg_un(struct ray *ray, csg_object *o)
136 struct hit *hita, *hitb;
138 hita = ray_intersect(ray, o->un.a);
139 hitb = ray_intersect(ray, o->un.a);
141 if(!hita) return hitb;
142 if(!hitb) return hita;
144 if(hita->t < hitb->t) {
152 struct hit *ray_csg_isect(struct ray *ray, csg_object *o)
157 struct hit *ray_csg_sub(struct ray *ray, csg_object *o)
163 void xform_ray(struct ray *ray, float *mat)
167 mat4_copy(m3x3, mat);
170 mat4_xform3(&ray->x, mat, &ray->x);
171 mat4_xform3(&ray->dx, m3x3, &ray->dx);