diff --git a/src/phys.c b/src/phys.c index 38f9af9a..6bec2c4f 100644 --- a/src/phys.c +++ b/src/phys.c @@ -53,7 +53,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) { struct sim_ent *check0 = &ss->ents[check0_index]; - if (!sim_ent_should_simulate(check0)) continue; + if (!sim_ent_is_valid_and_active(check0)) continue; if (!(sim_ent_has_prop(check0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue; if (check0->local_collider.count <= 0) continue; @@ -66,7 +66,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a while ((space_entry = space_iter_next(&iter))) { struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent); if (check1 == check0) continue; - if (!sim_ent_should_simulate(check1)) continue; + if (!sim_ent_is_valid_and_active(check1)) continue; if (!(sim_ent_has_prop(check1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue; if (check1->local_collider.count <= 0) continue; @@ -274,7 +274,7 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; - if (!sim_ent_should_simulate(constraint_ent)) continue; + if (!sim_ent_is_valid_and_active(constraint_ent)) continue; if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue; struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data; @@ -282,7 +282,7 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) u32 num_points = constraint->num_points; struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0); struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); - if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) { + if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) { struct v2 normal = constraint->normal; struct v2 tangent = v2_perp(normal); @@ -296,12 +296,26 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration) f32 inv_i0; f32 inv_i1; { - f32 scale0 = math_fabs(xform_get_determinant(e0_xf)); - f32 scale1 = math_fabs(xform_get_determinant(e1_xf)); - inv_m0 = 1.f / (e0->mass_unscaled * scale0); - inv_m1 = 1.f / (e1->mass_unscaled * scale1); - inv_i0 = 1.f / (e0->inertia_unscaled * scale0); - inv_i1 = 1.f / (e1->inertia_unscaled * scale1); + if (sim_ent_should_simulate(e0)) { + f32 scale0 = math_fabs(xform_get_determinant(e0_xf)); + inv_m0 = 1.f / (e0->mass_unscaled * scale0); + inv_i0 = 1.f / (e0->inertia_unscaled * scale0); + } else { + /* e0 is not simulated locally, pretend it has infinite mass for this contact */ + inv_m0 = 0; + inv_i0 = 0; + } + + if (sim_ent_should_simulate(e1)) { + f32 scale1 = math_fabs(xform_get_determinant(e1_xf)); + inv_m1 = 1.f / (e1->mass_unscaled * scale1); + inv_i1 = 1.f / (e1->inertia_unscaled * scale1); + } else { + /* e0 is not simulated locally, pretend it has infinite mass for this contact */ + inv_m1 = 0; + inv_i1 = 0; + } + } constraint->inv_m0 = inv_m0; constraint->inv_m1 = inv_m1; @@ -392,7 +406,7 @@ void phys_warm_start_contacts(struct phys_step_ctx *ctx) struct sim_snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; - if (!sim_ent_should_simulate(constraint_ent)) continue; + if (!sim_ent_is_valid_and_active(constraint_ent)) continue; if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue; struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data; @@ -401,7 +415,7 @@ void phys_warm_start_contacts(struct phys_step_ctx *ctx) struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0); struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); - if (num_points > 0 && sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1) && !constraint->skip_solve) { + if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve) { struct xform e0_xf = sim_ent_get_xform(e0); struct xform e1_xf = sim_ent_get_xform(e1); @@ -447,7 +461,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias) struct sim_snapshot *ss = ctx->sim_step_ctx->world; for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) { struct sim_ent *constraint_ent = &ss->ents[sim_ent_index]; - if (!sim_ent_should_simulate(constraint_ent)) continue; + if (!sim_ent_is_valid_and_active(constraint_ent)) continue; if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue; struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data; @@ -461,7 +475,7 @@ void phys_solve_contacts(struct phys_step_ctx *ctx, f32 dt, b32 apply_bias) f32 w1 = e1->angular_velocity; u32 num_points = constraint->num_points; - if (num_points > 0 && sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1) && !constraint->skip_solve) { + if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve) { struct xform e0_xf = sim_ent_get_xform(e0); struct xform e1_xf = sim_ent_get_xform(e1);