terrain

Real-time terrain generation using marching cubes
git clone git://git.christianermann.dev/terrain
Log | Files | Refs | README | LICENSE

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:
Minclude/camera.h | 23+++--------------------
Ainclude/player.h | 15+++++++++++++++
Minclude/save.h | 7+++----
Ainclude/transform.h | 26++++++++++++++++++++++++++
Minclude/vec.h | 2++
Msrc/camera.c | 135+++++++++++++++++++++++++------------------------------------------------------
Msrc/main.c | 38+++++++++++++++++++++++++++++---------
Asrc/player.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/save.c | 8++++----
Asrc/transform.c | 38++++++++++++++++++++++++++++++++++++++
Msrc/vec.c | 7+++++++
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;