collision
This commit is contained in:
parent
edec8789a9
commit
f56f28c721
4 changed files with 42 additions and 41 deletions
|
@ -11,18 +11,17 @@ float v2_len(v2 a) {
|
||||||
return sqrt(a.x * a.x + a.y * a.y);
|
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) {
|
float v2_square_dist(v2 a, v2 b) {
|
||||||
return pow(a.x - b.x, 2) + pow(a.y - b.y, 2);
|
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) {
|
uint32_t cast_ray(v2 pos, float theta, v2* hit_pos) {
|
||||||
|
|
||||||
const v2i move = {
|
const v2i move = {
|
||||||
#define sign(a) ((a) < 0 ? -1 : 1)
|
|
||||||
sign(cos(theta)),
|
sign(cos(theta)),
|
||||||
sign(sin(theta)),
|
sign(sin(theta)),
|
||||||
};
|
};
|
||||||
|
|
11
src/ray.h
11
src/ray.h
|
@ -3,6 +3,14 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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 {
|
typedef struct {
|
||||||
float x, y;
|
float x, y;
|
||||||
} v2;
|
} v2;
|
||||||
|
@ -11,10 +19,9 @@ typedef struct {
|
||||||
int x, y;
|
int x, y;
|
||||||
} v2i;
|
} v2i;
|
||||||
|
|
||||||
|
|
||||||
float v2_cross(v2 a, v2 b);
|
float v2_cross(v2 a, v2 b);
|
||||||
float v2_len(v2 a);
|
float v2_len(v2 a);
|
||||||
|
float v2_dist(v2 a, v2 b);
|
||||||
float v2_square_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);
|
uint32_t cast_ray(v2 pos, float theta, v2* hit_pos);
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define PI 3.14159265358979323846
|
|
||||||
#define PIH 1.57079632679489661923
|
|
||||||
#define PI2 6.28318530718
|
|
||||||
|
|
||||||
void init_camera(Camera* camera) {
|
void init_camera(Camera* camera) {
|
||||||
camera->x = 3;
|
camera->pos.x = 3;
|
||||||
camera->y = 3;
|
camera->pos.y = 3;
|
||||||
camera->angle = PI / 4;
|
camera->angle = PI / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +17,8 @@ static double fov = PI / 4;
|
||||||
#define MOVE_SPEED 1
|
#define MOVE_SPEED 1
|
||||||
#define ROTATE_SPEED PI / 2
|
#define ROTATE_SPEED PI / 2
|
||||||
#define FOV_CHANGE_SPEED 1
|
#define FOV_CHANGE_SPEED 1
|
||||||
|
#define PLAYER_SIZE .1
|
||||||
|
|
||||||
void update_camera(Camera* camera, Screen* screen) {
|
void update_camera(Camera* camera, Screen* screen) {
|
||||||
double rotate = 0;
|
double rotate = 0;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ void update_camera(Camera* camera, Screen* screen) {
|
||||||
v2 left = { forward.y, -forward.x };
|
v2 left = { forward.y, -forward.x };
|
||||||
v2 move = { 0, 0 };
|
v2 move = { 0, 0 };
|
||||||
|
|
||||||
if (key_pressed(screen, SDL_SCANCODE_W)) {
|
if (key_pressed(screen, SDL_SCANCODE_W)) {
|
||||||
move.x += forward.x;
|
move.x += forward.x;
|
||||||
move.y += forward.y;
|
move.y += forward.y;
|
||||||
}
|
}
|
||||||
|
@ -67,16 +67,17 @@ void update_camera(Camera* camera, Screen* screen) {
|
||||||
fov -= FOV_CHANGE_SPEED * screen->delta;
|
fov -= FOV_CHANGE_SPEED * screen->delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
camera->x += move.x * MOVE_SPEED * screen->delta;
|
v2 hit_pos;
|
||||||
camera->y += move.y * MOVE_SPEED * screen->delta;
|
bool movex, movey;
|
||||||
}
|
|
||||||
|
|
||||||
v2 get_cam_right(const Camera* camera) {
|
cast_ray(camera->pos, sign(move.x) == 1 ? 0 : PI, &hit_pos);
|
||||||
v2 cam_right = {
|
movex = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE;
|
||||||
-sin(camera->angle),
|
|
||||||
cos(camera->angle)
|
cast_ray(camera->pos, sign(move.y) == 1 ? PIH : -PIH, &hit_pos);
|
||||||
};
|
movey = v2_dist(hit_pos, camera->pos) > PLAYER_SIZE;
|
||||||
return cam_right;
|
|
||||||
|
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) {
|
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) {
|
void render(Screen* screen, const Camera* camera) {
|
||||||
|
|
||||||
const v2 pos = {
|
const v2 cam_right = {
|
||||||
camera->x,
|
-sin(camera->angle),
|
||||||
camera->y
|
cos(camera->angle)
|
||||||
};
|
};
|
||||||
|
|
||||||
const v2 cam_right = get_cam_right(camera);
|
for (int x = 0; x < screen->width; x++) {
|
||||||
|
const float xcam = (2 * (x / (float) (screen->width))) - 1;
|
||||||
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 change = fov * atan(xcam);
|
||||||
const float theta = camera->angle + change;
|
const float theta = camera->angle + change;
|
||||||
|
|
||||||
v2 hit_pos;
|
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.x -= camera->pos.x;
|
||||||
hit_pos.y -= pos.y;
|
hit_pos.y -= camera->pos.y;
|
||||||
|
|
||||||
float len = v2_cross(hit_pos, cam_right) / v2_len(cam_right);
|
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;
|
case 5: color = 0x00FFFFFF; break;
|
||||||
default: color = 0x000000FF; break;
|
default: color = 0x000000FF; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int
|
const int
|
||||||
h = (int) (screen->height / len),
|
h = (int) (screen->height / len),
|
||||||
y0 = max((screen->height / 2) - (h / 2), 0),
|
y0 = max((screen->height / 2) - (h / 2), 0),
|
||||||
y1 = min((screen->height / 2) + (h / 2), screen->height - 1);
|
y1 = min((screen->height / 2) + (h / 2), screen->height - 1);
|
||||||
|
|
||||||
verline(screen, sx, 0, y0, 0x202020FF);
|
verline(screen, x, 0, y0, 0x202020FF);
|
||||||
verline(screen, sx, y0, y1, color);
|
verline(screen, x, y0, y1, color);
|
||||||
verline(screen, sx, y1, screen->height - 1, 0x505050FF);
|
verline(screen, x, y1, screen->height - 1, 0x505050FF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float x, y;
|
v2 pos;
|
||||||
float angle;
|
float angle;
|
||||||
} Camera;
|
} Camera;
|
||||||
|
|
||||||
void init_camera(Camera* camera);
|
void init_camera(Camera* camera);
|
||||||
void update_camera(Camera* camera, Screen* screeen);
|
void update_camera(Camera* camera, Screen* screeen);
|
||||||
v2 get_cam_right(const Camera* camera);
|
|
||||||
|
|
||||||
void render(Screen* screen, const Camera* camera);
|
void render(Screen* screen, const Camera* camera);
|
||||||
|
|
Loading…
Reference in a new issue