36 lines
945 B
C
36 lines
945 B
C
#include "obj.h"
|
|
|
|
#include <math.h>
|
|
|
|
bool intersect_sphere(
|
|
obj_params_t params, ray_t ray, hit_t *hit_out, double t_min,
|
|
double t_max)
|
|
{
|
|
const vec3_t centre = params.sphere.centre;
|
|
const double r = params.sphere.radius;
|
|
const vec3_t disp = vec3_sub(centre, ray.orig);
|
|
|
|
const double a = vec3_dot(ray.dir, ray.dir);
|
|
const double h = vec3_dot(ray.dir, disp);
|
|
const double c = vec3_dot(disp, disp) - r * r;
|
|
|
|
const double discriminant = h * h - a * c;
|
|
if (discriminant < 0)
|
|
return false;
|
|
|
|
const double sqrtd = sqrt(discriminant);
|
|
const double low = (h - sqrtd) / a;
|
|
const double t = low > t_min ? low : (h + sqrtd) / a;
|
|
if (t < t_min || t_max < t)
|
|
return false;
|
|
|
|
const vec3_t point = vec3_add(ray.orig, vec3_scale(ray.dir, t));
|
|
const vec3_t normal = vec3_unit(vec3_sub(point, centre));
|
|
|
|
hit_out->point = point;
|
|
hit_out->normal = normal;
|
|
hit_out->t = t;
|
|
hit_out->front = vec3_dot(ray.dir, normal) < 0.0;
|
|
return true;
|
|
}
|