From 676a246a78c5219d20aa55f3e42ba1e4170b550c Mon Sep 17 00:00:00 2001
From: matthew <matthew@owens.tech>
Date: Tue, 18 Sep 2018 21:05:42 +0100
Subject: [PATCH] refactored camera code to seperate compilation unit

---
 gl/camera.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gl/camera.h | 12 +++++++++
 gl/main.c   | 21 ++++++----------
 3 files changed, 89 insertions(+), 14 deletions(-)
 create mode 100644 gl/camera.c
 create mode 100644 gl/camera.h

diff --git a/gl/camera.c b/gl/camera.c
new file mode 100644
index 0000000..5f571dd
--- /dev/null
+++ b/gl/camera.c
@@ -0,0 +1,70 @@
+#include "camera.h"
+#include <math.h>
+#include <stdlib.h>
+
+static vec3_t worldSpaceVec;
+static float aspectRatio = 16.f/9.f;	// sane default for the aspect ratio
+
+typedef struct
+{
+	vec3_t from, to, up;
+	mat4_t camera, perspective, worldToScreen;
+} Camera_t;
+
+///TODO: figure out why this is failing
+mat4_t recalcPerspective(float hFovDeg, float near, float far)
+{
+	float vFovDeg = 2 * atan( tan(hFovDeg/2) * aspectRatio );
+	float vFovRad = vFovDeg * (M_PI/180.f);
+
+	return m4_perspective(vFovRad, aspectRatio, near, far);
+}
+
+void crpgCameraSetAR(float ar)
+{
+	aspectRatio = ar;
+}
+
+crpgCamera *crpgCameraNew(vec3_t from, vec3_t to, vec3_t up)
+{
+	// ensuring that the world doesn't go mental
+	worldSpaceVec = vec3(1, 1, -1);
+	Camera_t *ct = malloc(sizeof(Camera_t));
+	ct->from = from;
+	ct->to = to;
+	ct->up = up;
+	ct->camera = m4_look_at(from, to, up);
+	//ct->perspective = recalcPerspective(90.f, 1, 10);
+	ct->perspective = m4_perspective(60, aspectRatio, 1, 10);
+	ct->worldToScreen = m4_mul(ct->perspective, ct->camera);
+
+	crpgCamera *c = (crpgCamera *) ct;
+	return c;
+}
+
+void crpgCameraFree(crpgCamera *c)
+{
+	if(c == NULL){
+		return;
+	} else {
+		free(c);
+	}
+}
+
+void crpgCameraPan(crpgCamera *c, vec3_t pan)
+{
+	Camera_t *ct = (Camera_t *) c;
+	ct->from.x += pan.x;
+	ct->from.y += pan.y;
+	ct->from.z += pan.z;
+
+	// recalc camera matrices
+	ct->camera = m4_look_at(ct->from, ct->to, ct->up);
+	ct->worldToScreen = m4_mul(ct->perspective, ct->camera);
+}
+
+mat4_t *crpgCameraGetMat(crpgCamera *c)
+{
+	Camera_t *ct = (Camera_t *)c;
+	return &(ct->worldToScreen);
+}
diff --git a/gl/camera.h b/gl/camera.h
new file mode 100644
index 0000000..ed8d739
--- /dev/null
+++ b/gl/camera.h
@@ -0,0 +1,12 @@
+#ifndef CAMERA_H
+#define CAMERA_H
+#include "math_3d.h"
+#include <stdbool.h>
+typedef struct {} crpgCamera;
+
+crpgCamera *crpgCameraNew(vec3_t from, vec3_t to, vec3_t up);
+void crpgCameraFree(crpgCamera *c);
+void crpgCameraPan(crpgCamera *c, vec3_t pan);
+void crpgCameraSetAR(float ar);
+mat4_t *crpgCameraGetMat(crpgCamera *c);
+#endif//CAMERA_H
diff --git a/gl/main.c b/gl/main.c
index e7fafb2..83fdcaf 100644
--- a/gl/main.c
+++ b/gl/main.c
@@ -11,6 +11,7 @@
 #include "math_3d.h"
 #include "point.h"
 #include "cube.h"
+#include "camera.h"
 
 static SDL_Window *window = NULL;
 static SDL_GLContext *context = NULL;
@@ -38,8 +39,8 @@ static float blendVal = 0.2f;
 static crpgShader *shader = NULL;
 static crpgTexture *tex[2];
 static crpgCube *cubes[2];
-static mat4_t projection, transform, camera, world_to_screen;
-static vec3_t from, to, up, screenSpace, worldSpace;
+static crpgCamera *camera = NULL;
+static mat4_t transform;
 
 static void initShapes()
 {
@@ -97,18 +98,10 @@ static void initShapes()
 
 static void initView()
 {
-	projection = m4_perspective(60, (float)screen_width/(float)screen_height, 1, 10);
-	//from = vec3(0, 0.5, 2);
-	from = vec3(0,0,4);
-	to = vec3(0,0,0);
-	up = vec3(0,1,0);
-	camera = m4_look_at(from, to, up);
-	worldSpace = vec3(1, 1, -1);
-	world_to_screen = m4_mul(projection, camera);
-	screenSpace = m4_mul_pos(world_to_screen, worldSpace);
-
-	crpgCubeSetCamera(cubes[0], &world_to_screen);
-	crpgCubeSetCamera(cubes[1], &world_to_screen);
+	crpgCameraSetAR((float)screen_width/(float)screen_height);
+	camera = crpgCameraNew(vec3(0,0,4), vec3(0,0,0), vec3(0,1,0));
+	crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
+	crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
 
 	glEnable(GL_DEPTH_TEST);
 	glDepthFunc(GL_LESS);
-- 
2.20.1