mat4 camera_get_view_mat(camera_t camera) { mat4 view = mat4_make_transl(v3_inv(camera.position)); view = mat4_rotate(view, camera.angles); return view; } void camera_get_vecs(camera_t camera, v3 *left, v3 *up, v3 *front) { f32 angle = deg2rad(camera.angles.x); f32 cp = fcos(angle); f32 sp = fsin(angle); angle = deg2rad(camera.angles.y); f32 cy = fcos(angle); f32 sy = fsin(angle); angle = deg2rad(camera.angles.z); f32 cr = fcos(angle); f32 sr = fsin(angle); *left = (v3){cy*cr, -cy*sr, sy}; *up = (v3){sp*sy*cr+cp*sr, -sp*sy*sr+cp*cr, -sp*cy}; *front = (v3){-cp*sy*cr+sp*sr, cp*sy*sr+sp*cr, cp*cy}; } mat4 camera_lookat(camera_t camera, v3 target, v3 world_up) { v3 front = v3_norm(v3_sub(camera.position, target)); v3 right = v3_norm(v3_cross(world_up, front)); v3 up = v3_cross(front, right); mat4 translate = mat4_make_transl(v3_inv(camera.position)); mat4 rotate = mat4_transp(mat4_make_rotate(right, up, front)); mat4 result = mat4_mul(rotate, translate); return result; } mat4 ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f) { mat4 ortho = MAT4_IDENTITY; ortho.c0.x = 2.0f/(r-l); ortho.c1.y = 2.0f/(t-b); ortho.c2.z = -2.0f/(f-n); ortho.c3.x = -(r+l)/(r-l); ortho.c3.y = -(t+b)/(t-b); ortho.c3.z = -(f+n)/(f-n); return ortho; } mat4 perspective(camera_t camera, f32 aspect_ratio) { f32 n = camera.near; f32 f = camera.far; f32 r = n*ftan(deg2rad(camera.fov/2.0f)); f32 t = r/aspect_ratio; mat4 perspective = MAT4_IDENTITY; perspective.c0.x = n/r; perspective.c1.y = n/t; perspective.c2.z = -(f+n)/(f-n); perspective.c2.w = -1.0f; perspective.c3.z = (-2.0f*f*n)/(f-n); perspective.c3.w = 0.0f; return perspective; }