I'm currently coding a simple raytracer in C. Everything is working fine, except for the rotations. I'm trying to rotate my objects (cylinders in that matter). The cylinders rotates, but the shading are completely off, and the object only rotates between 0° and 90°, and goes back to normal at 360° (which is obvious). I'd appreciate if anyone could give me a hint on what I'm doing wrong. Here's some sample code.
Function that find intersections for cylinders :
double mininter;
double inter;
t_vect *normal;
t_color *c;
t_cyl *cyl;
cyl = e->scene.cyls;
mininter = -1;
while (cyl != NULL && limiter-- != 0)
{
ray = rotate_eye(ray, cyl->rotate, -1);
inter = cylinder_inter(cyl, ray);
if (inter > ACCURACY && (inter < mininter || mininter == -1))
{
mininter = inter;
p = vect_add(ray->og, vect_mult(ray->dir, inter));
ray = rotate_eye(ray, cyl->rotate, 1);
normal = cylinder_normal(cyl->og, p);
c = cyl->color;
}
cyl = cyl->next;
}
return (new_inter(normal, mininter, c, p));
My rotation.c file :
static t_vect *x(t_vect *v, double rot, int stage)
{
rot = DEG_TO_RAD(rot * stage);
v->y = v->y * cos(rot) + v->z * -sin(rot);
v->z = v->y * sin(rot) + v->z * cos(rot);
return (v);
}
static t_vect *y(t_vect *v, double rot, int stage)
{
rot = DEG_TO_RAD(rot * stage);
v->x = v->x * cos(rot) + v->z * sin(rot);
v->z = v->x * -sin(rot) + v->z * cos(rot);
return (v);
}
static t_vect *z(t_vect *v, double rot, int stage)
{
rot = DEG_TO_RAD(rot * stage);
v->x = v->x * cos(rot) + v->y * -sin(rot);
v->y = v->x * sin(rot) + v->y * cos(rot);
return (v);
}
t_ray *rotate_eye(t_ray *ray, t_vect *rot, int stage)
{
ray->og = x(ray->og, rot->z, stage);
ray->og = y(ray->og, rot->y, stage);
ray->og = z(ray->og, rot->x, stage);
ray->dir = x(ray->dir, rot->z, stage);
ray->dir = y(ray->dir, rot->y, stage);
ray->dir = z(ray->dir, rot->x, stage);
return (ray);
}
The shadow/color file :
static double shadows(t_env *e, t_inter *inter)
{
t_ray *iray;
t_vect *v;
t_vect *l;
l = e->scene.spot->pos;
v = new_vector(l->x - inter->point->x, l->y - inter->point->y,
l->z - inter->point->z);
iray = new_ray(inter->point, l);
return (calc_inter(e, iray)->dist);
}
t_color *find_color_at(t_env *e, t_ray *ray)
{
t_color *result;
t_inter *mininter;
t_vect *dist_l;
double shade;
mininter = calc_inter(e, ray);
if (mininter->dist > ACCURACY)
{
dist_l = normalize(vect_add(e->scene.spot->pos, negative(ray->og)));
shade = dot_product(dist_l, mininter->normal);
if (shadows(e, mininter) > ACCURACY)
result = color_scalar(AMBIENTLIGHT * shadows(e, mininter),
mininter->color);
else
result = shade < 0 ? color_scalar(AMBIENTLIGHT + DIFFUSELIGHT *
0, mininter->color) : color_scalar(AMBIENTLIGHT +
DIFFUSELIGHT * shade, mininter->color);
}
else
result = new_color(0, 0, 0);
return (result);
}
Some screeshots.
Scene file : 0° rotation
camera:
pos:
0, 0, 100
dir:
0, 0, 0
----
spheres:
new:
pos:
20, 0, 20
radius:
30
color:
42, 255, 255
----
----
cylinders:
new:
pos:
-20, 0, -30
radius:
20
color:
255, 42, 23
rotate:
0, 0, 0
----
----
spot:
pos:
50, 0, 150
----
END
https://gyazo.com/6ab10dbfba27a889ac6397c30aa4adda
Scene file : 42° rotation
camera:
pos:
0, 0, 100
dir:
0, 0, 0
----
spheres:
new:
pos:
20, 0, 20
radius:
30
color:
42, 255, 255
----
----
cylinders:
new:
pos:
-20, 0, -30
radius:
20
color:
255, 42, 23
rotate:
42, 0, 0
----
----
spot:
pos:
50, 0, 150
----
END
https://gyazo.com/f244f6c7e2d2a81b6001fc175c16c289
Scene file : 91° rotation
camera:
pos:
0, 0, 100
dir:
0, 0, 0
----
spheres:
new:
pos:
20, 0, 20
radius:
30
color:
42, 255, 255
----
----
cylinders:
new:
pos:
-20, 0, -30
radius:
20
color:
255, 42, 23
rotate:
91, 0, 0
----
----
spot:
pos:
50, 0, 150
----
END
https: //gyazo.com/86cda440cfca079d07e04d1ef19b8a21
Anything will help, thanks in advance !
Consider your rotation around the x axis:
static t_vect *x(t_vect *v, double rot, int stage) { rot = DEG_TO_RAD(rot * stage); v->y = v->y * cos(rot) + v->z * -sin(rot); v->z = v->y * sin(rot) + v->z * cos(rot); return (v); }
Notice that the y coordinate of the input vector contributes to both the y and z coordinates of the result vector. Now notice that what you actually use in the computation of the resulting z coordinate is not the input y, but rather the computed result y. This is erroneous.
Similar applies to your other rotation functions.