commit 9576914fa6933bb5e8adcf4613a56bdf7daf19ab
parent 98ebaefddb0351101304f424205d3fae7f2e314f
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 29 Apr 2018 14:17:22 -0700
wip
Diffstat:
19 files changed, 603 insertions(+), 596 deletions(-)
diff --git a/Makefile b/Makefile
@@ -36,13 +36,13 @@ OBJS += $(SRC)/util.o
 
 SRCS=$(OBJS:.o=.c)
 
-# include $(OBJS:.o=.d)
+include $(OBJS:.o=.d)
 
 all: $(BIN)
 
-# src/%.d: src/%.c
-# 	@rm -f $@; \
-# 	$(CC) -MM $(CFLAGS) $< > $@
+src/%.d: src/%.c
+	@rm -f $@; \
+	$(CC) -MM $(CFLAGS) $< > $@
 
 %.o: %.c %.h
 	$(CC) $(CFLAGS) -fPIC $(DEFS) -c $< -o $@
diff --git a/src/camera.c b/src/camera.c
@@ -6,3 +6,9 @@
 struct camera *camera_init(struct camera *cam) {
   return NULL;
 }
+
+
+void
+camera_follow(mat4 *cam, mat4 *target_prev, mat4 *target) {
+  cam
+}
diff --git a/src/common.h b/src/common.h
@@ -5,6 +5,9 @@
 #include <stdbool.h>
 
 #define MAT3_ELEMS 9
+#define M_X 12
+#define M_Y 13
+#define M_Z 14
 #define MAT4_ELEMS 16
 
 #define SLAB(f) "etc/slab/" f
diff --git a/src/game.c b/src/game.c
@@ -7,7 +7,7 @@ mat4 *cam_init = (float[16]){
   0.955761, 0.228018, -0.185425, 0.000000,
   -0.293528, 0.779583, -0.552437, 0.000000,
   0.018780, 0.580299, 0.802257, 0.000000,
-  -58.746227, -62.404854, -34.097778, 1.000000
+  -71.766136, -47.881512, -44.216671, 1.000000
 };
 
 void game_init(struct game *game) {
@@ -16,11 +16,13 @@ void game_init(struct game *game) {
   float *camera = game->test_resources.camera;
   float *terrain = game->test_resources.terrain_node;
   float *player = game->test_resources.player;
+  float *player_cam = game->test_resources.player_cam;
   float *light_dir = game->test_resources.light_dir;
 
   mat4_id(mvp);
   mat4_id(normal);
   mat4_id(camera);
+  mat4_id(player_cam);
 
   light_dir[0] = 0.5;
   light_dir[1] = 1;
@@ -35,7 +37,7 @@ void game_init(struct game *game) {
 
   terrain[14] = 20.0;
 
-  mat4_scale(player, V3(0.36,0.36,1.7), player);
+  mat4_scale(player, V3(0.36,0.36,PLAYER_HEIGHT), player);
 
   input_init(&game->input);
 }
diff --git a/src/game.h b/src/game.h
@@ -5,6 +5,8 @@
 #include "buffer.h"
 #include "input.h"
 
+#define PLAYER_HEIGHT 1.7
+
 /*
  * Global data used by our render callback:
  * NOTE: just for testing right now
@@ -33,6 +35,7 @@ struct resources {
     float light_dir[3];
     float camera[MAT4_ELEMS];
     float player[MAT4_ELEMS];
+    float player_cam[MAT4_ELEMS];
     float camera_persp[MAT4_ELEMS];
     GLfloat fade_factor;
 };
diff --git a/src/mat4.c b/src/mat4.c
@@ -0,0 +1,325 @@
+
+#include "mat4.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include "../vec3/vec3.h"
+
+#define PI 3.14159265f
+
+mat4 *mat4_copy(const mat4 *src, mat4 *dst) {
+  memcpy(dst, src, sizeof(float) * 16);
+  return dst;
+}
+
+
+mat4 *mat4_id(mat4 *dst) {
+  dst[0]  = 1.; dst[1]  = 0.; dst[2]  = 0.; dst[3]  = 0.;
+  dst[4]  = 0.; dst[5]  = 1.; dst[6]  = 0.; dst[7]  = 0.;
+  dst[8]  = 0.; dst[9]  = 0.; dst[10] = 1.; dst[11] = 0.;
+  dst[12] = 0.; dst[13] = 0.; dst[14] = 0.; dst[15] = 1.;
+
+  return dst;
+}
+
+mat4 *mat4_transpose(mat4 *src, mat4 *dest) {
+	// If we are transposing ourselves we can skip a few steps but have to cache some values
+	if(dest == NULL || src == dest) {
+		float a01 = src[1], a02 = src[2], a03 = src[3];
+		float a12 = src[6], a13 = src[7];
+		float a23 = src[11];
+
+		src[1]  = src[4];
+		src[2]  = src[8];
+		src[3]  = src[12];
+		src[4]  = a01;
+		src[6]  = src[9];
+		src[7]  = src[13];
+		src[8]  = a02;
+		src[9]  = a12;
+		src[11] = src[14];
+		src[12] = a03;
+		src[13] = a13;
+		src[14] = a23;
+		return src;
+	}
+
+	dest[0]  = src[0];
+	dest[1]  = src[4];
+	dest[2]  = src[8];
+	dest[3]  = src[12];
+	dest[4]  = src[1];
+	dest[5]  = src[5];
+	dest[6]  = src[9];
+	dest[7]  = src[13];
+	dest[8]  = src[2];
+	dest[9]  = src[6];
+	dest[10] = src[10];
+	dest[11] = src[14];
+	dest[12] = src[3];
+	dest[13] = src[7];
+	dest[14] = src[11];
+	dest[15] = src[15];
+	return dest;
+
+}
+
+/*
+ * mat4.frustum
+ * Generates a frustum matrix with the given bounds
+ *
+ * Params:
+ * left, right - scalar, left and right bounds of the frustum
+ * bottom, top - scalar, bottom and top bounds of the frustum
+ * near, far - scalar, near and far bounds of the frustum
+ * dest - Optional, mat4 frustum matrix will be written into
+ *
+ * Returns:
+ * dest if specified, a new mat4 otherwise
+ */
+mat4 *mat4_frustum (float left, float right, float bottom,
+                    float top, float near, float far, mat4 *dest) {
+	float rl = (right - left);
+	float tb = (top - bottom);
+	float fn = (far - near);
+	dest[0] = (near*2) / rl;
+	dest[1] = 0;
+	dest[2] = 0;
+	dest[3] = 0;
+	dest[4] = 0;
+	dest[5] = (near*2) / tb;
+	dest[6] = 0;
+	dest[7] = 0;
+	dest[8] = (right + left) / rl;
+	dest[9] = (top + bottom) / tb;
+	dest[10] = -(far + near) / fn;
+	dest[11] = -1;
+	dest[12] = 0;
+	dest[13] = 0;
+	dest[14] = -(far*near*2) / fn;
+	dest[15] = 0;
+	return dest;
+}
+
+/*
+ * mat4.translate
+ * Translates a matrix by the given vector
+ *
+ * Params:
+ * mat - mat4 to translate
+ * vec - vec3 specifying the translation
+ * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
+ *
+ * Returns:
+ * dest if specified, mat otherwise
+ */
+mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest) {
+	if(!dest || mat == dest) {
+		mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12];
+		mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13];
+		mat[14] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14];
+		mat[15] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15];
+		return mat;
+	}
+
+	float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
+	float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
+	float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
+
+	dest[0] = a00;
+	dest[1] = a01;
+	dest[2] = a02;
+	dest[3] = a03;
+	dest[4] = a10;
+	dest[5] = a11;
+	dest[6] = a12;
+	dest[7] = a13;
+	dest[8] = a20;
+	dest[9] = a21;
+	dest[10] = a22;
+	dest[11] = a23;
+
+	dest[12] = a00*x + a10*y + a20*z + mat[12];
+	dest[13] = a01*x + a11*y + a21*z + mat[13];
+	dest[14] = a02*x + a12*y + a22*z + mat[14];
+	dest[15] = a03*x + a13*y + a23*z + mat[15];
+	return dest;
+}
+
+mat4 *mat4_perspective(float fov, float aspect, float near,
+                       float far, mat4 *dest) {
+	float top = near * tanf(fov*PI / 360.0f);
+	float right = top * aspect;
+	return mat4_frustum(-right, right, -top, top, near, far, dest);
+}
+
+mat4 *mat4_inverse(mat4 *src, mat4 *dest) {
+	if(dest == NULL) { dest = src; }
+
+	// Cache the srcrix values (makes for huge speed increases!)
+	float a00 = src[0], a01  = src[1], a02  = src[2], a03  = src[3];
+	float a10 = src[4], a11  = src[5], a12  = src[6], a13  = src[7];
+	float a20 = src[8], a21  = src[9], a22  = src[10], a23 = src[11];
+	float a30 = src[12], a31 = src[13], a32 = src[14], a33 = src[15];
+
+	float b00 = a00*a11 - a01*a10;
+	float b01 = a00*a12 - a02*a10;
+	float b02 = a00*a13 - a03*a10;
+	float b03 = a01*a12 - a02*a11;
+	float b04 = a01*a13 - a03*a11;
+	float b05 = a02*a13 - a03*a12;
+	float b06 = a20*a31 - a21*a30;
+	float b07 = a20*a32 - a22*a30;
+	float b08 = a20*a33 - a23*a30;
+	float b09 = a21*a32 - a22*a31;
+	float b10 = a21*a33 - a23*a31;
+	float b11 = a22*a33 - a23*a32;
+
+	// Calculate the determinant (inlined to avoid double-caching)
+	float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
+
+	dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet;
+	dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet;
+	dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet;
+	dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet;
+	dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet;
+	dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet;
+	dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet;
+	dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet;
+	dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet;
+	dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet;
+	dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet;
+	dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet;
+	dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet;
+	dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet;
+	dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet;
+	dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet;
+
+	return dest;
+}
+
+
+mat4 *mat4_multiply(const mat4 *a, const mat4 *b, mat4 *dst) {
+  float a00 = a[0],  a01 = a[1],  a02 = a[2],  a03 = a[3];
+  float a10 = a[4],  a11 = a[5],  a12 = a[6],  a13 = a[7];
+  float a20 = a[8],  a21 = a[9],  a22 = a[10], a23 = a[11];
+  float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
+
+  float b00 = b[0],  b01 = b[1],  b02 = b[2],  b03 = b[3];
+  float b10 = b[4],  b11 = b[5],  b12 = b[6],  b13 = b[7];
+  float b20 = b[8],  b21 = b[9],  b22 = b[10], b23 = b[11];
+  float b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15];
+
+  dst[0]  = b00*a00 + b01*a10 + b02*a20 + b03*a30;
+  dst[1]  = b00*a01 + b01*a11 + b02*a21 + b03*a31;
+  dst[2]  = b00*a02 + b01*a12 + b02*a22 + b03*a32;
+  dst[3]  = b00*a03 + b01*a13 + b02*a23 + b03*a33;
+  dst[4]  = b10*a00 + b11*a10 + b12*a20 + b13*a30;
+  dst[5]  = b10*a01 + b11*a11 + b12*a21 + b13*a31;
+  dst[6]  = b10*a02 + b11*a12 + b12*a22 + b13*a32;
+  dst[7]  = b10*a03 + b11*a13 + b12*a23 + b13*a33;
+  dst[8]  = b20*a00 + b21*a10 + b22*a20 + b23*a30;
+  dst[9]  = b20*a01 + b21*a11 + b22*a21 + b23*a31;
+  dst[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32;
+  dst[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33;
+  dst[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30;
+  dst[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31;
+  dst[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32;
+  dst[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33;
+
+  return dst;
+}
+
+// TODO: util me
+int float_eq(float a, float b);
+int float_eq(float a, float b) {
+  return fabsf(a - b) < 0.0001;
+}
+
+
+mat4 *mat4_rotate(const mat4 *mat, const float angle,
+                  const float *axis, mat4 *dest) {
+  float x = axis[0], y = axis[1], z = axis[2];
+  float len = (float)sqrt(x*x + y*y + z*z);
+
+  if (float_eq(len, 0.)) { return NULL; }
+  // TODO: float comparison tool
+  if (!float_eq(len, 1.)) {
+    len = 1 / len;
+    x *= len;
+    y *= len;
+    z *= len;
+  }
+
+  float s = (float)sin(angle);
+  float c = (float)cos(angle);
+  float t = 1-c;
+
+  // Cache the matrix values (makes for huge speed increases!)
+  float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03  = mat[3];
+  float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13  = mat[7];
+  float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
+
+  // Construct the elements of the rotation matrix
+  float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
+  float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
+  float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
+
+  // If the source and destination differ, copy the unchanged last row
+  if(mat != dest) {
+    dest[12] = mat[12];
+    dest[13] = mat[13];
+    dest[14] = mat[14];
+    dest[15] = mat[15];
+  }
+
+  // Perform rotation-specific matrix multiplication
+  dest[0] = a00*b00 + a10*b01 + a20*b02;
+  dest[1] = a01*b00 + a11*b01 + a21*b02;
+  dest[2] = a02*b00 + a12*b01 + a22*b02;
+  dest[3] = a03*b00 + a13*b01 + a23*b02;
+
+  dest[4] = a00*b10 + a10*b11 + a20*b12;
+  dest[5] = a01*b10 + a11*b11 + a21*b12;
+  dest[6] = a02*b10 + a12*b11 + a22*b12;
+  dest[7] = a03*b10 + a13*b11 + a23*b12;
+
+  dest[8] = a00*b20 + a10*b21 + a20*b22;
+  dest[9] = a01*b20 + a11*b21 + a21*b22;
+  dest[10] = a02*b20 + a12*b21 + a22*b22;
+  dest[11] = a03*b20 + a13*b21 + a23*b22;
+
+  return dest;
+}
+
+mat4 *mat4_scale(mat4 *a, float v[3], mat4 *out) {
+  float x = v[0], y = v[1], z = v[2];
+
+  out[0] = a[0] * x;
+  out[1] = a[1] * x;
+  out[2] = a[2] * x;
+  out[3] = a[3] * x;
+  out[4] = a[4] * y;
+  out[5] = a[5] * y;
+  out[6] = a[6] * y;
+  out[7] = a[7] * y;
+  out[8] = a[8] * z;
+  out[9] = a[9] * z;
+  out[10] = a[10] * z;
+  out[11] = a[11] * z;
+  out[12] = a[12];
+  out[13] = a[13];
+  out[14] = a[14];
+  out[15] = a[15];
+  return out;
+};
+
+
+void mat4_print(const mat4 *m) {
+  for (int i = 0; i < 16; ++i) {
+    if (i % 4 == 0)
+      printf("\n");
+    printf("%f, ", m[i]);
+  }
+  printf("\n");
+}
diff --git a/src/mat4/mat4.h b/src/mat4.h
diff --git a/src/mat4/mat4.c b/src/mat4/mat4.c
@@ -1,324 +0,0 @@
-
-#include "mat4.h"
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-
-#define PI 3.14159265f
-
-mat4 *mat4_copy(const mat4 *src, mat4 *dst) {
-  memcpy(dst, src, sizeof(float) * 16);
-  return dst;
-}
-
-
-mat4 *mat4_id(mat4 *dst) {
-  dst[0]  = 1.; dst[1]  = 0.; dst[2]  = 0.; dst[3]  = 0.;
-  dst[4]  = 0.; dst[5]  = 1.; dst[6]  = 0.; dst[7]  = 0.;
-  dst[8]  = 0.; dst[9]  = 0.; dst[10] = 1.; dst[11] = 0.;
-  dst[12] = 0.; dst[13] = 0.; dst[14] = 0.; dst[15] = 1.;
-
-  return dst;
-}
-
-mat4 *mat4_transpose(mat4 *src, mat4 *dest) {
-	// If we are transposing ourselves we can skip a few steps but have to cache some values
-	if(dest == NULL || src == dest) {
-		float a01 = src[1], a02 = src[2], a03 = src[3];
-		float a12 = src[6], a13 = src[7];
-		float a23 = src[11];
-
-		src[1]  = src[4];
-		src[2]  = src[8];
-		src[3]  = src[12];
-		src[4]  = a01;
-		src[6]  = src[9];
-		src[7]  = src[13];
-		src[8]  = a02;
-		src[9]  = a12;
-		src[11] = src[14];
-		src[12] = a03;
-		src[13] = a13;
-		src[14] = a23;
-		return src;
-	}
-
-	dest[0]  = src[0];
-	dest[1]  = src[4];
-	dest[2]  = src[8];
-	dest[3]  = src[12];
-	dest[4]  = src[1];
-	dest[5]  = src[5];
-	dest[6]  = src[9];
-	dest[7]  = src[13];
-	dest[8]  = src[2];
-	dest[9]  = src[6];
-	dest[10] = src[10];
-	dest[11] = src[14];
-	dest[12] = src[3];
-	dest[13] = src[7];
-	dest[14] = src[11];
-	dest[15] = src[15];
-	return dest;
-
-}
-
-/*
- * mat4.frustum
- * Generates a frustum matrix with the given bounds
- *
- * Params:
- * left, right - scalar, left and right bounds of the frustum
- * bottom, top - scalar, bottom and top bounds of the frustum
- * near, far - scalar, near and far bounds of the frustum
- * dest - Optional, mat4 frustum matrix will be written into
- *
- * Returns:
- * dest if specified, a new mat4 otherwise
- */
-mat4 *mat4_frustum (float left, float right, float bottom,
-                    float top, float near, float far, mat4 *dest) {
-	float rl = (right - left);
-	float tb = (top - bottom);
-	float fn = (far - near);
-	dest[0] = (near*2) / rl;
-	dest[1] = 0;
-	dest[2] = 0;
-	dest[3] = 0;
-	dest[4] = 0;
-	dest[5] = (near*2) / tb;
-	dest[6] = 0;
-	dest[7] = 0;
-	dest[8] = (right + left) / rl;
-	dest[9] = (top + bottom) / tb;
-	dest[10] = -(far + near) / fn;
-	dest[11] = -1;
-	dest[12] = 0;
-	dest[13] = 0;
-	dest[14] = -(far*near*2) / fn;
-	dest[15] = 0;
-	return dest;
-}
-
-/*
- * mat4.translate
- * Translates a matrix by the given vector
- *
- * Params:
- * mat - mat4 to translate
- * vec - vec3 specifying the translation
- * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
- *
- * Returns:
- * dest if specified, mat otherwise
- */
-mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest) {
-	if(!dest || mat == dest) {
-		mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12];
-		mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13];
-		mat[14] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14];
-		mat[15] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15];
-		return mat;
-	}
-
-	float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
-	float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
-	float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
-
-	dest[0] = a00;
-	dest[1] = a01;
-	dest[2] = a02;
-	dest[3] = a03;
-	dest[4] = a10;
-	dest[5] = a11;
-	dest[6] = a12;
-	dest[7] = a13;
-	dest[8] = a20;
-	dest[9] = a21;
-	dest[10] = a22;
-	dest[11] = a23;
-
-	dest[12] = a00*x + a10*y + a20*z + mat[12];
-	dest[13] = a01*x + a11*y + a21*z + mat[13];
-	dest[14] = a02*x + a12*y + a22*z + mat[14];
-	dest[15] = a03*x + a13*y + a23*z + mat[15];
-	return dest;
-}
-
-mat4 *mat4_perspective(float fov, float aspect, float near,
-                       float far, mat4 *dest) {
-	float top = near * tanf(fov*PI / 360.0f);
-	float right = top * aspect;
-	return mat4_frustum(-right, right, -top, top, near, far, dest);
-}
-
-mat4 *mat4_inverse(mat4 *src, mat4 *dest) {
-	if(dest == NULL) { dest = src; }
-
-	// Cache the srcrix values (makes for huge speed increases!)
-	float a00 = src[0], a01  = src[1], a02  = src[2], a03  = src[3];
-	float a10 = src[4], a11  = src[5], a12  = src[6], a13  = src[7];
-	float a20 = src[8], a21  = src[9], a22  = src[10], a23 = src[11];
-	float a30 = src[12], a31 = src[13], a32 = src[14], a33 = src[15];
-
-	float b00 = a00*a11 - a01*a10;
-	float b01 = a00*a12 - a02*a10;
-	float b02 = a00*a13 - a03*a10;
-	float b03 = a01*a12 - a02*a11;
-	float b04 = a01*a13 - a03*a11;
-	float b05 = a02*a13 - a03*a12;
-	float b06 = a20*a31 - a21*a30;
-	float b07 = a20*a32 - a22*a30;
-	float b08 = a20*a33 - a23*a30;
-	float b09 = a21*a32 - a22*a31;
-	float b10 = a21*a33 - a23*a31;
-	float b11 = a22*a33 - a23*a32;
-
-	// Calculate the determinant (inlined to avoid double-caching)
-	float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
-
-	dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet;
-	dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet;
-	dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet;
-	dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet;
-	dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet;
-	dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet;
-	dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet;
-	dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet;
-	dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet;
-	dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet;
-	dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet;
-	dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet;
-	dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet;
-	dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet;
-	dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet;
-	dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet;
-
-	return dest;
-}
-
-
-mat4 *mat4_multiply(const mat4 *a, const mat4 *b, mat4 *dst) {
-  float a00 = a[0],  a01 = a[1],  a02 = a[2],  a03 = a[3];
-  float a10 = a[4],  a11 = a[5],  a12 = a[6],  a13 = a[7];
-  float a20 = a[8],  a21 = a[9],  a22 = a[10], a23 = a[11];
-  float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
-
-  float b00 = b[0],  b01 = b[1],  b02 = b[2],  b03 = b[3];
-  float b10 = b[4],  b11 = b[5],  b12 = b[6],  b13 = b[7];
-  float b20 = b[8],  b21 = b[9],  b22 = b[10], b23 = b[11];
-  float b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15];
-
-  dst[0]  = b00*a00 + b01*a10 + b02*a20 + b03*a30;
-  dst[1]  = b00*a01 + b01*a11 + b02*a21 + b03*a31;
-  dst[2]  = b00*a02 + b01*a12 + b02*a22 + b03*a32;
-  dst[3]  = b00*a03 + b01*a13 + b02*a23 + b03*a33;
-  dst[4]  = b10*a00 + b11*a10 + b12*a20 + b13*a30;
-  dst[5]  = b10*a01 + b11*a11 + b12*a21 + b13*a31;
-  dst[6]  = b10*a02 + b11*a12 + b12*a22 + b13*a32;
-  dst[7]  = b10*a03 + b11*a13 + b12*a23 + b13*a33;
-  dst[8]  = b20*a00 + b21*a10 + b22*a20 + b23*a30;
-  dst[9]  = b20*a01 + b21*a11 + b22*a21 + b23*a31;
-  dst[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32;
-  dst[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33;
-  dst[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30;
-  dst[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31;
-  dst[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32;
-  dst[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33;
-
-  return dst;
-}
-
-// TODO: util me
-int float_eq(float a, float b);
-int float_eq(float a, float b) {
-  return fabsf(a - b) < 0.0001;
-}
-
-
-mat4 *mat4_rotate(const mat4 *mat, const float angle,
-                  const float *axis, mat4 *dest) {
-  float x = axis[0], y = axis[1], z = axis[2];
-  float len = (float)sqrt(x*x + y*y + z*z);
-
-  if (float_eq(len, 0.)) { return NULL; }
-  // TODO: float comparison tool
-  if (!float_eq(len, 1.)) {
-    len = 1 / len;
-    x *= len;
-    y *= len;
-    z *= len;
-  }
-
-  float s = (float)sin(angle);
-  float c = (float)cos(angle);
-  float t = 1-c;
-
-  // Cache the matrix values (makes for huge speed increases!)
-  float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03  = mat[3];
-  float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13  = mat[7];
-  float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
-
-  // Construct the elements of the rotation matrix
-  float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
-  float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
-  float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
-
-  // If the source and destination differ, copy the unchanged last row
-  if(mat != dest) {
-    dest[12] = mat[12];
-    dest[13] = mat[13];
-    dest[14] = mat[14];
-    dest[15] = mat[15];
-  }
-
-  // Perform rotation-specific matrix multiplication
-  dest[0] = a00*b00 + a10*b01 + a20*b02;
-  dest[1] = a01*b00 + a11*b01 + a21*b02;
-  dest[2] = a02*b00 + a12*b01 + a22*b02;
-  dest[3] = a03*b00 + a13*b01 + a23*b02;
-
-  dest[4] = a00*b10 + a10*b11 + a20*b12;
-  dest[5] = a01*b10 + a11*b11 + a21*b12;
-  dest[6] = a02*b10 + a12*b11 + a22*b12;
-  dest[7] = a03*b10 + a13*b11 + a23*b12;
-
-  dest[8] = a00*b20 + a10*b21 + a20*b22;
-  dest[9] = a01*b20 + a11*b21 + a21*b22;
-  dest[10] = a02*b20 + a12*b21 + a22*b22;
-  dest[11] = a03*b20 + a13*b21 + a23*b22;
-
-  return dest;
-}
-
-mat4 *mat4_scale(mat4 *a, float v[3], mat4 *out) {
-  float x = v[0], y = v[1], z = v[2];
-
-  out[0] = a[0] * x;
-  out[1] = a[1] * x;
-  out[2] = a[2] * x;
-  out[3] = a[3] * x;
-  out[4] = a[4] * y;
-  out[5] = a[5] * y;
-  out[6] = a[6] * y;
-  out[7] = a[7] * y;
-  out[8] = a[8] * z;
-  out[9] = a[9] * z;
-  out[10] = a[10] * z;
-  out[11] = a[11] * z;
-  out[12] = a[12];
-  out[13] = a[13];
-  out[14] = a[14];
-  out[15] = a[15];
-  return out;
-};
-
-
-void mat4_print(const mat4 *m) {
-  for (int i = 0; i < 16; ++i) {
-    if (i % 4 == 0)
-      printf("\n");
-    printf("%f, ", m[i]);
-  }
-  printf("\n");
-}
diff --git a/src/noise.c b/src/noise.c
diff --git a/src/terrain.c b/src/terrain.c
@@ -19,9 +19,8 @@ static const u32 plane_indices[] = {
 };
 
 
-double old_noisy_boi(void *data, double x, double y) {
+double old_noisy_boi(struct terrain *t, double x, double y) {
   /* return cos(x/10.0) * sin(y/10.0) * 20.0; */
-  struct terrain *t = (struct terrain*)data;
   struct perlin_settings *s = &t->settings;
   x *= s->scale;
   y *= s->scale;
@@ -45,6 +44,13 @@ void
 terrain_init(struct terrain *terrain) {
 }
 
+double offset_fn(struct terrain* terrain, double x, double y) {
+  struct perlin_settings *perlin = &terrain->settings;
+  double ox = perlin->ox * (1/perlin->scale);
+  double oy = perlin->oy * (1/perlin->scale);
+  return old_noisy_boi(terrain, ox+x, oy+y);
+}
+
 void
 terrain_create(struct terrain *terrain) {
   u32 i;
@@ -53,12 +59,10 @@ terrain_create(struct terrain *terrain) {
   float tmp1[3], tmp2[3];
   assert(terrain->n_samples > 0);
   del_point2d_t *points = calloc(terrain->n_samples, sizeof(*points));
-  struct perlin_settings *perlin = &terrain->settings;
 
   float *verts = calloc(terrain->n_samples * 3, sizeof(*verts));
 
-  double ox = perlin->ox * (1/perlin->scale);
-  double oy = perlin->oy * (1/perlin->scale);
+  terrain->fn = offset_fn;
 
   // 100 random samples from our noise function
   for (i = 0; i < (u32)terrain->n_samples; i++) {
@@ -68,7 +72,7 @@ terrain_create(struct terrain *terrain) {
     x = terrain->samples[i].x;
     y = terrain->samples[i].y;
 
-    double z = old_noisy_boi((void*)terrain, ox+x, oy+y);
+    double z = terrain->fn(terrain, x, y);
 
     points[i].x = x;
     points[i].y = y;
diff --git a/src/terrain.h b/src/terrain.h
@@ -18,14 +18,18 @@ struct perlin_settings {
   double exp;
 };
 
+
 struct terrain {
   struct geometry geom;
   struct perlin_settings settings;
   struct point *samples;
+  double (*fn)(struct terrain *, double, double);
   int n_samples;
   double size;
 };
 
+double old_noisy_boi(struct terrain *, double x, double y);
+
 void terrain_init(struct terrain *terrain);
 void terrain_create(struct terrain *terrain);
 void terrain_destroy(struct terrain *terrain);
diff --git a/src/update.c b/src/update.c
@@ -70,10 +70,18 @@ void update (struct game *game, u32 dt) {
 
   if (game->input.modifiers & KMOD_LALT) {
     movement(game, res->camera);
-    mat4_loo
+    /* mat4_multiply(res->player, res->ca era, res->player); */
   }
-  else {
+  if (game->input.modifiers & KMOD_LCTRL) {
     movement(game, res->terrain_node);
+    /* mat4_multiply(res->player, res->ca era, res->player); */
+  }
+  else {
+    movement(game, res->player);
+    res->player[14] =
+      game->terrain->fn(game->terrain, res->player[M_X], res->player[M_Y]) +
+        PLAYER_HEIGHT;
+    camera_follow(camera, player);
     /* movement(game, res->camera); */
   }
 
diff --git a/src/util.c b/src/util.c
@@ -1,6 +1,6 @@
 
 #include "util.h"
-#include "vec3.h"
+#include "vec3/vec3.h"
 #include <stdlib.h>
 
 int clampi(int a, int mina, int maxa) {
@@ -44,45 +44,10 @@ double rand_0to1() {
   return (double) rand() / RAND_MAX;
 }
 
-void glhLookAtf2( float *matrix, float *eyePosition3D,
-                  float *center3D, float *upVector3D )
-{
-   float forward[3], side[3], up[3];
-   float matrix2[16], resultMatrix[16];
-   // --------------------
-   forward[0] = center3D[0] - eyePosition3D[0];
-   forward[1] = center3D[1] - eyePosition3D[1];
-   forward[2] = center3D[2] - eyePosition3D[2];
-   vec3_normalize(forward, forward);
-   // --------------------
-   // Side = forward x up
-   ComputeNormalOfPlane(side, forward, upVector3D);
-   NormalizeVector(side);
-   --------------------
-   // Recompute up as: up = side x forward
-   ComputeNormalOfPlane(up, side, forward);
-   // --------------------
-   matrix2[0] = side[0];
-   matrix2[4] = side[1];
-   matrix2[8] = side[2];
-   matrix2[12] = 0.0;
-   // --------------------
-   matrix2[1] = up[0];
-   matrix2[5] = up[1];
-   matrix2[9] = up[2];
-   matrix2[13] = 0.0;
-   // --------------------
-   matrix2[2] = -forward[0];
-   matrix2[6] = -forward[1];
-   matrix2[10] = -forward[2];
-   matrix2[14] = 0.0;
-   // --------------------
-   matrix2[3] = matrix2[7] = matrix2[11] = 0.0;
-   matrix2[15] = 1.0;
-   // --------------------
-   MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2);
-   glhTranslatef2(resultMatrix,
-                  -eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]);
-   // --------------------
-   memcpy(matrix, resultMatrix, 16*sizeof(float));
+mat4 *look_at(vec3 *eye, vec3 *target, vec3 *up) {
+  float[3] z;
+  vec3_subtract(eye, target, z);
+  if (vec3_lengthsq(z) == 0)
+    z[V_Z] = 0;
 }
+
diff --git a/src/util.h b/src/util.h
@@ -12,6 +12,7 @@ int clampi(int a, int mina, int maxa);
 double clamp(double a, double mina, double maxa);
 double max(double a, double b);
 double min(double a, double b);
+mat4 *look_at(vec3 *eye, vec3 *target, vec3 *up);
 
 double rand_0to1();
 
diff --git a/src/vec3.c b/src/vec3.c
@@ -0,0 +1,209 @@
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "mat4/mat4.h"
+#include "vec3.h"
+
+vec3 *vec3_create(vec3 *vec) {
+    vec3 *dest = calloc(sizeof(float_t), 3);
+
+    if (vec) {
+        dest[0] = vec[0];
+        dest[1] = vec[1];
+        dest[2] = vec[2];
+    } else {
+        dest[0] = dest[1] = dest[2] = 0;
+    }
+
+    return dest;
+}
+
+vec3 *vec3_set(vec3 *vec, vec3 *dest) {
+    dest[0] = vec[0];
+    dest[1] = vec[1];
+    dest[2] = vec[2];
+
+    return dest;
+}
+
+vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest) {
+    if (!dest || vec == dest) {
+        vec[0] += vec2[0];
+        vec[1] += vec2[1];
+        vec[2] += vec2[2];
+        return vec;
+    }
+
+    dest[0] = vec[0] + vec2[0];
+    dest[1] = vec[1] + vec2[1];
+    dest[2] = vec[2] + vec2[2];
+
+    return dest;
+}
+
+vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest) {
+    if (!dest || vec == dest) {
+        vec[0] -= vec2[0];
+        vec[1] -= vec2[1];
+        vec[2] -= vec2[2];
+        return vec;
+    }
+
+    dest[0] = vec[0] - vec2[0];
+    dest[1] = vec[1] - vec2[1];
+    dest[2] = vec[2] - vec2[2];
+    return dest;
+}
+
+vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest) {
+    if (!dest || vec == dest) {
+        vec[0] *= vec2[0];
+        vec[1] *= vec2[1];
+        vec[2] *= vec2[2];
+        return vec;
+    }
+
+    dest[0] = vec[0] * vec2[0];
+    dest[1] = vec[1] * vec2[1];
+    dest[2] = vec[2] * vec2[2];
+    return dest;
+}
+
+vec3 *vec3_negate(vec3 *vec, vec3 *dest) {
+    if (!dest) { dest = vec; }
+
+    dest[0] = -vec[0];
+    dest[1] = -vec[1];
+    dest[2] = -vec[2];
+    return dest;
+}
+
+vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest) {
+    if (!dest || vec == dest) {
+        vec[0] *= val;
+        vec[1] *= val;
+        vec[2] *= val;
+        return vec;
+    }
+
+    dest[0] = vec[0] * val;
+    dest[1] = vec[1] * val;
+    dest[2] = vec[2] * val;
+    return dest;
+}
+
+vec3 *vec3_normalize(vec3 *vec, vec3 *dest) {
+    if (!dest) { dest = vec; }
+
+    float x = vec[0], y = vec[1], z = vec[2],
+        len = sqrt(x * x + y * y + z * z);
+
+    if (!len) {
+        dest[0] = 0;
+        dest[1] = 0;
+        dest[2] = 0;
+        return dest;
+    } else if (len == 1) {
+        dest[0] = x;
+        dest[1] = y;
+        dest[2] = z;
+        return dest;
+    }
+
+    len = 1 / len;
+    dest[0] = x * len;
+    dest[1] = y * len;
+    dest[2] = z * len;
+    return dest;
+}
+
+vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest) {
+    if (!dest) { dest = vec; }
+
+    float x = vec[0], y = vec[1], z = vec[2],
+        x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];
+
+    dest[0] = y * z2 - z * y2;
+    dest[1] = z * x2 - x * z2;
+    dest[2] = x * y2 - y * x2;
+    return dest;
+}
+
+float vec3_length(vec3 *vec) {
+    float x = vec[0], y = vec[1], z = vec[2];
+    return sqrt(x * x + y * y + z * z);
+}
+
+float vec3_dot(vec3 *vec, vec3 *vec2) {
+    return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2];
+}
+
+vec3 *vec3_direction (vec3 *vec, vec3 *vec2, vec3 *dest) {
+    if (!dest) { dest = vec; }
+
+    float x = vec[0] - vec2[0],
+        y = vec[1] - vec2[1],
+        z = vec[2] - vec2[2],
+        len = sqrt(x * x + y * y + z * z);
+
+    if (!len) {
+        dest[0] = 0;
+        dest[1] = 0;
+        dest[2] = 0;
+        return dest;
+    }
+
+    len = 1 / len;
+    dest[0] = x * len;
+    dest[1] = y * len;
+    dest[2] = z * len;
+    return dest;
+}
+
+vec3 *vec3_lerp(vec3 *vec, vec3 *vec2, float lerp, vec3 *dest) {
+    if (!dest) { dest = vec; }
+
+    dest[0] = vec[0] + lerp * (vec2[0] - vec[0]);
+    dest[1] = vec[1] + lerp * (vec2[1] - vec[1]);
+    dest[2] = vec[2] + lerp * (vec2[2] - vec[2]);
+
+    return dest;
+}
+
+float vec3_lengthsq(vec3 *vec, vec3 *vec) {
+  float x = vec2[0] - vec[0],
+        y = vec2[1] - vec[1],
+        z = vec2[2] - vec[2];
+
+  return x*x + y*y + z*z;
+}
+
+
+float vec3_length(vec3 *vec, vec3 *vec2) {
+  return sqrt(vec3_lengthsq(vec, vec2));
+}
+
+/* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */
+/*     if (!dest) { dest = vec; } */
+
+/*     mat4 m = mat4_create(NULL); */
+/*     float *v = malloc(sizeof(float) * 4); */
+
+/*     v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0; */
+/*     v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0; */
+/*     v[2] = 2.0 * vec[2] - 1.0; */
+/*     v[3] = 1.0; */
+
+/*     mat4_multiply(proj, view, m); */
+/*     if(!mat4_inverse(m, NULL)) { return NULL; } */
+
+/*     mat4_multiplyVec4(m, v, NULL); */
+/*     if(v[3] == 0.0) { return NULL; } */
+
+/*     dest[0] = v[0] / v[3]; */
+/*     dest[1] = v[1] / v[3]; */
+/*     dest[2] = v[2] / v[3]; */
+
+/*     return dest; */
+/* } */
diff --git a/src/vec3.h b/src/vec3.h
@@ -0,0 +1,16 @@
+typedef float vec3;
+
+#define V3(x,y,z) ((vec3[3]){x,y,z})
+#define V_X 0
+#define V_Y 1
+#define V_Z 2
+
+vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest);
+vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest);
+vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest);
+vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest);
+vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest);
+vec3 *vec3_normalize(vec3 *vec, vec3 *dest);
+vec3 *vec3_length(vec3 *vec, vec3 *dest);
+vec3 *vec3_lengthsq(vec3 *vec, vec3 *dest);
+
diff --git a/src/vec3/vec3.c b/src/vec3/vec3.c
@@ -1,204 +0,0 @@
-
-#include <stdlib.h>
-#include <math.h>
-
-#include "mat4/mat4.h"
-#include "vec3.h"
-
-vec3 *vec3_create(vec3 *vec) {
-    vec3 *dest = calloc(sizeof(double_t), 3);
-
-    if (vec) {
-        dest[0] = vec[0];
-        dest[1] = vec[1];
-        dest[2] = vec[2];
-    } else {
-        dest[0] = dest[1] = dest[2] = 0;
-    }
-
-    return dest;
-}
-
-vec3 *vec3_set(vec3 *vec, vec3 *dest) {
-    dest[0] = vec[0];
-    dest[1] = vec[1];
-    dest[2] = vec[2];
-
-    return dest;
-}
-
-vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest) {
-    if (!dest || vec == dest) {
-        vec[0] += vec2[0];
-        vec[1] += vec2[1];
-        vec[2] += vec2[2];
-        return vec;
-    }
-
-    dest[0] = vec[0] + vec2[0];
-    dest[1] = vec[1] + vec2[1];
-    dest[2] = vec[2] + vec2[2];
-
-    return dest;
-}
-
-vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest) {
-    if (!dest || vec == dest) {
-        vec[0] -= vec2[0];
-        vec[1] -= vec2[1];
-        vec[2] -= vec2[2];
-        return vec;
-    }
-
-    dest[0] = vec[0] - vec2[0];
-    dest[1] = vec[1] - vec2[1];
-    dest[2] = vec[2] - vec2[2];
-    return dest;
-}
-
-vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest) {
-    if (!dest || vec == dest) {
-        vec[0] *= vec2[0];
-        vec[1] *= vec2[1];
-        vec[2] *= vec2[2];
-        return vec;
-    }
-
-    dest[0] = vec[0] * vec2[0];
-    dest[1] = vec[1] * vec2[1];
-    dest[2] = vec[2] * vec2[2];
-    return dest;
-}
-
-vec3 *vec3_negate(vec3 *vec, vec3 *dest) {
-    if (!dest) { dest = vec; }
-
-    dest[0] = -vec[0];
-    dest[1] = -vec[1];
-    dest[2] = -vec[2];
-    return dest;
-}
-
-vec3 *vec3_scale(vec3 *vec, double val, vec3 *dest) {
-    if (!dest || vec == dest) {
-        vec[0] *= val;
-        vec[1] *= val;
-        vec[2] *= val;
-        return vec;
-    }
-
-    dest[0] = vec[0] * val;
-    dest[1] = vec[1] * val;
-    dest[2] = vec[2] * val;
-    return dest;
-}
-
-vec3 *vec3_normalize(vec3 *vec, vec3 *dest) {
-    if (!dest) { dest = vec; }
-
-    double x = vec[0], y = vec[1], z = vec[2],
-        len = sqrt(x * x + y * y + z * z);
-
-    if (!len) {
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-        return dest;
-    } else if (len == 1) {
-        dest[0] = x;
-        dest[1] = y;
-        dest[2] = z;
-        return dest;
-    }
-
-    len = 1 / len;
-    dest[0] = x * len;
-    dest[1] = y * len;
-    dest[2] = z * len;
-    return dest;
-}
-
-vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest) {
-    if (!dest) { dest = vec; }
-
-    double x = vec[0], y = vec[1], z = vec[2],
-        x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];
-
-    dest[0] = y * z2 - z * y2;
-    dest[1] = z * x2 - x * z2;
-    dest[2] = x * y2 - y * x2;
-    return dest;
-}
-
-double vec3_length(vec3 *vec) {
-    double x = vec[0], y = vec[1], z = vec[2];
-    return sqrt(x * x + y * y + z * z);
-}
-
-double vec3_dot(vec3 *vec, vec3 *vec2) {
-    return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2];
-}
-
-vec3 *vec3_direction (vec3 *vec, vec3 *vec2, vec3 *dest) {
-    if (!dest) { dest = vec; }
-
-    double x = vec[0] - vec2[0],
-        y = vec[1] - vec2[1],
-        z = vec[2] - vec2[2],
-        len = sqrt(x * x + y * y + z * z);
-
-    if (!len) {
-        dest[0] = 0;
-        dest[1] = 0;
-        dest[2] = 0;
-        return dest;
-    }
-
-    len = 1 / len;
-    dest[0] = x * len;
-    dest[1] = y * len;
-    dest[2] = z * len;
-    return dest;
-}
-
-vec3 *vec3_lerp(vec3 *vec, vec3 *vec2, double lerp, vec3 *dest) {
-    if (!dest) { dest = vec; }
-
-    dest[0] = vec[0] + lerp * (vec2[0] - vec[0]);
-    dest[1] = vec[1] + lerp * (vec2[1] - vec[1]);
-    dest[2] = vec[2] + lerp * (vec2[2] - vec[2]);
-
-    return dest;
-}
-
-double vec3_dist(vec3 *vec, vec3 *vec2) {
-    double x = vec2[0] - vec[0],
-        y = vec2[1] - vec[1],
-        z = vec2[2] - vec[2];
-
-    return sqrt(x*x + y*y + z*z);
-}
-
-/* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */
-/*     if (!dest) { dest = vec; } */
-
-/*     mat4 m = mat4_create(NULL); */
-/*     double *v = malloc(sizeof(double) * 4); */
-
-/*     v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0; */
-/*     v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0; */
-/*     v[2] = 2.0 * vec[2] - 1.0; */
-/*     v[3] = 1.0; */
-
-/*     mat4_multiply(proj, view, m); */
-/*     if(!mat4_inverse(m, NULL)) { return NULL; } */
-
-/*     mat4_multiplyVec4(m, v, NULL); */
-/*     if(v[3] == 0.0) { return NULL; } */
-
-/*     dest[0] = v[0] / v[3]; */
-/*     dest[1] = v[1] / v[3]; */
-/*     dest[2] = v[2] / v[3]; */
-
-/*     return dest; */
-/* } */
diff --git a/src/vec3/vec3.h b/src/vec3/vec3.h
@@ -1,11 +0,0 @@
-typedef float vec3;
-
-#define V3(x,y,z) ((float[3]){x,y,z})
-
-vec3 *vec3_scale(vec3 *vec, double val, vec3 *dest);
-vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest);
-vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest);
-vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest);
-vec3 *vec3_scale(vec3 *vec, double val, vec3 *dest);
-vec3 *vec3_normalize(vec3 *vec, vec3 *dest);
-
diff --git a/src/window.c b/src/window.c
@@ -9,7 +9,7 @@ void
 handle_resize(float *camera, int width, int height) {
   printf("resizing %d %d\n", width, height);
   glViewport( 0, 0, width, height );
-  mat4_perspective(90 /* fov */, (float)width / height, 1, 1000, camera);
+  mat4_perspective(100 /* fov */, (float)width / height, 1, 1000, camera);
 
   /* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */
   /* Set the camera perspective */