commit 0b9c14b88423f086211d83468247baf2f44bacdd
parent 15978352074cc31e15335776c0eb7fe7142cba1f
Author: Christian Ermann <christianermann@gmail.com>
Date: Mon, 30 May 2022 17:36:16 -0700
Remove player movement from camera.
Diffstat:
11 files changed, 228 insertions(+), 129 deletions(-)
diff --git a/include/camera.h b/include/camera.h
@@ -3,6 +3,7 @@
#include "input.h"
#include "vec.h"
+#include "transform.h"
typedef struct {
Vec3 n;
@@ -10,21 +11,12 @@ typedef struct {
} Plane;
typedef struct {
- Vec3 position;
- float yaw;
- float pitch;
+ Transform *transform;
- Vec3 world_up;
float fovy;
float aspect;
float near;
float far;
- float speed;
- float sensitivity;
-
- Vec3 front;
- Vec3 up;
- Vec3 right;
Mat4 matrix;
@@ -36,23 +28,14 @@ typedef struct {
} Camera;
-Camera *Camera_make(float x, float y, float z, float yaw, float pitch);
+Camera *Camera_make(Transform *t);
void Camera_free(Camera *camera);
void Camera_defaultSettings(Camera* camera);
-void Camera_updateRotation(Camera* camera, float dx, float dy);
-void Camera_updatePosition(Camera* camera, float z, float x, float y);
-
-// Update camera 'front', 'right', 'up' vectors.
-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, UserInput *input);
-
void Camera_updateFrustum(Camera *camera);
int Camera_sphereInFrustum(const Camera *camera, Vec3 p, float r);
diff --git a/include/player.h b/include/player.h
@@ -0,0 +1,15 @@
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "input.h"
+#include "transform.h"
+
+typedef struct {
+ float speed;
+ float sensitivity;
+ Transform *transform;
+} Player;
+
+void Player_move(Player *player, UserInput *input);
+
+#endif
diff --git a/include/save.h b/include/save.h
@@ -1,10 +1,9 @@
#ifndef SAVE_H
#define SAVE_H
-#include "input.h"
-#include "vec.h"
+#include "transform.h"
-int save(const Vec3 position);
-int load(Vec3 position);
+int save(const Transform *t);
+int load(Transform *t);
#endif
diff --git a/include/transform.h b/include/transform.h
@@ -0,0 +1,26 @@
+#ifndef TRANSFORM_H
+#define TRANSFORM_H
+
+#include "vec.h"
+
+typedef struct {
+ Vec3 position;
+ float yaw;
+ float pitch;
+ Vec3 forward;
+ Vec3 up;
+ Vec3 right;
+} Transform;
+
+void Transform_init(
+ Transform *t,
+ float x,
+ float y,
+ float z,
+ float yaw,
+ float pitch
+);
+
+void Transform_updateVectors(Transform *t);
+
+#endif
diff --git a/include/vec.h b/include/vec.h
@@ -11,6 +11,8 @@ bool IVec3_equal(const IVec3 a, const IVec3 b);
typedef float Vec3[3];
+void Vec3_set(float x, float y, float z, Vec3 dst);
+
// dst = src * scale
void Vec3_scale(const Vec3 src, float scale, Vec3 dst);
diff --git a/src/camera.c b/src/camera.c
@@ -3,16 +3,11 @@
#include <math.h>
#include <stdlib.h>
-Camera *Camera_make(float x, float y, float z, float yaw, float pitch)
+Camera *Camera_make(Transform *t)
{
Camera *camera = malloc(sizeof *camera);
- camera->position[0] = x;
- camera->position[1] = y;
- camera->position[2] = z;
- camera->yaw = yaw;
- camera->pitch = pitch;
+ camera->transform = t;
Camera_defaultSettings(camera);
- Camera_updateVectors(camera);
Camera_updateMatrix(camera);
return camera;
}
@@ -27,15 +22,10 @@ void Camera_free(Camera *camera)
void Camera_defaultSettings(Camera* camera)
{
- camera->world_up[0] = 0.0f;
- camera->world_up[1] = 1.0f;
- camera->world_up[2] = 0.0f;
camera->fovy = 90.0f;
camera->aspect = 1.0f;
camera->near = 0.1f;
camera->far = 200.0f;
- camera->speed = 0.1f;
- camera->sensitivity = 0.3f;
camera->near_h = 2 * tan(camera->fovy / 2) * camera->near;
camera->near_w = camera->near_h * camera->aspect;
@@ -44,102 +34,63 @@ void Camera_defaultSettings(Camera* camera)
camera->far_w = camera->far_h * camera->aspect;
}
-void Camera_updateRotation(Camera* camera, float dx, float dy)
-{
- camera->yaw += dx * camera->sensitivity;
-
- camera->pitch += dy * camera->sensitivity;
- if (camera->pitch > 85.0f) camera->pitch = 85.0f;
- if (camera->pitch < -85.0f) camera->pitch = -85.0f;
-}
-
-void Camera_updatePosition(Camera* camera, float x, float y, float z)
-{
- Vec3 movement_x;
- Vec3_scale(camera->right, x, movement_x);
-
- Vec3 movement_y;
- Vec3_scale(camera->up, y, movement_y);
-
- Vec3 movement_z;
- Vec3_scale(camera->front, z, movement_z);
-
- 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);
-
- Vec3_add(camera->position, movement, camera->position);
-}
-
-void Camera_updateVectors(Camera* camera)
-{
- 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);
-
- Vec3_mul(camera->front, camera->world_up, camera->right);
- Vec3_normalize(camera->right, camera->right);
-
- Vec3_mul(camera->right, camera->front, camera->up);
- Vec3_normalize(camera->up, camera->up);
-}
-
-void Camera_updateMatrix(Camera* camera)
+void Camera_updateMatrix(Camera *camera)
{
Vec3 camera_target;
- Vec3_add(camera->position, camera->front, camera_target);
+ Vec3_add(
+ camera->transform->position,
+ camera->transform->forward,
+ camera_target
+ );
Mat4 view;
- Mat4_lookAt(camera->position, camera_target, camera->up, view);
+ Mat4_lookAt(
+ camera->transform->position,
+ camera_target,
+ camera->transform->up,
+ view
+ );
Mat4 projection;
- Mat4_perspective(radians(camera->fovy), camera->aspect, camera->near,
- camera->far, projection);
+ Mat4_perspective(
+ radians(camera->fovy),
+ camera->aspect,
+ camera->near,
+ camera->far,
+ projection
+ );
Mat4_mul(projection, view, camera->matrix);
}
-void Camera_move(Camera *camera, UserInput *input)
-{
- Camera_updateRotation(camera, input->rotation_dx, -input->rotation_dy);
- Camera_updatePosition(camera, input->move_dx, input->move_dy, input->move_dz);
- Camera_updateVectors(camera);
- Camera_updateMatrix(camera);
- Camera_updateFrustum(camera);
-}
-
void Camera_updateFrustum(Camera *camera)
{
// Near plane
- camera->frustum[0].n[0] = camera->front[0];
- camera->frustum[0].n[1] = camera->front[1];
- camera->frustum[0].n[2] = camera->front[2];
+ camera->frustum[0].n[0] = camera->transform->forward[0];
+ camera->frustum[0].n[1] = camera->transform->forward[1];
+ camera->frustum[0].n[2] = camera->transform->forward[2];
Vec3_scale(
- camera->front,
+ camera->transform->forward,
camera->near,
camera->frustum[0].p
);
Vec3_add(
- camera->position,
+ camera->transform->position,
camera->frustum[0].p,
camera->frustum[0].p
);
// Far plane
- camera->frustum[1].n[0] = -camera->front[0];
- camera->frustum[1].n[1] = -camera->front[1];
- camera->frustum[1].n[2] = -camera->front[2];
+ camera->frustum[1].n[0] = -camera->transform->forward[0];
+ camera->frustum[1].n[1] = -camera->transform->forward[1];
+ camera->frustum[1].n[2] = -camera->transform->forward[2];
Vec3_scale(
- camera->front,
+ camera->transform->forward,
camera->far,
camera->frustum[1].p
);
Vec3_add(
- camera->position,
+ camera->transform->position,
camera->frustum[1].p,
camera->frustum[1].p
);
@@ -149,7 +100,7 @@ void Camera_updateFrustum(Camera *camera)
// Top plane
Vec3_scale(
- camera->up,
+ camera->transform->up,
camera->near_h / 2,
camera->frustum[2].p
);
@@ -161,13 +112,13 @@ void Camera_updateFrustum(Camera *camera)
Vec3_sub(
camera->frustum[2].p,
- camera->position,
+ camera->transform->position,
a
);
Vec3_mul(
a,
- camera->right,
+ camera->transform->right,
camera->frustum[2].n
);
Vec3_normalize(
@@ -177,7 +128,7 @@ void Camera_updateFrustum(Camera *camera)
// Bottom plane
Vec3_scale(
- camera->up,
+ camera->transform->up,
camera->near_h / 2,
camera->frustum[3].p
);
@@ -189,12 +140,12 @@ void Camera_updateFrustum(Camera *camera)
Vec3_sub(
camera->frustum[3].p,
- camera->position,
+ camera->transform->position,
a
);
Vec3_mul(
- camera->right,
+ camera->transform->right,
a,
camera->frustum[3].n
);
@@ -205,7 +156,7 @@ void Camera_updateFrustum(Camera *camera)
// Left plane
Vec3_scale(
- camera->right,
+ camera->transform->right,
camera->near_w / 2,
camera->frustum[4].p
);
@@ -217,13 +168,13 @@ void Camera_updateFrustum(Camera *camera)
Vec3_sub(
camera->frustum[4].p,
- camera->position,
+ camera->transform->position,
a
);
Vec3_mul(
a,
- camera->up,
+ camera->transform->up,
camera->frustum[4].n
);
Vec3_normalize(
@@ -233,7 +184,7 @@ void Camera_updateFrustum(Camera *camera)
// Right plane
Vec3_scale(
- camera->right,
+ camera->transform->right,
camera->near_w / 2,
camera->frustum[5].p
);
@@ -245,12 +196,12 @@ void Camera_updateFrustum(Camera *camera)
Vec3_sub(
camera->frustum[5].p,
- camera->position,
+ camera->transform->position,
a
);
Vec3_mul(
- camera->up,
+ camera->transform->up,
a,
camera->frustum[5].n
);
diff --git a/src/main.c b/src/main.c
@@ -5,6 +5,8 @@
#include "perlin.h"
#include "save.h"
#include "shader.h"
+#include "transform.h"
+#include "player.h"
#include "glad/glad.h"
#include "GLFW/glfw3.h"
@@ -75,11 +77,27 @@ int main(int argc, char** argv)
UserInput input = { 0 };
UserInput_init(&input, app->window);
- Camera *camera = Camera_make(0, 0, -3, 0, 0);
- load(camera->position);
+ Transform player_transform;
+ Transform_init(
+ &player_transform,
+ 0, // x
+ 0, // y
+ -3, // z
+ 0, // yaw
+ 0 // pitch
+ );
+ load(&player_transform);
+
+ Player player = {
+ .speed = 0.1f,
+ .sensitivity = 0.3f,
+ .transform = &player_transform
+ };
+
+ Camera *camera = Camera_make(&player_transform);
ChunkManager chunk_manager = ChunkManager_create(
- camera->position,
+ player_transform.position,
5,
terrainSDF,
0.0f
@@ -132,26 +150,28 @@ int main(int argc, char** argv)
UserInput_update(&input, app->window);
- Camera_move(camera, &input);
+ Player_move(&player, &input);
+ Camera_updateMatrix(camera);
+
Shader_setInt(shader, "time", loop_count);
Shader_setMat4(shader, "camera", camera->matrix);
- Shader_setVec3(shader, "view_pos", camera->position);
- Shader_setVec3(shader, "pointlight_pos", camera->position);
+ Shader_setVec3(shader, "view_pos", player_transform.position);
+ Shader_setVec3(shader, "pointlight_pos", player_transform.position);
- ChunkManager_recenter(&chunk_manager, camera->position);
+ ChunkManager_recenter(&chunk_manager, player_transform.position);
ChunkManager_drawChunks(&chunk_manager, camera);
loop_count += 1;
if (loop_count % 100000 == 0)
{
- save(camera->position);
+ save(&player_transform);
}
glfwSwapBuffers(app->window);
glfwPollEvents();
}
- save(camera->position);
+ save(&player_transform);
ChunkManager_free(&chunk_manager);
App_free(app);
diff --git a/src/player.c b/src/player.c
@@ -0,0 +1,58 @@
+#include "player.h"
+
+static void Player_updateRotation(Player *player, float dx, float dy)
+{
+ player->transform->yaw += dx * player->sensitivity;
+
+ player->transform->pitch -= dy * player->sensitivity;
+ if (player->transform->pitch > 85.0f)
+ {
+ player->transform->pitch = 85.0f;
+ }
+ if (player->transform->pitch < -85.0f)
+ {
+ player->transform->pitch = -85.0f;
+ }
+}
+
+static void Player_updatePosition(Player *player, float dx, float dy, float dz)
+{
+ Vec3 movement_x;
+ Vec3_scale(player->transform->right, dx, movement_x);
+
+ Vec3 movement_y;
+ Vec3_scale(player->transform->up, dy, movement_y);
+
+ Vec3 movement_z;
+ Vec3_scale(player->transform->forward, dz, movement_z);
+
+ Vec3 movement;
+ Vec3_add(movement_x, movement_y, movement);
+ Vec3_add(movement_z, movement, movement);
+ Vec3_normalize(movement, movement);
+ Vec3_scale(movement, player->speed, movement);
+
+ Vec3_add(
+ player->transform->position,
+ movement,
+ player->transform->position
+ );
+}
+
+void Player_move(Player *player, UserInput *input)
+{
+ Player_updateRotation(
+ player,
+ input->rotation_dx,
+ input->rotation_dy
+ );
+
+ Player_updatePosition(
+ player,
+ input->move_dx,
+ input->move_dy,
+ input->move_dz
+ );
+
+ Transform_updateVectors(player->transform);
+}
diff --git a/src/save.c b/src/save.c
@@ -2,22 +2,22 @@
#include <stdio.h>
-int save(const Vec3 position)
+int save(const Transform *t)
{
FILE *fp;
fp = fopen("savedata", "w");
if (!fp) return -1;
- fwrite(position, 3, sizeof(float), fp);
+ fwrite(t, 1, sizeof(Transform), fp);
fclose(fp);
return 0;
}
-int load(Vec3 position)
+int load(Transform *t)
{
FILE *fp;
fp = fopen("savedata", "r");
if (!fp) return -1;
- fread(position, sizeof(float), 3, fp);
+ fread(t, sizeof(Transform), 1, fp);
fclose(fp);
return 0;
}
diff --git a/src/transform.c b/src/transform.c
@@ -0,0 +1,38 @@
+#include "transform.h"
+
+#include <math.h>
+
+const Vec3 WORLD_UP = { 0, 1, 0 };
+
+void Transform_init(
+ Transform *t,
+ float x,
+ float y,
+ float z,
+ float yaw,
+ float pitch
+)
+{
+ t->yaw = yaw;
+ t->pitch = pitch;
+ Vec3_set(x, y, z, t->position);
+ Transform_updateVectors(t);
+}
+
+// Set forward, up, and right vectors based on pitch and yaw.
+void Transform_updateVectors(Transform *t)
+{
+ Vec3_set(
+ cosf(radians(t->yaw)) * cosf(radians(t->pitch)),
+ sinf(radians(t->pitch)),
+ sinf(radians(t->yaw)) * cosf(radians(t->pitch)),
+ t->forward
+ );
+ Vec3_normalize(t->forward, t->forward);
+
+ Vec3_mul(t->forward, WORLD_UP, t->right);
+ Vec3_normalize(t->right, t->right);
+
+ Vec3_mul(t->right, t->forward, t->up);
+ Vec3_normalize(t->up, t->up);
+}
diff --git a/src/vec.c b/src/vec.c
@@ -12,6 +12,13 @@ bool IVec3_equal(const IVec3 a, const IVec3 b)
return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]);
}
+void Vec3_set(float x, float y, float z, Vec3 dst)
+{
+ dst[0] = x;
+ dst[1] = y;
+ dst[2] = z;
+}
+
void Vec3_scale(const Vec3 src, float scale, Vec3 dst)
{
dst[0] = src[0] * scale;