summaryrefslogtreecommitdiff
path: root/camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'camera.c')
-rw-r--r--camera.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/camera.c b/camera.c
new file mode 100644
index 0000000..f09d38c
--- /dev/null
+++ b/camera.c
@@ -0,0 +1,81 @@
+#include "camera.h"
+#include <math.h>
+
+struct camera
+create_default_camera(void)
+{
+ struct camera camera = {0};
+ camera.fov = 90.0f;
+ camera.near = 0.1f;
+ camera.far = 1000.0f;
+ return camera;
+}
+
+mat
+get_camera_view_mat(struct camera cam)
+{
+ return rotate_mat(make_translate(invv3(cam.pos)), cam.angles);
+}
+
+void
+get_camera_vectors(struct camera camera, v3 *l, v3 *u, v3 *f)
+{
+ f32 angle = deg2rad(camera.angles.x);
+ f32 cp = cosf(angle);
+ f32 sp = sinf(angle);
+ angle = deg2rad(camera.angles.y);
+ f32 cy = cosf(angle);
+ f32 sy = sinf(angle);
+ angle = deg2rad(camera.angles.z);
+ f32 cr = cosf(angle);
+ f32 sr = sinf(angle);
+ *l = (v3){cy * cr, -cy * sr, sy};
+ *u = (v3){sp * sy * cr + cp * sr, -sp * sy * sr + cp * cr, -sp * cy};
+ *f = (v3){-cp * sy * cr + sp * sr, cp * sy * sr + sp * cr, cp * cy};
+}
+
+mat
+camera_lookat(struct camera camera, v3 target, v3 worldy)
+{
+ mat translate = make_translate(invv3(camera.pos));
+ v3 z = normv3(subv3(camera.pos, target));
+ v3 x = normv3(crossv3(worldy, z));
+ v3 y = crossv3(z, x);
+ mat rotate = transpose_mat(make_rotate(x, y, z));
+ mat result = mulmat(rotate, translate);
+ return result;
+}
+
+mat
+ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f)
+{
+ mat ortho = mat_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;
+}
+
+mat
+perspective(f32 near, f32 far, f32 fov, f32 aspect_ratio)
+{
+ f32 r = near * tanf(deg2rad(fov / 2.0f));
+ f32 t = r / aspect_ratio;
+ mat res = mat_identity;
+ res.c0.x = near / r;
+ res.c1.y = near / t;
+ res.c2.z = -(far + near) / (far - near);
+ res.c2.w = -1.0f;
+ res.c3.z = (-2.0f * far * near) / (far - near);
+ res.c3.w = 0.0f;
+ return res;
+}
+
+mat
+camera_perspective(struct camera camera, f32 aspect_ratio)
+{
+ return perspective(camera.near, camera.far, camera.fov, aspect_ratio);
+}