commit b27f37b973503385c93e0ce37cf021d95dc0d46d
parent 71d684de3b226f7d186ecf86f644e0d4a4e26286
Author: amin <dev@aminmesbah.com>
Date: Sat, 20 Apr 2019 23:57:33 +0000
Replace previous approach with swept cast
FossilOrigin-Name: 16708e369b6b524371c16724997305a1e14ccf4aa49b6cd14c499263a115707b
Diffstat:
M | src/game.c | | | 51 | ++++++++++++++++++++++++++++++++++++--------------- |
M | src/glmth.h | | | 34 | ++++++++++++++++++++++++++++++++++ |
2 files changed, 70 insertions(+), 15 deletions(-)
diff --git a/src/game.c b/src/game.c
@@ -112,7 +112,11 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+#if 0
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+#else
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+#endif
m4 view = glmth_m4_init_id();
// World origin is in the lower left
@@ -148,7 +152,9 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
f32 dt = game_input->dt;
f32 max_meters_per_second = 5.0f;
f32 acceleration_rate = 50.0f;
- f32 friction = 0.7f;
+ // TODO: restore friction
+ //f32 friction = 0.7f;
+ f32 friction = 1.0f;
if (game_input->key_up)
{
@@ -186,6 +192,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
player->pos = glmth_v2_a(player->pos, glmth_v2f_m(player->velocity, dt));
glmth_clamp(&(player->pos.x), 0, ROOM_TILE_DIM_X);
glmth_clamp(&(player->pos.y), 0, ROOM_TILE_DIM_Y);
+
}
// render tiles
@@ -233,6 +240,33 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
.min = tile_pos,
.max = {tile_pos.x + tile_size, tile_pos.y + tile_size},
};
+
+ // cast player
+ if (glmth_v2_is_nonzero(player->velocity))
+ {
+ v2 player_direction = glmth_v2_normalize(player->velocity);
+
+ i32 max_cast = glmth_round(glmth_v2_length((v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y}));
+ for (i32 i = 0; i < max_cast; i++)
+ {
+ v2 cast_pos = glmth_v2_a(player->pos, glmth_v2f_m(player_direction, i));
+ rect cast_aabb = {
+ .min = {cast_pos.x - half_w, cast_pos.y - half_h},
+ .max = {cast_pos.x + half_w, cast_pos.y + half_h},
+ };
+ bool cast_intersects = glmth_aabb_intersect(cast_aabb, tile_aabb);
+ if(cast_intersects)
+ {
+ color = (v3) {0.4f, 0.4f, 0.8f};
+ }
+ if(cast_intersects && tile_id > 0)
+ {
+ color = (v3) {0.8f, 0.4f, 0.8f};
+ break;
+ }
+ }
+ }
+
bool player_is_in_tile = glmth_aabb_intersect(player_aabb, tile_aabb);
if (player_is_in_tile)
{
@@ -241,18 +275,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
if (player_is_in_tile && tile_id > 0)
{
color = (v3) {0.8f, 0.4f, 0.4f};
- v2 tile_center = glmth_v2_a(tile_aabb.min, glmth_v2f_m(glmth_v2_s(tile_aabb.max, tile_aabb.min), 0.5f));
- v2 diff = glmth_v2_s(player->pos, tile_center);
- if (x == 13 && y == 3)
- {
- printf("***");
- glmth_v2_print(player->pos);
- printf("- ");
- glmth_v2_print(tile_center);
- printf("= ");
- glmth_v2_print(diff);
- }
- player->pos = glmth_v2_a(player->pos, diff);
}
}
@@ -273,7 +295,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
glBindVertexArray(game_state->tiles.vao);
struct Entity player = game_state->player;
-
m4 model = glmth_m4_init_id();
model = glmth_translate(model, (v3) {player.pos.x, player.pos.y, 0.0f});
model = glmth_scale(model, (v3) {player.dimensions.x, player.dimensions.y, 1.0f});
diff --git a/src/glmth.h b/src/glmth.h
@@ -5,6 +5,11 @@
// TODO: make sure these functions are inlineable and that the compiler does
// indeed inline them.
+internal inline i32 glmth_round(f32 n)
+{
+ return n < 0.0f ? n - 0.5 : n + 0.5;
+}
+
internal inline bool glmth_aabb_intersect(rect r1, rect r2)
{
f32 total_w = (r1.max.x - r1.min.x) + (r2.max.x - r2.min.x);
@@ -125,6 +130,21 @@ internal inline v4 glmth_m4v4_m(m4 m, v4 v)
return r;
}
+internal inline bool glmth_approx(f32 n, f32 compare, f32 epsilon)
+{
+ return fabsf(n - compare) <= epsilon;
+}
+
+internal inline bool glmth_v2_is_nonzero(v2 v)
+{
+ // TODO: Figure out whether this epsilon is universally appropriate.
+ f32 epsilon = 0.000001;
+ return (
+ !glmth_approx(v.x, 0.0f, epsilon)
+ || !glmth_approx(v.y, 0.0f, epsilon)
+ );
+}
+
internal inline v2 glmth_v2_a(v2 vec1, v2 vec2)
{
v2 r = {
@@ -151,6 +171,19 @@ internal inline v2 glmth_v2f_m(v2 v, f32 s)
return r;
}
+internal inline f32 glmth_v2_length(v2 v)
+{
+ return sqrtf((v.x * v.x) + (v.y * v.y));
+}
+
+// TODO: handle degenerate case where l is near 0.0f
+internal inline v2 glmth_v2_normalize(v2 v)
+{
+ f32 l = glmth_v2_length(v);
+ v2 r = {v.x / l, v.y / l};
+ return r;
+}
+
internal inline void glmth_v2_print(v2 v)
{
printf("( %f, %f )\n", v.x, v.y);
@@ -183,6 +216,7 @@ internal inline v3 glmth_v3_negate(v3 v)
return r;
}
+// TODO: handle degenerate case where l is near 0.0f
internal inline v3 glmth_v3_normalize(v3 v)
{
f32 l = glmth_v3_length(v);