predict collisions w/ server ents as having infinite mass

This commit is contained in:
jacob 2025-02-25 17:19:23 -06:00
parent 48dbcacd45
commit 79b32b187a

View File

@ -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) { for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) {
struct sim_ent *check0 = &ss->ents[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 (!(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; 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))) { while ((space_entry = space_iter_next(&iter))) {
struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent); struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent);
if (check1 == check0) continue; 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 (!(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; 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) { 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]; 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; if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data; 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; u32 num_points = constraint->num_points;
struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0); struct sim_ent *e0 = sim_ent_from_id(ss, constraint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); 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 normal = constraint->normal;
struct v2 tangent = v2_perp(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_i0;
f32 inv_i1; f32 inv_i1;
{ {
if (sim_ent_should_simulate(e0)) {
f32 scale0 = math_fabs(xform_get_determinant(e0_xf)); 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_m0 = 1.f / (e0->mass_unscaled * scale0);
inv_m1 = 1.f / (e1->mass_unscaled * scale1);
inv_i0 = 1.f / (e0->inertia_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); 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_m0 = inv_m0;
constraint->inv_m1 = inv_m1; 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; 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) { 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]; 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; if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data; 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 *e0 = sim_ent_from_id(ss, constraint->e0);
struct sim_ent *e1 = sim_ent_from_id(ss, constraint->e1); 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 e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1); 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; 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) { 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]; 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; if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data; 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; f32 w1 = e1->angular_velocity;
u32 num_points = constraint->num_points; 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 e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1); struct xform e1_xf = sim_ent_get_xform(e1);