summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-04-22 12:35:09 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-04-22 12:35:09 -0400
commitedec8789a919372207c530ae1a3c98c05ec07aed (patch)
tree287c7bc5cd77f03dbab42a4aab0dfc49dc5d6ad3 /src
parentupdate makefile (diff)
downloadraycaster-edec8789a919372207c530ae1a3c98c05ec07aed.tar.gz
raycaster-edec8789a919372207c530ae1a3c98c05ec07aed.tar.bz2
raycaster-edec8789a919372207c530ae1a3c98c05ec07aed.zip
move raycastign to its own file
Diffstat (limited to '')
-rw-r--r--src/map.h17
-rw-r--r--src/ray.c106
-rw-r--r--src/ray.h20
-rw-r--r--src/renderer.c148
-rw-r--r--src/renderer.h2
5 files changed, 172 insertions, 121 deletions
diff --git a/src/map.h b/src/map.h
new file mode 100644
index 0000000..3e265b2
--- /dev/null
+++ b/src/map.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <stdint.h>
+
+#define MAP_SIZE 8
+static uint8_t MAPDATA[MAP_SIZE * MAP_SIZE] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 3, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 2, 0, 4, 4, 0, 1,
+ 1, 0, 0, 0, 4, 0, 0, 1,
+ 1, 0, 3, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+#define value(x, y) (MAPDATA[(x) + MAP_SIZE * (y)])
diff --git a/src/ray.c b/src/ray.c
new file mode 100644
index 0000000..36e89b4
--- /dev/null
+++ b/src/ray.c
@@ -0,0 +1,106 @@
+#include "ray.h"
+#include "map.h"
+
+#include <math.h>
+
+float v2_cross(v2 a, v2 b) {
+ return fabs(a.x * b.y - a.y * b.x);
+}
+
+float v2_len(v2 a) {
+ return sqrt(a.x * a.x + a.y * a.y);
+}
+
+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)),
+ };
+
+ const v2i offset = {
+ move.x == -1 ? 1 : 0,
+ move.y == -1 ? 1 : 0
+ };
+
+ const float tanc = tan(theta);
+ const float cotc = tan(PIH - (theta));
+
+ v2i posi = {
+ (int)pos.x + offset.x,
+ (int)pos.y + offset.y
+ };
+
+ bool fx = false;
+ uint32_t vx = 0;
+ float x;
+
+ while (!fx) {
+ posi.y += move.y;
+ x = cotc * (posi.y - pos.y) + pos.x;
+
+ if (fabs(x) - pos.x >= MAP_SIZE) break;
+
+ vx = value((int)x, posi.y - offset.y);
+
+ if (vx != 0) {
+ fx = true;
+ }
+ }
+
+ bool fy = false;
+ uint32_t vy = 0;
+ float y;
+
+ while (!fy) {
+ posi.x += move.x;
+ y = tanc * (posi.x - pos.x) + pos.y;
+
+ if (fabs(y) - pos.y >= MAP_SIZE) break;
+
+ vy = value(posi.x - offset.x, (int)y);
+
+ if (vy != 0) {
+ fy = true;
+ }
+ }
+
+ uint32_t hit;
+ if (!fx && !fy) {
+ hit = 0;
+ hit_pos->x = pos.x + 1000 * move.x;
+ hit_pos->y = pos.y + 1000 * move.y;
+ return false;
+ } else if (fx && !fy) {
+ hit = vx;
+ hit_pos->x = x;
+ hit_pos->y = posi.y;
+ } else if (fy && !fx) {
+ hit = vy;
+ hit_pos->x = posi.x;
+ hit_pos->y = y;
+ } else {
+ const v2 posx = {x, posi.y};
+ const v2 posy = {posi.x, y};
+ if (v2_square_dist(posx, pos) < v2_square_dist(posy, pos)) {
+ hit = vx;
+ hit_pos->x = x;
+ hit_pos->y = posi.y;
+ } else {
+ hit = vy;
+ hit_pos->x = posi.x;
+ hit_pos->y= y;
+ }
+ }
+
+ return hit;
+}
diff --git a/src/ray.h b/src/ray.h
new file mode 100644
index 0000000..8ad2638
--- /dev/null
+++ b/src/ray.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct {
+ float x, y;
+} v2;
+
+typedef struct {
+ int x, y;
+} v2i;
+
+
+float v2_cross(v2 a, v2 b);
+float v2_len(v2 a);
+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 8eee037..6d8e1af 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -1,5 +1,6 @@
#include "renderer.h"
#include "screen.h"
+#include "ray.h"
#include <math.h>
@@ -13,16 +14,11 @@ void init_camera(Camera* camera) {
camera->angle = PI / 4;
}
-typedef struct {
- float x, y;
-} v2;
-
-typedef struct {
- int x, y;
-} v2i;
+static double fov = PI / 4;
#define MOVE_SPEED 1
#define ROTATE_SPEED PI / 2
+#define FOV_CHANGE_SPEED 1
void update_camera(Camera* camera, Screen* screen) {
double rotate = 0;
@@ -43,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;
}
@@ -63,22 +59,25 @@ void update_camera(Camera* camera, Screen* screen) {
move.y -= left.y;
}
+ if (key_pressed(screen, SDL_SCANCODE_EQUALS)) {
+ fov += FOV_CHANGE_SPEED * screen->delta;
+ }
+
+ if (key_pressed(screen, SDL_SCANCODE_MINUS)) {
+ fov -= FOV_CHANGE_SPEED * screen->delta;
+ }
+
camera->x += move.x * MOVE_SPEED * screen->delta;
camera->y += move.y * MOVE_SPEED * screen->delta;
}
-
-#define MAP_SIZE 8
-static uint8_t MAPDATA[MAP_SIZE * MAP_SIZE] = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 1,
- 1, 0, 0, 0, 0, 3, 0, 1,
- 1, 0, 0, 0, 0, 0, 0, 1,
- 1, 0, 2, 0, 4, 4, 0, 1,
- 1, 0, 0, 0, 4, 0, 0, 1,
- 1, 0, 3, 0, 0, 0, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
-};
+v2 get_cam_right(const Camera* camera) {
+ v2 cam_right = {
+ -sin(camera->angle),
+ cos(camera->angle)
+ };
+ return cam_right;
+}
static void verline(Screen* screen, int x, int y0, int y1, uint32_t color) {
for (int y = y0; y <= y1; y++) {
@@ -86,124 +85,31 @@ static void verline(Screen* screen, int x, int y0, int y1, uint32_t color) {
}
}
-static float v2_cross(v2 a, v2 b) {
- return fabs(a.x * b.y - a.y * b.x);
-}
-
-static float v2_len(v2 a) {
- return sqrt(a.x * a.x + a.y * a.y);
-}
-
-static float v2_square_dist(v2 a, v2 b) {
- return pow(a.x - b.x, 2) + pow(a.y - b.y, 2);
-}
-
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
-#define sign(a) ((a) < 0 ? -1 : 1)
-#define value(x, y) (MAPDATA[(x) + MAP_SIZE * (y)])
void render(Screen* screen, const Camera* camera) {
- const double fov = PI / 3;
-
- const v2 cam_right = {
- -sin(camera->angle),
- cos(camera->angle)
- };
-
const v2 pos = {
camera->x,
camera->y
};
+ 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;
const float change = fov * atan(xcam);
+ const float theta = camera->angle + change;
- const v2i move = {
- sign(cos(camera->angle + change)),
- sign(sin(camera->angle + change)),
- };
-
- const v2i offset = {
- move.x == -1 ? 1 : 0,
- move.y == -1 ? 1 : 0
- };
-
- const float tanc = tan(camera->angle + change);
- const float cotc = tan(PIH - (camera->angle + change));
-
- v2i posi = {
- (int)pos.x + offset.x,
- (int)pos.y + offset.y
- };
-
- bool fx = false;
- uint32_t vx = 0;
- float x;
-
- while (!fx) {
- posi.y += move.y;
- x = cotc * (posi.y - pos.y) + pos.x;
-
- if (fabs(x) - pos.x >= MAP_SIZE) break;
-
- vx = value((int)x, posi.y - offset.y);
-
- if (vx != 0) {
- fx = true;
- }
- }
-
- bool fy = false;
- uint32_t vy = 0;
- float y;
-
- while (!fy) {
- posi.x += move.x;
- y = tanc * (posi.x - pos.x) + pos.y;
-
- if (fabs(y) - pos.y >= MAP_SIZE) break;
-
- vy = value(posi.x - offset.x, (int)y);
-
- if (vy != 0) {
- fy = true;
- }
- }
-
- uint32_t hit;
- if (!fx && !fy) {
- hit = 0;
- x = pos.x + 1000 * move.x;
- y = pos.y + 1000 * move.y;
- } else if (fx && !fy) {
- hit = vx;
- y = posi.y;
- } else if (fy && !fx) {
- hit = vy;
- x = posi.x;
- } else {
- const v2 posx = {x, posi.y};
- const v2 posy = {posi.x, y};
- if (v2_square_dist(posx, pos) < v2_square_dist(posy, pos)) {
- hit = vx;
- y = posi.y;
- } else {
- hit = vy;
- x = posi.x;
- }
- }
+ v2 hit_pos;
+ uint32_t hit = cast_ray(pos, theta, &hit_pos);
- const v2 relative = {
- x - pos.x,
- y - pos.y
- };
+ hit_pos.x -= pos.x;
+ hit_pos.y -= pos.y;
- float len = v2_cross(relative, cam_right) / v2_len(cam_right);
- if (len < 0.00001) len = 0.00001;
+ float len = v2_cross(hit_pos, cam_right) / v2_len(cam_right);
uint32_t color;
switch (hit) {
diff --git a/src/renderer.h b/src/renderer.h
index ca184a9..998c9d7 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -1,6 +1,7 @@
#pragma once
#include "screen.h"
+#include "ray.h"
typedef struct {
float x, y;
@@ -9,5 +10,6 @@ typedef struct {
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);