fix dangling constraint entities

This commit is contained in:
jacob 2025-01-06 15:05:15 -06:00
parent dd4b05cbd1
commit 967a408972

View File

@ -575,16 +575,15 @@ INTERNAL void create_contacts(void)
constraint_ent = entity_alloc(root); constraint_ent = entity_alloc(root);
constraint_ent->contact_constraint_data.e1 = e1->handle; constraint_ent->contact_constraint_data.e1 = e1->handle;
constraint_ent->contact_constraint_data.e0 = e0->handle; constraint_ent->contact_constraint_data.e0 = e0->handle;
constraint_ent->contact_constraint_data.skip_solve = entity_has_prop(e0, ENTITY_PROP_SENSOR) || entity_has_prop(e1, ENTITY_PROP_SENSOR) constraint_ent->contact_constraint_data.skip_solve = entity_has_prop(e0, ENTITY_PROP_SENSOR) || entity_has_prop(e1, ENTITY_PROP_SENSOR)
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC)); || !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC));
entity_enable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
/* TODO: Should we recalculate normal as more contact points are added? */ /* TODO: Should we recalculate normal as more contact points are added? */
entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT); entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT);
activate_now(constraint_ent); activate_now(constraint_ent);
if (!entry) { ASSERT(!entry); /* Existing entry should never be present here */
contact_lookup_set(&G.contact_lookup, lookup_hash, constraint_ent->handle); contact_lookup_set(&G.contact_lookup, lookup_hash, constraint_ent->handle);
}
} }
} }
constraint = &constraint_ent->contact_constraint_data; constraint = &constraint_ent->contact_constraint_data;
@ -785,6 +784,14 @@ INTERNAL void prepare_contacts(void)
/* Mark constraint for removal */ /* Mark constraint for removal */
entity_disable_prop(constraint_ent, ENTITY_PROP_ACTIVE); entity_disable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
entity_enable_prop(constraint_ent, ENTITY_PROP_RELEASE_AT_END_OF_FRAME); entity_enable_prop(constraint_ent, ENTITY_PROP_RELEASE_AT_END_OF_FRAME);
/* Remove from lookup */
u64 hash = contact_lookup_hash_from_entities(constraint->e0, constraint->e1);
struct contact_lookup_entry *entry = contact_lookup_get(&G.contact_lookup, hash);
if (entry) {
contact_lookup_remove(&G.contact_lookup, entry);
} else {
ASSERT(false); /* This should always exist */
}
} }
} }
} }
@ -1496,7 +1503,8 @@ INTERNAL f32 toi(struct collider_shape *c0, struct collider_shape *c1,
} }
} }
/* Root finding (bisection) */ /* Bisect until distance is within tolerance */
/* TODO: Implement false position method as well? (should speed up more linear cases) */
f32 t0 = 0.0; f32 t0 = 0.0;
f32 t1 = 1.0; f32 t1 = 1.0;
f32 t = 0.5f; f32 t = 0.5f;
@ -2021,7 +2029,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
bullet->bullet_src_dir = rel_dir; bullet->bullet_src_dir = rel_dir;
//bullet->bullet_impulse = 0.1f; //bullet->bullet_impulse = 0.1f;
//bullet->bullet_impulse = 0.25f; //bullet->bullet_impulse = 0.25f;
bullet->bullet_impulse = 1.f; //bullet->bullet_impulse = 5.f;
bullet->bullet_impulse = 100000.f;
bullet->mass_unscaled = 0.04f; bullet->mass_unscaled = 0.04f;
bullet->inertia_unscaled = 0.00001f; bullet->inertia_unscaled = 0.00001f;
bullet->sprite_collider_slice = STR("shape"); bullet->sprite_collider_slice = STR("shape");
@ -2219,8 +2228,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
{ {
f32 remaining_dt = dt; f32 remaining_dt = dt;
while (remaining_dt > 0) { while (remaining_dt > 0) {
f32 min_toi = 0.00001f; f32 min_toi = 0.000001f;
f32 tolerance = 0.0001f; f32 tolerance = 0.001f;
f32 earliest_toi = max_f32(determine_earliest_toi(remaining_dt, tolerance), min_toi); f32 earliest_toi = max_f32(determine_earliest_toi(remaining_dt, tolerance), min_toi);
f32 step_dt = remaining_dt * earliest_toi; f32 step_dt = remaining_dt * earliest_toi;
@ -2419,17 +2428,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 i = 0; i < ents_to_release_count; ++i) { for (u64 i = 0; i < ents_to_release_count; ++i) {
struct entity *ent = ents_to_release[i]; struct entity *ent = ents_to_release[i];
if (ent->valid) { if (ent->valid) {
/* Remove contact constraint from lookup */
if (entity_has_prop(ent, ENTITY_PROP_CONTACT_CONSTRAINT)) {
u64 hash = contact_lookup_hash_from_entities(ent->contact_constraint_data.e0, ent->contact_constraint_data.e1);
struct contact_lookup_entry *entry = contact_lookup_get(&G.contact_lookup, hash);
if (entry) {
contact_lookup_remove(&G.contact_lookup, entry);
} else {
ASSERT(false); /* This should always exist */
}
}
/* Release */ /* Release */
entity_release(store, ent); entity_release(store, ent);
} }