108 lines
2.4 KiB
C++
108 lines
2.4 KiB
C++
#include "camera.h"
|
|
#include <stdio.h>
|
|
|
|
|
|
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;
|
|
}
|