diff --git a/src/ray.c b/src/ray.c index 36e89b4..e3d2cb0 100644 --- a/src/ray.c +++ b/src/ray.c @@ -11,18 +11,17 @@ float v2_len(v2 a) { return sqrt(a.x * a.x + a.y * a.y); } +float v2_dist(v2 a, v2 b) { + return sqrt(v2_square_dist(a, b)); +} + float v2_square_dist(v2 a, v2 b) { return pow(a.x - b.x, 2) + pow(a.y - b.y, 2); } -#define PI 3.14159265358979323846 -#define PIH 1.57079632679489661923 -#define PI2 6.28318530718 - uint32_t cast_ray(v2 pos, float theta, v2* hit_pos) { const v2i move = { - #define sign(a) ((a) < 0 ? -1 : 1) sign(cos(theta)), sign(sin(theta)), }; diff --git a/src/ray.h b/src/ray.h index 8ad2638..6f2e600 100644 --- a/src/ray.h +++ b/src/ray.h @@ -3,6 +3,14 @@ #include #include +#define PI 3.14159265358979323846 +#define PIH 1.57079632679489661923 +#define PI2 6.28318530718 + +#define sign(a) ((a) < 0 ? -1 : 1) +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) + typedef struct { float x, y; } v2; @@ -11,10 +19,9 @@ typedef struct { int x, y; } v2i; - float v2_cross(v2 a, v2 b); float v2_len(v2 a); +float v2_dist(v2 a, v2 b); float v2_square_dist(v2 a, v2 b); -v2 v2_add(v2 a, v2 b); uint32_t cast_ray(v2 pos, float theta, v2* hit_pos); diff --git a/src/renderer.c b/src/renderer.c index 6d8e1af..c64be51 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -3,14 +3,12 @@ #include "ray.h" #include +#include -#define PI 3.14159265358979323846 -#define PIH 1.57079632679489661923 -#define PI2 6.28318530718 void init_camera(Camera* camera) { - camera->x = 3; - camera->y = 3; + camera->pos.x = 3; + camera->pos.y = 3; camera->angle = PI / 4; } @@ -19,6 +17,8 @@ static double fov = PI / 4; #define MOVE_SPEED 1 #define ROTATE_SPEED PI / 2 #define FOV_CHANGE_SPEED 1 +#define PLAYER_SIZE .1 + void update_camera(Camera* camera, Screen* screen) { double rotate = 0; @@ -39,7 +39,7 @@ void update_camera(Camera* camera, Screen* screen) { v2 left = { forward.y, -forward.x }; v2 move = { 0, 0 }; - if (key_pressed(screen, SDL_SCANCODE_W)) { + if (key_pressed(screen, SDL_SCANCODE_W)) { move.x += forward.x; move.y += forward.y; } @@ -67,16 +67,17 @@ void update_camera(Camera* camera, Screen* screen) { fov -= FOV_CHANGE_SPEED * screen->delta; } - camera->x += move.x * MOVE_SPEED * screen->delta; - camera->y += move.y * MOVE_SPEED * screen->delta; -} + v2 hit_pos; + bool movex, movey; -v2 get_cam_right(const Camera* camera) { - v2 cam_right = { - -sin(camera->angle), - cos(camera->angle) - }; - return cam_right; + cast_ray(camera->pos, sign(move.x) == 1 ? 0 : PI, &hit_pos); + movex = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE; + + cast_ray(camera->pos, sign(move.y) == 1 ? PIH : -PIH, &hit_pos); + movey = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE; + + if (movex) camera->pos.x += move.x * MOVE_SPEED * screen->delta; + if (movey) camera->pos.y += move.y * MOVE_SPEED * screen->delta; } static void verline(Screen* screen, int x, int y0, int y1, uint32_t color) { @@ -85,29 +86,23 @@ static void verline(Screen* screen, int x, int y0, int y1, uint32_t color) { } } -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - void render(Screen* screen, const Camera* camera) { - const v2 pos = { - camera->x, - camera->y + const v2 cam_right = { + -sin(camera->angle), + cos(camera->angle) }; - const v2 cam_right = get_cam_right(camera); - - for (int sx = 0; sx < screen->width; sx++) { - - const float xcam = (2 * (sx / (float) (screen->width))) - 1; + for (int x = 0; x < screen->width; x++) { + const float xcam = (2 * (x / (float) (screen->width))) - 1; const float change = fov * atan(xcam); const float theta = camera->angle + change; v2 hit_pos; - uint32_t hit = cast_ray(pos, theta, &hit_pos); + uint32_t hit = cast_ray(camera->pos, theta, &hit_pos); - hit_pos.x -= pos.x; - hit_pos.y -= pos.y; + hit_pos.x -= camera->pos.x; + hit_pos.y -= camera->pos.y; float len = v2_cross(hit_pos, cam_right) / v2_len(cam_right); @@ -120,13 +115,14 @@ void render(Screen* screen, const Camera* camera) { case 5: color = 0x00FFFFFF; break; default: color = 0x000000FF; break; } + const int h = (int) (screen->height / len), y0 = max((screen->height / 2) - (h / 2), 0), y1 = min((screen->height / 2) + (h / 2), screen->height - 1); - verline(screen, sx, 0, y0, 0x202020FF); - verline(screen, sx, y0, y1, color); - verline(screen, sx, y1, screen->height - 1, 0x505050FF); + verline(screen, x, 0, y0, 0x202020FF); + verline(screen, x, y0, y1, color); + verline(screen, x, y1, screen->height - 1, 0x505050FF); } } diff --git a/src/renderer.h b/src/renderer.h index 998c9d7..4bbc711 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -4,12 +4,11 @@ #include "ray.h" typedef struct { - float x, y; + v2 pos; float angle; } Camera; void init_camera(Camera* camera); void update_camera(Camera* camera, Screen* screeen); -v2 get_cam_right(const Camera* camera); void render(Screen* screen, const Camera* camera);