scop/src/mat4_lookat.c

126 lines
2.8 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* mat4_lookat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: gbrochar <gbrochar@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/12/23 16:14:47 by gbrochar #+# #+# */
/* Updated: 2020/12/23 17:05:21 by gbrochar ### ########.fr */
/* */
/* ************************************************************************** */
#include "mat4.h"
#include "vec3.h"
#include "scop.h"
t_mat4 mat4_lookat_make_mat(t_vec3 x, t_vec3 y, t_vec3 z, t_vec3 eye)
{
t_mat4 ret;
ret.data[0] = x.x;
ret.data[1] = x.y;
ret.data[2] = x.z;
ret.data[3] = 0;
ret.data[4] = y.x;
ret.data[5] = y.y;
ret.data[6] = y.z;
ret.data[7] = 0;
ret.data[8] = z.x;
ret.data[9] = z.y;
ret.data[10] = z.z;
ret.data[11] = 0;
ret.data[12] = -(x.x * eye.x + x.y * eye.y + x.z * eye.z);
ret.data[13] = -(y.x * eye.x + y.y * eye.y + y.z * eye.z);
ret.data[14] = -(z.x * eye.x + z.y * eye.y + z.z * eye.z);
ret.data[15] = 1;
return (ret);
}
t_vec3 mat4_lookat_make_y(t_vec3 x, t_vec3 z)
{
t_vec3 y;
double len;
y.x = z.y * x.z - z.z * x.y;
y.y = z.z * x.x - z.x * x.z;
y.z = z.x * x.y - z.y * x.x;
len = y.x * y.x + y.y * y.y + y.z * y.z;
if (len - EPSILON < 0 && len + EPSILON > 0)
{
y.x = 0;
y.y = 0;
y.z = 0;
}
else
{
len = 1.0 / sqrt(len);
y.x *= len;
y.y *= len;
y.z *= len;
}
return (y);
}
t_vec3 mat4_lookat_make_x(t_vec3 z, t_vec3 up)
{
t_vec3 x;
double len;
x.x = up.y * z.z - up.z * z.y;
x.y = up.z * z.x - up.x * z.z;
x.z = up.x * z.y - up.y * z.x;
len = x.x * x.x + x.y * x.y + x.z * x.z;
if (len - EPSILON < 0 && len + EPSILON > 0)
{
x.x = 0;
x.y = 0;
x.z = 0;
}
else
{
len = 1.0 / sqrt(len);
x.x *= len;
x.y *= len;
x.z *= len;
}
return (x);
}
t_vec3 mat4_lookat_make_z(t_vec3 eye, t_vec3 target)
{
t_vec3 z;
double len;
z.x = eye.x - target.x;
z.y = eye.y - target.y;
z.z = eye.z - target.z;
len = z.x * z.x + z.y * z.y + z.z * z.z;
if (len - EPSILON < 0 && len + EPSILON > 0)
{
z.x = 0;
z.y = 0;
z.z = 1;
}
else
{
len = 1.0 / sqrt(len);
z.x *= len;
z.y *= len;
z.z *= len;
}
return (z);
}
t_mat4 mat4_lookat(t_vec3 eye, t_vec3 up, t_vec3 target)
{
t_vec3 z;
t_vec3 x;
t_vec3 y;
z = mat4_lookat_make_z(eye, target);
x = mat4_lookat_make_x(z, up);
y = mat4_lookat_make_y(x, z);
return (mat4_lookat_make_mat(x, y, z, eye));
}