diff --git a/miniRT.h b/miniRT.h index 939b0ff..dbbad10 100644 --- a/miniRT.h +++ b/miniRT.h @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 20:02:36 by yantoine #+# #+# */ -/* Updated: 2025/02/17 18:08:03 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 18:19:10 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -58,7 +58,6 @@ typdef struct s_calc float y; float t_cap; float t_bot; - float dist; float t_top; t_vec3 p; t_vec3 cp; diff --git a/parsing_cylinder.c b/parsing_cylinder.c index 27681e3..f5c08b4 100644 --- a/parsing_cylinder.c +++ b/parsing_cylinder.c @@ -6,26 +6,13 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/15 19:54:13 by yantoine #+# #+# */ -/* Updated: 2025/02/17 18:08:15 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 18:21:13 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -t_scene parsing_cylinder(const char *line, t_scene scene) -{ - const char **tokens = get_tokens_secure(scene, scene.numCylinders, MAX_CYLINDERS, 6); - scene.token_if_exit = tokens; - scene.cylinders[scene.numCylinders].center = parse_vector(tokens[1], scene); - scene.cylinders[scene.numCylinders].axis = parse_vector_normalize(tokens[2], scene); - scene.cylinders[scene.numCylinders].radius = parse_float(tokens[3], scene); - scene.cylinders[scene.numCylinders].height = parse_float(tokens[4], scene); - scene.cylinders[scene.numCylinders].color = parse_color(tokens[5], scene); - ft_free_array(tokens); - scene.numCylinders++; - return (scene); -} - +/* float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) { t_calc calc; @@ -103,5 +90,116 @@ float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) *hitNormal = (calc.proj > 0) ? calc.v : vec3_scale(calc.v, -1); } return calc.t_final; +}*/ + +t_scene parsing_cylinder(const char *line, t_scene scene) +{ + const char **tokens = get_tokens_secure(scene, scene.numCylinders, MAX_CYLINDERS, 6); + scene.token_if_exit = tokens; + scene.cylinders[scene.numCylinders].center = parse_vector(tokens[1], scene); + scene.cylinders[scene.numCylinders].axis = parse_vector_normalize(tokens[2], scene); + scene.cylinders[scene.numCylinders].radius = parse_float(tokens[3], scene); + scene.cylinders[scene.numCylinders].height = parse_float(tokens[4], scene); + scene.cylinders[scene.numCylinders].color = parse_color(tokens[5], scene); + ft_free_array(tokens); + scene.numCylinders++; + return (scene); } +// Initialise les variables de calcul et les coefficients du polynôme d'intersection +static int init_intersection(Ray ray, Cylinder cy, t_calc *calc) { + calc->d = ray.dir; + calc->oc = vec3_sub(ray.origin, cy.center); + calc->v = cy.axis; + calc->d_dot_v = vec3_dot(calc->d, calc->v); + calc->oc_dot_v = vec3_dot(calc->oc, calc->v); + calc->d_perp = vec3_sub(calc->d, vec3_scale(calc->v, calc->d_dot_v)); + calc->oc_perp = vec3_sub(calc->oc, vec3_scale(calc->v, calc->oc_dot_v)); + calc->a = vec3_dot(calc->d_perp, calc->d_perp); + calc->b = 2 * vec3_dot(calc->d_perp, calc->oc_perp); + calc->c = vec3_dot(calc->oc_perp, calc->oc_perp) - cy.radius * cy.radius; + calc->disc = calc->b * calc->b - 4 * calc->a * calc->c; + if (calc->disc < 0) + return -1; + calc->sqrtDisc = sqrtf(calc->disc); + calc->t0 = (-calc->b - calc->sqrtDisc) / (2 * calc->a); + calc->t1 = (-calc->b + calc->sqrtDisc) / (2 * calc->a); + return 0; +} + +// Calcule l'intersection sur la surface latérale du cylindre +static void compute_side_intersection(Ray ray, Cylinder cy, t_calc *calc) { + calc->t_side = -1; + if (calc->t0 > 1e-3f) { + calc->y = calc->oc_dot_v + calc->t0 * calc->d_dot_v; + if (fabs(calc->y) <= cy.height / 2.0f) + calc->t_side = calc->t0; + } + if (calc->t_side < 0 && calc->t1 > 1e-3f) { + calc->y = calc->oc_dot_v + calc->t1 * calc->d_dot_v; + if (fabs(calc->y) <= cy.height / 2.0f) + calc->t_side = calc->t1; + } +} + +// Calcule l'intersection sur les capuchons supérieur et inférieur +static void compute_cap_intersection(Ray ray, Cylinder cy, t_calc *calc) { + calc->t_cap = -1; + if (fabs(calc->d_dot_v) > 1e-6f) { + calc->t_bot = ((-cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; + if (calc->t_bot > 1e-3f) { + calc->p = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_bot)); + calc->cp = vec3_sub(calc->p, cy.center); + calc->dist = vec3_length(vec3_sub(calc->cp, vec3_scale(calc->v, vec3_dot(calc->cp, calc->v)))); + if (calc->dist <= cy.radius) + calc->t_cap = calc->t_bot; + } + calc->t_top = ((cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; + if (calc->t_top > 1e-3f) { + calc->p = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_top)); + calc->cp = vec3_sub(calc->p, cy.center); + calc->dist = vec3_length(vec3_sub(calc->cp, vec3_scale(calc->v, vec3_dot(calc->cp, calc->v)))); + if (calc->dist <= cy.radius && (calc->t_cap < 0 || calc->t_top < calc->t_cap)) + calc->t_cap = calc->t_top; + } + } +} + +// Sélectionne l'intersection la plus proche entre la surface latérale et les capuchons +static float select_final_intersection(t_calc *calc) { + if (calc->t_side > 1e-3f && calc->t_cap > 1e-3f) + calc->t_final = (calc->t_side < calc->t_cap) ? calc->t_side : calc->t_cap; + else if (calc->t_side > 1e-3f) + calc->t_final = calc->t_side; + else + calc->t_final = calc->t_cap; + return (calc->t_final > 1e-3f) ? calc->t_final : -1; +} + +// Calcule la normale au point d'intersection +static void compute_hit_normal(Ray ray, Cylinder cy, t_calc *calc, t_vec3 *hitNormal) { + calc->hitPoint = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_final)); + calc->cp = vec3_sub(calc->hitPoint, cy.center); + calc->proj = vec3_dot(calc->cp, calc->v); + if (fabs(calc->proj) < cy.height / 2.0f - 1e-3f) { + calc->n = vec3_sub(calc->cp, vec3_scale(calc->v, calc->proj)); + *hitNormal = vec3_normalize(calc->n); + } else { + *hitNormal = (calc->proj > 0) ? calc->v : vec3_scale(calc->v, -1); + } +} + +// Fonction principale d'intersection du cylindre +float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) { + t_calc calc; + if (init_intersection(ray, cy, &calc) < 0) + return -1; + compute_side_intersection(ray, cy, &calc); + compute_cap_intersection(ray, cy, &calc); + if (select_final_intersection(&calc) < 0) + return -1; + compute_hit_normal(ray, cy, &calc, hitNormal); + return calc.t_final; +} + + diff --git a/tags b/tags index af44277..8d4adbb 100644 --- a/tags +++ b/tags @@ -102,6 +102,9 @@ color miniRT.h /^ t_vec3 color;$/;" m struct:s_cylinder typeref:typename:t_vec3 color miniRT.h /^ t_vec3 color;$/;" m struct:s_light typeref:typename:t_vec3 color miniRT.h /^ t_vec3 color;$/;" m struct:s_plane typeref:typename:t_vec3 color miniRT.h /^ t_vec3 color;$/;" m struct:s_sphere typeref:typename:t_vec3 +compute_cap_intersection parsing_cylinder.c /^static void compute_cap_intersection(Ray ray, Cylinder cy, t_calc *calc) {$/;" f typeref:typename:void file: +compute_hit_normal parsing_cylinder.c /^static void compute_hit_normal(Ray ray, Cylinder cy, t_calc *calc, t_vec3 *hitNormal) {$/;" f typeref:typename:void file: +compute_side_intersection parsing_cylinder.c /^static void compute_side_intersection(Ray ray, Cylinder cy, t_calc *calc) {$/;" f typeref:typename:void file: cp miniRT.h /^ t_vec3 cp;$/;" m struct:s_calc typeref:typename:t_vec3 create_scene scene.c /^t_scene create_scene(void)$/;" f typeref:typename:t_scene cylinders miniRT.h /^ t_cylinder cylinders[MAX_CYLINDERS];$/;" m struct:s_scene typeref:typename:t_cylinder[] @@ -117,7 +120,8 @@ fov raytracer_formatted.c /^float fov = 90.0f;$/;" v typeref:typename:float get_tokens_secure parsing_utils.c /^inline char **get_tokens_secure(t_scene scene, const int numObject, const int numObjectMax, cons/;" f typeref:typename:char ** height miniRT.h /^ float height;$/;" m struct:s_cylinder typeref:typename:float hitPoint miniRT.h /^ t_vec3 hitPoint;$/;" m struct:s_calc typeref:typename:t_vec3 -intersectCylinder parsing_cylinder.c /^float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal)$/;" f typeref:typename:float +init_intersection parsing_cylinder.c /^static int init_intersection(Ray ray, Cylinder cy, t_calc *calc) {$/;" f typeref:typename:int file: +intersectCylinder parsing_cylinder.c /^float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) {$/;" f typeref:typename:float intersectCylinder raytracer_formatted.c /^float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal)$/;" f typeref:typename:float intersectPlane parsing_plane.c /^float intersectPlane(Ray ray, Plane p, t_vec3 *hitNormal)$/;" f typeref:typename:float intersectPlane raytracer_formatted.c /^float intersectPlane(Ray ray, Plane p, t_vec3 *hitNormal)$/;" f typeref:typename:float @@ -171,6 +175,7 @@ s_ray miniRT.h /^typedef struct s_ray$/;" s s_scene miniRT.h /^typedef struct s_scene$/;" s s_sphere miniRT.h /^typedef struct s_sphere$/;" s s_vec3 miniRT.h /^typedef struct s_vec3$/;" s +select_final_intersection parsing_cylinder.c /^static float select_final_intersection(t_calc *calc) {$/;" f typeref:typename:float file: spheres miniRT.h /^ t_sphere spheres[MAX_SPHERES];$/;" m struct:s_scene typeref:typename:t_sphere[] sqrtDisc miniRT.h /^ float sqrtDisc;$/;" m struct:s_calc typeref:typename:float t miniRT.h /^ float t;$/;" m struct:s_calc typeref:typename:float