fix manifold swap issue

This commit is contained in:
jacob 2024-09-19 20:42:31 -05:00
parent dbdd653ae8
commit 4b88b282df
2 changed files with 56 additions and 40 deletions

View File

@ -19,6 +19,9 @@ GLOBAL struct {
b32 paused; b32 paused;
struct sprite_scope *sprite_frame_scope; struct sprite_scope *sprite_frame_scope;
/* TODO: Remove this (testing) */
b32 box_spawned;
/* Game thread input */ /* Game thread input */
struct sys_mutex game_cmds_mutex; struct sys_mutex game_cmds_mutex;
struct arena game_cmds_arena; struct arena game_cmds_arena;
@ -129,10 +132,10 @@ INTERNAL void spawn_test_entities(void)
//struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */ //struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */
//struct v2 size = V2(1, 1); //struct v2 size = V2(1, 1);
struct v2 size = V2(0.5, 0.5); struct v2 size = V2(0.5, 0.5);
f32 r = PI / 4; //f32 r = PI / 4;
//f32 r = PI / 3; //f32 r = PI / 3;
//f32 r = PI / 2; //f32 r = PI / 2;
//f32 r = 0; f32 r = 0;
f32 skew = 0; f32 skew = 0;
struct entity *e = entity_alloc(root); struct entity *e = entity_alloc(root);
@ -149,14 +152,15 @@ INTERNAL void spawn_test_entities(void)
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
//e->control_force = 4500; //e->control_force = 4500;
e->control_force = 1200; //e->control_force = 1200;
e->control_force = 250;
e->control_torque = 10; e->control_torque = 10;
e->control.focus = V2(0, -1); e->control.focus = V2(0, -1);
entity_enable_prop(e, ENTITY_PROP_PHYSICAL); entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
e->mass_unscaled = 100; e->mass_unscaled = 100;
//e->inertia_unscaled = 1; e->inertia_unscaled = 25;
e->inertia_unscaled = F32_INFINITY; //e->inertia_unscaled = F32_INFINITY;
e->linear_ground_friction = 1000; e->linear_ground_friction = 1000;
e->angular_ground_friction = 100; e->angular_ground_friction = 100;
@ -188,7 +192,9 @@ INTERNAL void spawn_test_entities(void)
} }
/* Box */ /* Box */
{ if (!G.box_spawned) {
G.box_spawned = true;
//struct v2 pos = V2(0.5, -0.5); //struct v2 pos = V2(0.5, -0.5);
struct v2 pos = V2(0.5, -1); struct v2 pos = V2(0.5, -1);
struct v2 size = V2(1, 1); struct v2 size = V2(1, 1);
@ -281,6 +287,11 @@ INTERNAL void create_contact_manifolds(void)
if (!(e1->valid && entity_has_prop(e1, ENTITY_PROP_ACTIVE))) continue; if (!(e1->valid && entity_has_prop(e1, ENTITY_PROP_ACTIVE))) continue;
if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue;
/* TODO: Remove this (temporary stop to prevent double-manifold creation) */
if (e0_index >= e1_index) {
continue;
}
/* TODO: Remove this */ /* TODO: Remove this */
static struct arena dict_arena = ZI; static struct arena dict_arena = ZI;
static struct fixed_dict dict = ZI; static struct fixed_dict dict = ZI;
@ -295,10 +306,6 @@ INTERNAL void create_contact_manifolds(void)
{ {
struct entity_handle h0 = e0->handle; struct entity_handle h0 = e0->handle;
struct entity_handle h1 = e1->handle; struct entity_handle h1 = e1->handle;
if (h0.idx > h1.idx) {
h0 = e1->handle;
h1 = e0->handle;
}
manifold_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&h0)); manifold_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&h0));
manifold_hash = hash_fnv64(manifold_hash, BUFFER_FROM_STRUCT(&h1)); manifold_hash = hash_fnv64(manifold_hash, BUFFER_FROM_STRUCT(&h1));
manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash)); manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash));
@ -335,11 +342,14 @@ INTERNAL void create_contact_manifolds(void)
} }
#if 1 #if 1
const f32 remove_contact_threshold_global_dist_sq = 0.005f * 0.005f; const f32 remove_contact_threshold_global_dist_sq = 0.025f * 0.025f;
const f32 insert_contact_threshold_global_dist_sq = 0.005f * 0.005f; const f32 insert_contact_threshold_global_dist_sq = 0.025f * 0.025f;
#else #elif 0
const f32 remove_contact_threshold_global_dist_sq = 0; const f32 remove_contact_threshold_global_dist_sq = 0;
const f32 insert_contact_threshold_global_dist_sq = 0; const f32 insert_contact_threshold_global_dist_sq = 0;
#else
const f32 remove_contact_threshold_global_dist_sq = F32_INFINITY;
const f32 insert_contact_threshold_global_dist_sq = F32_INFINITY;
#endif #endif
struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly); struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly);
@ -502,8 +512,12 @@ INTERNAL void create_contact_manifolds(void)
/* Copy */ /* Copy */
/* TODO: Optimize */ /* TODO: Optimize */
CT_ASSERT(ARRAY_COUNT(manifold->contacts) == 2); /* Logic assumes 2 contact points */ CT_ASSERT(ARRAY_COUNT(manifold->contacts) == 2); /* Logic assumes 2 contact points */
manifold->contacts[0] = *deepest; {
manifold->contacts[1] = *furthest; struct contact deepest_cpy = *deepest;
struct contact furthest_cpy = *furthest;
manifold->contacts[0] = deepest_cpy;
manifold->contacts[1] = furthest_cpy;
}
} }
@ -527,17 +541,11 @@ INTERNAL void create_contact_manifolds(void)
#endif #endif
} else if (manifold->valid) { } else if (manifold->valid) {
/* No longer colliding, delete manifold */ /* No longer colliding, delete manifold */
#if 0 #if 1
manifold->num_contacts = 0; manifold->num_contacts = 0;
//fixed_dict_set(&dict_arena, &dict, manifold_key, NULL); entity_enable_prop(manifold, ENTITY_PROP_RELEASE);
//entity_enable_prop(manifold, ENTITY_PROP_RELEASE);
#else #else
if (res.solved) { if (res.solved) {
manifold->prototype.len = 0; manifold->prototype.len = 0;
@ -599,10 +607,10 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
f32 bias = 0; f32 bias = 0;
if (apply_bias) { if (apply_bias) {
//f32 bias_factor = 0.2f; //f32 bias_factor = 0.2f;
f32 bias_factor = 0.1f; f32 bias_factor = 0.025f;
//f32 bias_slop = 0.0005f; //f32 bias_slop = 0.0005f;
f32 bias_slop = 0.001f; f32 bias_slop = 0.005f;
//f32 bias_slop = 0.00f; //f32 bias_slop = 0.00f;
bias = (bias_factor / dt) * max_f32((contact->depth - bias_slop), 0); bias = (bias_factor / dt) * max_f32((contact->depth - bias_slop), 0);
@ -764,13 +772,16 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
switch (cmd.kind) { switch (cmd.kind) {
/* Clear level */ /* Clear level */
case GAME_CMD_KIND_CLEAR_ALL: { case GAME_CMD_KIND_CLEAR_ALL:
{
logf_info("Clearing level"); logf_info("Clearing level");
entity_store_reset(store); entity_store_reset(store);
G.box_spawned = false;
} break; } break;
/* Spawn test */ /* Spawn test */
case GAME_CMD_KIND_SPAWN_TEST: { case GAME_CMD_KIND_SPAWN_TEST:
{
logf_info("Spawning (test)"); logf_info("Spawning (test)");
spawn_test_entities(); spawn_test_entities();
} break; } break;
@ -1339,9 +1350,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
* ========================== */ * ========================== */
{ {
u32 substeps = 4; f32 substep_dt = dt / GAME_PHYSICS_SUBSTEPS;
f32 substep_dt = dt / substeps; for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) {
for (u32 i = 0; i < substeps; ++i) {
#if 0 #if 0
create_contact_manifolds(); create_contact_manifolds();

View File

@ -987,7 +987,6 @@ INTERNAL void user_update(void)
} }
} }
#if 1
/* Draw collision */ /* Draw collision */
if (entity_has_prop(ent, ENTITY_PROP_MANIFOLD)) { if (entity_has_prop(ent, ENTITY_PROP_MANIFOLD)) {
struct entity *e0 = entity_from_handle(store, ent->manifold_e0); struct entity *e0 = entity_from_handle(store, ent->manifold_e0);
@ -1025,7 +1024,12 @@ INTERNAL void user_update(void)
}; };
} }
} }
(UNUSED)e0_quad;
(UNUSED)e0_poly;
(UNUSED)e1_quad;
(UNUSED)e1_poly;
#if 0
#if 0 #if 0
/* Draw collision shapes */ /* Draw collision shapes */
{ {
@ -1119,7 +1123,9 @@ INTERNAL void user_update(void)
draw_solid_poly_line(G.viewport_canvas, simplex_array, simplex.len > 2, thickness, line_color); draw_solid_poly_line(G.viewport_canvas, simplex_array, simplex.len > 2, thickness, line_color);
} }
} }
#endif
#if 1
/* Draw contacts */ /* Draw contacts */
{ {
f32 radius = 5; f32 radius = 5;
@ -1141,8 +1147,8 @@ INTERNAL void user_update(void)
} }
} }
} }
}
#endif #endif
}
/* Draw hierarchy */ /* Draw hierarchy */
if (entity_has_prop(parent, ENTITY_PROP_ACTIVE) && !parent->is_root) { if (entity_has_prop(parent, ENTITY_PROP_ACTIVE) && !parent->is_root) {