sphere.c
 1  /* ************************************************************************** */
 2  /*                                                                            */
 3  /*                                                        :::      ::::::::   */
 4  /*   sphere.c                                           :+:      :+:    :+:   */
 5  /*                                                    +:+ +:+         +:+     */
 6  /*   By: salee2 <salee2@student.42seoul.kr>         +#+  +:+       +#+        */
 7  /*                                                +#+#+#+#+#+   +#+           */
 8  /*   Created: 2023/05/24 20:23:05 by salee2            #+#    #+#             */
 9  /*   Updated: 2023/05/24 20:23:06 by salee2           ###   ########.fr       */
10  /*                                                                            */
11  /* ************************************************************************** */
12  
13  #include "include/minirt.h"
14  
15  t_sphere	*sphere_(t_point3 center, double radius)
16  {
17  	t_sphere	*this;
18  
19  	this = (t_sphere *)malloc(sizeof(t_sphere));
20  	if (this == NULL)
21  		return (NULL);
22  	this->center = center;
23  	this->radius = radius;
24  	this->radius_sq = radius * radius;
25  	return (this);
26  }
27  
28  static t_coefficient	get_coefficient(const t_sphere *sphere, t_ray *ray)
29  {
30  	t_coefficient	coef;
31  	const t_vec3	co = sub(ray->origin, sphere->center);
32  
33  	coef.a = mag_sq(ray->dir);
34  	coef.b = dot(co, ray->dir);
35  	coef.c = mag_sq(co) - sphere->radius_sq;
36  	return (coef);
37  }
38  
39  t_bool	intersect_ray_sphere(t_object *object, t_ray *ray, t_hit *hit)
40  {
41  	const t_sphere		*sphere = object->element;
42  	const t_coefficient	coef = get_coefficient(sphere, ray);
43  	const double		d = coef.b * coef.b - coef.a * coef.c;
44  	const double		sqrtd = sqrt(d);
45  	double				root;
46  
47  	if (d < 0.0)
48  		return (FALSE);
49  	root = (-coef.b - sqrtd) / coef.a;
50  	if (root < hit->t_min || hit->t_max < root)
51  	{
52  		root = (-coef.b + sqrtd) / coef.a;
53  		if (root < hit->t_min || hit->t_max < root)
54  			return (FALSE);
55  	}
56  	hit->t = root;
57  	hit->t_max = hit->t;
58  	hit->point = ray_at(hit->t, ray);
59  	hit->normal = norm(sub(hit->point, sphere->center));
60  	if (dot(ray->dir, hit->normal) > 0)
61  		hit->normal = scl_mul(-1, hit->normal);
62  	hit->albedo = object->albedo;
63  	return (TRUE);
64  }