#include "camera.h" #include void r_camera_base_look_at(r_camera_base *c, v3 target) { c->direction = normalize(target - c->position); } m4 r_camera_base_view(r_camera_base *c) { return r_view_matrix(c->position, c->direction, c->up); } void r_camera_fps_look_at(r_camera_fps *c, v3 target) { v3 direction = normalize(target - c->position); c->pitch = degrees(asin(direction.z)); direction = normalize(v3{direction.x, direction.y, 0}); c->yaw = degrees(asin(direction.y)); if(direction.x < 0) c->yaw = 180 - c->yaw; } m4 r_camera_fps_view(r_camera_fps *c) { v3 up; v3 direction; up = r_camera_up_vector; direction = r_camera_fps_direction(c); return r_view_matrix(c->position, direction, up); } v3 r_camera_fps_direction(r_camera_fps *c) { v3 direction; direction.x = cos(radians(c->yaw)) * cos(radians(c->pitch)); direction.y = sin(radians(c->yaw)) * cos(radians(c->pitch)); direction.z = sin(radians(c->pitch)); return direction; } m4 r_view_matrix(v3 position, v3 direction, v3 up) { v3 right = normalize(cross(up, -direction)); v3 camera_up = normalize(cross(-direction, right)); m4 result = m4_identity; // new X axis result.E[0][0] = right.x; result.E[0][1] = right.y; result.E[0][2] = right.z; // new Y axis result.E[1][0] = camera_up.x; result.E[1][1] = camera_up.y; result.E[1][2] = camera_up.z; // new Z axis result.E[2][0] = -direction.x; result.E[2][1] = -direction.y; result.E[2][2] = -direction.z; // translation result.E[0][3] = -dot(right , position); result.E[1][3] = -dot(camera_up, position); result.E[2][3] = -dot(-direction, position); return result; } m4 r_perspective_matrix(f32 fov, f32 aspect_ratio, f32 near_plane, f32 far_plane) { m4 result = m4_zero; f32 tanf2 = tan(radians(fov) / 2.0); result.E[0][0] = 1.0 / (aspect_ratio * tanf2); result.E[1][1] = 1.0 / tanf2; result.E[2][2] = - (far_plane + near_plane) / (far_plane - near_plane); result.E[2][3] = -2.0 * far_plane * near_plane / (far_plane - near_plane); result.E[3][2] = -1.0; return result; } m4 r_orthographic_matrix(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) { m4 result = m4_zero; result.E[0][0] = 2 / (right - left); result.E[1][1] = 2 / (top - bottom); result.E[2][2] = -2 / (far - near); result.E[3][3] = 1; result.E[0][3] = - (right + left) / (right - left); result.E[1][3] = - (top + bottom) / (top - bottom); result.E[2][3] = - (far + near) / (far - near); return result; }