Reworked camera
authormatthew <matthew@owens.tech>
Sat, 3 Nov 2018 16:21:43 +0000 (16:21 +0000)
committermatthew <matthew@owens.tech>
Sat, 3 Nov 2018 16:21:43 +0000 (16:21 +0000)
gl/camera.c
gl/camera.h

index 980c143..fc6c456 100644 (file)
@@ -1,50 +1,98 @@
-#include "camera.h"
-#include <math.h>
 #include <stdlib.h>
+#include <math.h>
+#include "camera.h"
 #include "input.h"
 
-static vec3_t worldSpaceVec;
-static float aspectRatio = 16.f/9.f;   // sane default for the aspect ratio
+static const float YAW                 = -90.f;
+static const float PITCH               = 0.0f;
+static const float SPEED               = 2.5f;
+static const float SENSITIVITY = 0.1f;
+static const float ZOOM                        = 45.0f;
 
 typedef struct
 {
-       vec3_t from, to, up;
-       mat4_t camera, perspective, worldToScreen;
-       float speed;
+       vec3_t position;
+       vec3_t front;
+       vec3_t up;
+       vec3_t right;
+       vec3_t worldUp;
+
+       /* euler angles */
+       float yaw;
+       float pitch;
+
+       /* camera options */
+       float movementSpeed;
+       float mouseSensitivity;
+       float zoom;
+       float aspectRatio;
+       float near;
+       float far;
+
+       /* storing the final matrix to prevent multiple calculations/frame */
+       mat4_t matrix;
+} crpgCamera_t;
+
+double toRadians(double degrees)
+{
+       return degrees * (M_PI / 180.f);
+}
 
-       // Axis' to manouver across. If 0, no movement is occuring
-       vec3_t pan, yaw, roll;
-} Camera_t;
+double toDegrees(double radians)
+{
+       return radians * (180.f / M_PI);
+}
 
-///TODO: figure out why this is failing
-mat4_t recalcPerspective(float hFovDeg, float near, float far)
+void updateMatrix(crpgCamera_t *ct)
 {
-       float vFovDeg = 2 * atan( tan(hFovDeg/2) * aspectRatio );
-       float vFovRad = vFovDeg * (M_PI/180.f);
+       vec3_t to = v3_add(ct->position, ct->front);
 
-       return m4_perspective(vFovRad, aspectRatio, near, far);
+       mat4_t lookat = m4_look_at(ct->position, to, ct->up);
+       mat4_t perspective = m4_perspective(60, ct->aspectRatio, ct->near, ct->far);
+       ct->matrix = m4_mul(perspective, lookat);
 }
 
-void crpgCameraSetAR(float ar)
+void updateVectors(crpgCamera_t *ct)
 {
-       aspectRatio = ar;
+       /* calculate the new front vector */
+       ct->front.x = cos(toRadians(ct->yaw)) * cos(toRadians(ct->pitch));
+       ct->front.y = sin(toRadians(ct->pitch));
+       ct->front.z = sin(toRadians(ct->yaw)) * cos(toRadians(ct->pitch));
+       ct->front = v3_norm(ct->front);
+
+       /* calculating the new right and up vectors */
+       ct->right = v3_norm(v3_cross(ct->position, ct->worldUp));
+       ct->up = v3_norm(v3_cross(ct->right, ct->front));
 }
 
-crpgCamera *crpgCameraNew(vec3_t from, vec3_t to, vec3_t up)
+mat4_t *crpgCameraGetMat(crpgCamera *c)
 {
-       // 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);
-       ct->speed = 1.0f;
+       crpgCamera_t *ct = (crpgCamera_t *)c;
+       updateMatrix(ct);
+       return &(ct->matrix);
+}
 
-       crpgCamera *c = (crpgCamera *) ct;
+crpgCamera *crpgCameraNew(vec3_t position, vec3_t up)
+{
+       crpgCamera_t *ct = malloc(sizeof(crpgCamera_t));
+       ct->position = position;
+       ct->up = up;
+       ct->worldUp = vec3(0,1,0);
+
+       /* using some sane defaults */
+       ct->front = vec3(0.0f, 0.0f, -1.0f);
+       ct->yaw = YAW;
+       ct->pitch = PITCH;
+       ct->zoom = ZOOM;
+       ct->movementSpeed = SPEED;
+       ct->mouseSensitivity = SENSITIVITY;
+       ct->aspectRatio = 16.f/9.f;
+       ct->near = 1.f;
+       ct->far = 10.f;
+
+       updateVectors(ct);
+
+       crpgCamera *c = (crpgCamera *)ct;
        return c;
 }
 
@@ -57,74 +105,39 @@ void crpgCameraFree(crpgCamera *c)
        }
 }
 
-void crpgCameraSetSpeed(crpgCamera *c, float speedPerSecond)
+void crpgCameraSetZoom(crpgCamera *c, float zoom)
 {
-       if(c == NULL) return;
-
-       Camera_t *ct = (Camera_t *) c;
-       ct->speed = speedPerSecond;
+       crpgCamera_t *ct = (crpgCamera_t *)c;
+       ct->zoom = zoom;
 }
 
-// This function expects a vec3_t formatted with values of 1, 0 or -1.
-// to represent if the axis should be panned across and the direction
-void crpgCameraPan(crpgCamera *c, vec3_t panAxis)
+void crpgCameraSetSpeed(crpgCamera *c, float speed)
 {
-       if(c == NULL)
-               return;
-
-       Camera_t *ct = (Camera_t *) c;
-       ct->pan = panAxis;
-
+       crpgCamera_t *ct = (crpgCamera_t *)c;
+       ct->movementSpeed = speed;
 }
 
-mat4_t *crpgCameraGetMat(crpgCamera *c)
+void crpgCameraSetSensitivity(crpgCamera *c, float sensitivity)
 {
-       Camera_t *ct = (Camera_t *)c;
-       return &(ct->worldToScreen);
+       crpgCamera_t *ct = (crpgCamera_t *)c;
+       ct->mouseSensitivity = sensitivity;
 }
 
-// expecting components as {from, to, up}
-void updatePan(vec3_t panAxis, vec3_t *components[3], float speed, float dtms)
+void crpgCameraRender(crpgCamera *c, float dtms)
 {
-       int axis[] = { panAxis.x, panAxis.y, panAxis.z };
-       float* fromArr[] = { &components[0]->x, &components[0]->y, &components[0]->z };
-       float* toArr[] = { &components[1]->x, &components[1]->y, &components[1]->z };
-
-       for(int i = 0; i < 3; ++i){
-               if(axis[i] != 0){       // if we should pan on this axis
-                       int sign = 0;
-                       sign = (axis[i] > 0) ? 1 : -1;
-                       *fromArr[i] += sign * (speed/1000.f);
-                       *toArr[i] += sign * (speed/1000.f);
-               }
-       }
 }
 
-void crpgCameraUpdate(crpgCamera *c)
+void crpgCameraUpdate(crpgCamera *c, float dtms)
 {
-       vec3_t panAxis = (vec3_t){0.f,0.f,0.f};
+       /*
+       crpgCamera_t *ct = (crpgCamera_t *)c;
+       float velocity = ct->movementSpeed * dtms;
 
-       panAxis.x = crpgInputHeld(INPUT_CAMERA_PAN_RIGHT) ? 1 : 0;
-       panAxis.x = crpgInputHeld(INPUT_CAMERA_PAN_LEFT) ? -1 : panAxis.x;
-
-       panAxis.y = crpgInputHeld(INPUT_CAMERA_PAN_UP) ? 1 : 0;
-       panAxis.y = crpgInputHeld(INPUT_CAMERA_PAN_DOWN) ? -1 : panAxis.y;
-
-       panAxis.z = crpgInputHeld(INPUT_CAMERA_PAN_IN) ? 1 : 0;
-       panAxis.z = crpgInputHeld(INPUT_CAMERA_PAN_OUT) ? -1 : panAxis.z;
-
-       Camera_t *ct = (Camera_t *)c;
-       ct->pan = panAxis;
-}
-
-void crpgCameraRender(crpgCamera *c, float dtms)
-{
-       Camera_t *ct = (Camera_t *)c;
-       vec3_t *components[] = { &(ct->from), &(ct->to), &(ct->up) };
-
-       updatePan(ct->pan, components, ct->speed, dtms);
-
-       // recalc camera matrices
-       ct->camera = m4_look_at(ct->from, ct->to, ct->up);
-       ct->worldToScreen = m4_mul(ct->perspective, ct->camera);
+       if(crpgInputHeld(INPUT_CAMERA_PAN_IN)){
+               ct->position = v3_add(ct->position, v3_muls(ct->front, velocity));
+       }
+       if(crpgInputHeld(INPUT_CAMERA_PAN_OUT)){
+               ct->position = v3_sub(ct->position, v3_muls(ct->front, velocity));
+       }
+       */
 }
index 030cc82..fbede13 100644 (file)
@@ -1,15 +1,16 @@
 #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);
+crpgCamera *crpgCameraNew(vec3_t position, vec3_t up);
 void crpgCameraFree(crpgCamera *c);
-void crpgCameraPan(crpgCamera *c, vec3_t panAxis);
-void crpgCameraSetAR(float ar);
 mat4_t *crpgCameraGetMat(crpgCamera *c);
-void crpgCameraSetSpeed(crpgCamera *c, float speedPerSecond);
+void crpgCameraSetZoom(crpgCamera *c, float zoom);
+void crpgCameraSetSpeed(crpgCamera *c, float speed);
+void crpgCameraSetSensitivity(crpgCamera *c, float sensitivity);
+
 void crpgCameraRender(crpgCamera *c, float dtms);
-void crpgCameraUpdate(crpgCamera *c);
+void crpgCameraUpdate(crpgCamera *c, float dtms);
 #endif//CAMERA_H