commit c390e429cf5a91ab3c0361e1136a3371f4175247
parent 24b64e7c7a2da19bacc8182032629da42299a463
Author: Christian Ermann <christianermann@gmail.com>
Date: Fri, 19 Nov 2021 14:55:23 -0800
Implemented vector and matrix operations
Diffstat:
M | include/camera.h | | | 15 | ++++++++------- |
M | include/vec.h | | | 36 | ++++++++++++++++++++++++++++++++++++ |
M | src/camera.c | | | 61 | ++++++++++++++++++++++++++++++------------------------------- |
M | src/vec.c | | | 156 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 230 insertions(+), 38 deletions(-)
diff --git a/include/camera.h b/include/camera.h
@@ -1,14 +1,14 @@
#ifndef CAMERA_H
#define CAMERA_H
-#include <cglm/cglm.h>
+#include "vec.h"
typedef struct {
- vec3 position;
+ Vec3 position;
float yaw;
float pitch;
- vec3 world_up;
+ Vec3 world_up;
float fovy;
float aspect;
float near;
@@ -16,11 +16,11 @@ typedef struct {
float speed;
float sensitivity;
- vec3 front;
- vec3 up;
- vec3 right;
+ Vec3 front;
+ Vec3 up;
+ Vec3 right;
- mat4 matrix;
+ Mat4 matrix;
} Camera;
Camera *Camera_make(float x, float y, float z, float yaw, float pitch);
@@ -37,6 +37,7 @@ void Camera_updateVectors(Camera* camera);
// Update the (projection * view) matrix of the camera.
void Camera_updateMatrix(Camera* camera);
+// Process user input to adjust camera's position and orientation
void Camera_move(Camera *camera);
#endif
diff --git a/include/vec.h b/include/vec.h
@@ -3,11 +3,47 @@
#include <stdbool.h>
+float radians(float degrees);
+
typedef int IVec3[3];
bool IVec3_equal(const IVec3 a, const IVec3 b);
typedef float Vec3[3];
+
+// dst = src * scale
+void Vec3_scale(Vec3 src, float scale, Vec3 dst);
+
+// dst = src_a + src_b
+void Vec3_add(Vec3 src_a, Vec3 src_b, Vec3 dst);
+
+// dst = src_a - src_b
+void Vec3_sub(Vec3 src_a, Vec3 src_b, Vec3 dst);
+
+// dst = src_a x src_b
+void Vec3_mul(Vec3 src_a, Vec3 src_b, Vec3 dst);
+
+// dst = src / ||src||
+void Vec3_normalize(Vec3 src, Vec3 dst);
+
+// src_a * src_b
+float Vec3_dot(Vec3 src_a, Vec3 src_b);
+
+// ||src||^2
+float Vec3_magSquared(Vec3 src);
+
+// ||src||
+float Vec3_mag(Vec3 src);
+
typedef float Mat4[4][4];
+// dst = src_a * src_b
+void Mat4_mul(Mat4 src_a, Mat4 src_b, Mat4 dst);
+
+// Computes the view matrix.
+void Mat4_lookAt(Vec3 camera, Vec3 target, Vec3 up, Mat4 dst);
+
+// Computes the perspective projection matrix.
+void Mat4_perspective(float fov, float aspect, float near, float far, Mat4 dst);
+
#endif
diff --git a/src/camera.c b/src/camera.c
@@ -48,52 +48,52 @@ void Camera_updateRotation(Camera* camera, float dx, float dy)
void Camera_updatePosition(Camera* camera, float x, float y, float z)
{
- vec3 movement_x;
- glm_vec3_scale(camera->right, x, movement_x);
+ Vec3 movement_x;
+ Vec3_scale(camera->right, x, movement_x);
- vec3 movement_y;
- glm_vec3_scale(camera->up, y, movement_y);
+ Vec3 movement_y;
+ Vec3_scale(camera->up, y, movement_y);
- vec3 movement_z;
- glm_vec3_scale(camera->front, z, movement_z);
+ Vec3 movement_z;
+ Vec3_scale(camera->front, z, movement_z);
- vec3 movement;
- glm_vec3_add(movement_x, movement_y, movement);
- glm_vec3_add(movement_z, movement, movement);
- glm_vec3_normalize(movement);
- glm_vec3_scale(movement, 0.1f, movement);
+ Vec3 movement;
+ Vec3_add(movement_x, movement_y, movement);
+ Vec3_add(movement_z, movement, movement);
+ Vec3_normalize(movement, movement);
+ Vec3_scale(movement, 0.1f, movement);
- glm_vec3_add(camera->position, movement, camera->position);
+ Vec3_add(camera->position, movement, camera->position);
}
void Camera_updateVectors(Camera* camera)
{
- vec3 front;
- front[0] = cosf(glm_rad(camera->yaw)) * cosf(glm_rad(camera->pitch));
- front[1] = sinf(glm_rad(camera->pitch));
- front[2] = sinf(glm_rad(camera->yaw)) * cosf(glm_rad(camera->pitch));
- glm_vec3_normalize_to(front, camera->front);
+ Vec3 front;
+ front[0] = cosf(radians(camera->yaw)) * cosf(radians(camera->pitch));
+ front[1] = sinf(radians(camera->pitch));
+ front[2] = sinf(radians(camera->yaw)) * cosf(radians(camera->pitch));
+ Vec3_normalize(front, camera->front);
- glm_vec3_cross(camera->front, camera->world_up, camera->right);
- glm_vec3_normalize(camera->right);
+ Vec3_mul(camera->front, camera->world_up, camera->right);
+ Vec3_normalize(camera->right, camera->right);
- glm_vec3_cross(camera->right, camera->front, camera->up);
- glm_vec3_normalize(camera->up);
+ Vec3_mul(camera->right, camera->front, camera->up);
+ Vec3_normalize(camera->up, camera->up);
}
void Camera_updateMatrix(Camera* camera)
{
- vec3 camera_target;
- glm_vec3_add(camera->position, camera->front, camera_target);
+ Vec3 camera_target;
+ Vec3_add(camera->position, camera->front, camera_target);
- mat4 view;
- glm_lookat(camera->position, camera_target, camera->up, view);
+ Mat4 view;
+ Mat4_lookAt(camera->position, camera_target, camera->up, view);
- mat4 projection;
- glm_perspective(glm_rad(camera->fovy), camera->aspect, camera->near,
+ Mat4 projection;
+ Mat4_perspective(radians(camera->fovy), camera->aspect, camera->near,
camera->far, projection);
- glm_mat4_mul(projection, view, camera->matrix);
+ Mat4_mul(projection, view, camera->matrix);
}
void Camera_move(Camera *camera)
@@ -107,7 +107,7 @@ void Camera_move(Camera *camera)
float y = kb[SDL_SCANCODE_SPACE] - kb[SDL_SCANCODE_LSHIFT];
float z = kb[SDL_SCANCODE_W] - kb[SDL_SCANCODE_S];
Camera_updatePosition(camera, x, y, z);
-
+
Camera_updateVectors(camera);
Camera_updateMatrix(camera);
-}
-\ No newline at end of file
+}
diff --git a/src/vec.c b/src/vec.c
@@ -1,6 +1,162 @@
#include "vec.h"
+#include <math.h>
+
+float radians(float degrees)
+{
+ return degrees * (M_PI / 180.0f);
+}
+
bool IVec3_equal(const IVec3 a, const IVec3 b)
{
return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]);
}
+
+void Vec3_scale(Vec3 src, float scale, Vec3 dst)
+{
+ dst[0] = src[0] * scale;
+ dst[1] = src[1] * scale;
+ dst[2] = src[2] * scale;
+}
+
+void Vec3_add(Vec3 src_a, Vec3 src_b, Vec3 dst)
+{
+ dst[0] = src_a[0] + src_b[0];
+ dst[1] = src_a[1] + src_b[1];
+ dst[2] = src_a[2] + src_b[2];
+}
+
+void Vec3_sub(Vec3 src_a, Vec3 src_b, Vec3 dst)
+{
+ dst[0] = src_a[0] - src_b[0];
+ dst[1] = src_a[1] - src_b[1];
+ dst[2] = src_a[2] - src_b[2];
+}
+
+void Vec3_mul(Vec3 src_a, Vec3 src_b, Vec3 dst)
+{
+ dst[0] = src_a[1] * src_b[2] - src_a[2] * src_b[1];
+ dst[1] = src_a[2] * src_b[0] - src_a[0] * src_b[2];
+ dst[2] = src_a[0] * src_b[1] - src_a[1] * src_b[0];
+}
+
+void Vec3_normalize(Vec3 src, Vec3 dst)
+{
+ float m = Vec3_mag(src);
+ if (m > 0.0f)
+ {
+ dst[0] = src[0] / m;
+ dst[1] = src[1] / m;
+ dst[2] = src[2] / m;
+ }
+}
+
+float Vec3_dot(Vec3 src_a, Vec3 src_b)
+{
+ return src_a[0] * src_b[0] + src_a[1] * src_b[1] + src_a[2] * src_b[2];
+}
+
+float Vec3_magSquared(Vec3 src)
+{
+ return Vec3_dot(src, src);
+}
+
+float Vec3_mag(Vec3 src)
+{
+ return sqrtf(Vec3_magSquared(src));
+}
+
+void Mat4_mul(Mat4 src_a, Mat4 src_b, Mat4 dst)
+{
+ // x basis
+ dst[0][0] = src_a[0][0] * src_b[0][0] + src_a[1][0] * src_b[0][1] + src_a[2][0] * src_b[0][2] + src_a[3][0] * src_b[0][3];
+ dst[0][1] = src_a[0][1] * src_b[0][0] + src_a[1][1] * src_b[0][1] + src_a[2][1] * src_b[0][2] + src_a[3][1] * src_b[0][3];
+ dst[0][2] = src_a[0][2] * src_b[0][0] + src_a[1][2] * src_b[0][1] + src_a[2][2] * src_b[0][2] + src_a[3][2] * src_b[0][3];
+ dst[0][3] = src_a[0][3] * src_b[0][0] + src_a[1][3] * src_b[0][1] + src_a[2][3] * src_b[0][2] + src_a[3][3] * src_b[0][3];
+
+ // y basis
+ dst[1][0] = src_a[0][0] * src_b[1][0] + src_a[1][0] * src_b[1][1] + src_a[2][0] * src_b[1][2] + src_a[3][0] * src_b[1][3];
+ dst[1][1] = src_a[0][1] * src_b[1][0] + src_a[1][1] * src_b[1][1] + src_a[2][1] * src_b[1][2] + src_a[3][1] * src_b[1][3];
+ dst[1][2] = src_a[0][2] * src_b[1][0] + src_a[1][2] * src_b[1][1] + src_a[2][2] * src_b[1][2] + src_a[3][2] * src_b[1][3];
+ dst[1][3] = src_a[0][3] * src_b[1][0] + src_a[1][3] * src_b[1][1] + src_a[2][3] * src_b[1][2] + src_a[3][3] * src_b[1][3];
+
+ // z basis
+ dst[2][0] = src_a[0][0] * src_b[2][0] + src_a[1][0] * src_b[2][1] + src_a[2][0] * src_b[2][2] + src_a[3][0] * src_b[2][3];
+ dst[2][1] = src_a[0][1] * src_b[2][0] + src_a[1][1] * src_b[2][1] + src_a[2][1] * src_b[2][2] + src_a[3][1] * src_b[2][3];
+ dst[2][2] = src_a[0][2] * src_b[2][0] + src_a[1][2] * src_b[2][1] + src_a[2][2] * src_b[2][2] + src_a[3][2] * src_b[2][3];
+ dst[2][3] = src_a[0][3] * src_b[2][0] + src_a[1][3] * src_b[2][1] + src_a[2][3] * src_b[2][2] + src_a[3][3] * src_b[2][3];
+
+ // w basis
+ dst[3][0] = src_a[0][0] * src_b[3][0] + src_a[1][0] * src_b[3][1] + src_a[2][0] * src_b[3][2] + src_a[3][0] * src_b[3][3];
+ dst[3][1] = src_a[0][1] * src_b[3][0] + src_a[1][1] * src_b[3][1] + src_a[2][1] * src_b[3][2] + src_a[3][1] * src_b[3][3];
+ dst[3][2] = src_a[0][2] * src_b[3][0] + src_a[1][2] * src_b[3][1] + src_a[2][2] * src_b[3][2] + src_a[3][2] * src_b[3][3];
+ dst[3][3] = src_a[0][3] * src_b[3][0] + src_a[1][3] * src_b[3][1] + src_a[2][3] * src_b[3][2] + src_a[3][3] * src_b[3][3];
+}
+
+void Mat4_lookAt(Vec3 camera, Vec3 target, Vec3 up, Mat4 dst)
+{
+ Vec3 f;
+ Vec3_sub(target, camera, f);
+ Vec3_normalize(f, f);
+
+ Vec3 s;
+ Vec3_mul(f, up, s);
+ Vec3_normalize(s, s);
+
+ Vec3 u;
+ Vec3_mul(s, f, u);
+ Vec3_normalize(s, s);
+
+ // x basis
+ dst[0][0] = s[0];
+ dst[0][1] = u[0];
+ dst[0][2] = -f[0];
+ dst[0][3] = 0.0f;
+
+ // y basis
+ dst[1][0] = s[1];
+ dst[1][1] = u[1];
+ dst[1][2] = -f[1];
+ dst[1][3] = 0.0f;
+
+ // z basis
+ dst[2][0] = s[2];
+ dst[2][1] = u[2];
+ dst[2][2] = -f[2];
+ dst[2][3] = 0.0f;
+
+ // w basis
+ dst[3][0] = -Vec3_dot(s, camera);
+ dst[3][1] = -Vec3_dot(u, camera);
+ dst[3][2] = Vec3_dot(f, camera);
+ dst[3][3] = 1.0f;
+}
+
+void Mat4_perspective(float fov, float aspect, float near, float far, Mat4 dst)
+{
+ float tan_half_fov = tanf(fov * 0.5f);
+
+ // x basis
+ dst[0][0] = 1.0f / (aspect * tan_half_fov);
+ dst[0][1] = 0.0f;
+ dst[0][2] = 0.0f;
+ dst[0][3] = 0.0f;
+
+ // y basis
+ dst[1][0] = 0.0f;
+ dst[1][1] = 1.0f / (tan_half_fov);
+ dst[1][2] = 0.0f;
+ dst[1][3] = 0.0f;
+
+ // z basis
+ dst[2][0] = 0.0f;
+ dst[2][1] = 0.0f;
+ dst[2][2] = -(far + near) / (far - near);
+ dst[2][3] = -1.0f;
+
+ // w basis
+ dst[3][0] = 0.0f;
+ dst[3][1] = 0.0f;
+ dst[3][2] = -(2 * far * near) / (far - near);
+ dst[3][3] = 0.0f;
+}