From e9c7cced16ff58c55af9af34c39fd3a4fd39cec5 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 22 May 2025 01:17:08 -0500 Subject: [PATCH] one directional wall testing --- src/phys.c | 16 +++++++++++++++- src/sim_ent.h | 22 ++++++++++++++++++++++ src/sim_step.c | 34 ++++++++++++++++++++++++++++++++++ src/user.c | 3 +++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/phys.c b/src/phys.c index 37bdb0e2..f2597a27 100644 --- a/src/phys.c +++ b/src/phys.c @@ -95,8 +95,22 @@ void phys_create_and_update_contacts(struct phys_step_ctx *ctx, f32 elapsed_dt, CT_ASSERT(ARRAY_COUNT(constraint_ent->contact_constraint_data.points) == 2); CT_ASSERT(ARRAY_COUNT(collider_res.points) == 2); + b32 create_constraint = collider_res.num_points > 0; + if (create_constraint) { + struct v2 normal = collider_res.normal; + struct v2 dir0 = e0->test_dir; + struct v2 dir1 = e1->test_dir; + f32 threshold = 0.5; + if (create_constraint && !v2_is_zero(dir0)) { + create_constraint = v2_dot(dir0, normal) > threshold; + } + if (create_constraint && !v2_is_zero(dir1)) { + create_constraint = v2_dot(dir1, v2_neg(normal)) > threshold; + } + } + struct phys_contact_constraint *constraint = NULL; - if (collider_res.num_points > 0) { + if (create_constraint) { b32 is_start = false; if (!constraint_ent->valid) { is_start = true; diff --git a/src/sim_ent.h b/src/sim_ent.h index 00f91031..fb979bb9 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -73,6 +73,28 @@ enum sim_ent_prop { struct sim_ent { struct sim_snapshot *ss; + + + + + + + + + + + + + struct v2 test_dir; + + + + + + + + + /* ====================================================================== */ /* Metadata */ diff --git a/src/sim_step.c b/src/sim_step.c index fdc3d31c..48d7877c 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -438,6 +438,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) struct wall_node { struct v2i32 start; struct v2i32 end; + i32 wall_dir; /* = 0 up, 1 = right, 2 = down, 3 = left */ struct wall_node *next; }; @@ -460,7 +461,9 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) { i32 wall_start = -1; i32 wall_end = -1; + i32 last_wall_dir = -1; for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) { + i32 wall_dir = -1; enum sim_tile_kind tile = SIM_TILE_KIND_NONE; if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) { tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y)); @@ -479,9 +482,11 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) if (tile == SIM_TILE_KIND_WALL) { /* Process wall tile */ should_have_top_wall = top_tile != SIM_TILE_KIND_WALL; + wall_dir = 0; } else { /* Process non-wall tile */ should_have_top_wall = top_tile == SIM_TILE_KIND_WALL; + wall_dir = 2; } } if (should_have_top_wall) { @@ -491,6 +496,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) } /* Extend wall */ wall_end = tile_x + 1; + last_wall_dir = wall_dir; } else if (wall_end >= 0) { /* Stop wall */ struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_start, tile_y)); @@ -509,6 +515,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) node = arena_push(scratch.arena, struct wall_node); node->start = start; node->next = first_wall; + node->wall_dir = last_wall_dir; first_wall = node; } node->end = end; @@ -518,6 +525,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) } wall_start = -1; wall_end = -1; + last_wall_dir = -1; } } } @@ -535,7 +543,9 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) { i32 wall_start = -1; i32 wall_end = -1; + i32 last_wall_dir = -1; for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) { + i32 wall_dir = -1; enum sim_tile_kind tile = SIM_TILE_KIND_NONE; if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) { tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y)); @@ -555,9 +565,11 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) if (tile == SIM_TILE_KIND_WALL) { /* Process wall tile */ should_have_left_wall = left_tile != SIM_TILE_KIND_WALL; + wall_dir = 3; } else { /* Process non-wall tile */ should_have_left_wall = left_tile == SIM_TILE_KIND_WALL; + wall_dir = 1; } } if (should_have_left_wall) { @@ -567,6 +579,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) } /* Extend wall */ wall_end = tile_y + 1; + last_wall_dir = wall_dir; } else if (wall_end >= 0) { /* Stop wall */ struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_start)); @@ -585,6 +598,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) node = arena_push(scratch.arena, struct wall_node); node->start = start; node->next = first_wall; + node->wall_dir = last_wall_dir; first_wall = node; } node->end = end; @@ -594,6 +608,7 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) } wall_start = -1; wall_end = -1; + last_wall_dir = -1; } } } @@ -614,6 +629,25 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) wall_ent->local_collider.count = 2; wall_ent->local_collider.points[1] = v2_sub(end, start); + switch (node->wall_dir) { + case 0: + { + wall_ent->test_dir = V2(0, -1); + } break; + case 1: + { + wall_ent->test_dir = V2(1, 0); + } break; + case 2: + { + wall_ent->test_dir = V2(0, 1); + } break; + case 3: + { + wall_ent->test_dir = V2(-1, 0); + } break; + } + sim_ent_activate(wall_ent, world->tick); } diff --git a/src/user.c b/src/user.c index 1464d67c..216367b7 100644 --- a/src/user.c +++ b/src/user.c @@ -412,6 +412,9 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e res.len += string_format(arena, LIT("linear velocity: (%F, %F)\n"), FMT_FLOAT(linear_velocity.x), FMT_FLOAT(linear_velocity.y)).len; res.len += string_format(arena, LIT("angular velocity: %F\n"), FMT_FLOAT(angular_velocity)).len; + /* Test */ + res.len += string_format(arena, LIT("test_dir: (%F, %F)\n"), FMT_FLOAT(ent->test_dir.x), FMT_FLOAT(ent->test_dir.y)).len; + /* Children */ if (!sim_ent_id_is_nil(ent->first) || !sim_ent_id_is_nil(ent->last)) { struct sim_ent *child = sim_ent_from_id(ss, ent->first);