chucker testing. always insert collision callback data.

This commit is contained in:
jacob 2025-05-16 21:39:10 -05:00
parent 88dc2a22ab
commit 2c6dc93167
4 changed files with 83 additions and 42 deletions

View File

@ -115,7 +115,9 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
struct phys_contact_constraint *constraint = NULL; struct phys_contact_constraint *constraint = NULL;
if (collider_res.num_points > 0) { if (collider_res.num_points > 0) {
b32 is_start = false;
if (!constraint_ent->valid) { if (!constraint_ent->valid) {
is_start = true;
/* Create constraint */ /* Create constraint */
constraint_ent = sim_ent_alloc_local_with_id(root, constraint_id); constraint_ent = sim_ent_alloc_local_with_id(root, constraint_id);
constraint_ent->contact_constraint_data.e0 = e0->id; constraint_ent->contact_constraint_data.e0 = e0->id;
@ -128,40 +130,6 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
/* TODO: Should we recalculate normal as more contact points are added? */ /* TODO: Should we recalculate normal as more contact points are added? */
sim_ent_enable_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT); sim_ent_enable_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT);
sim_ent_activate(constraint_ent, tick); sim_ent_activate(constraint_ent, tick);
/* Push collision data */
/* TODO: Analyze benefits of calling callback here directly rather than deferring */
if (ctx->collision_callback) {
struct phys_collision_data *data = arena_push(arena, struct phys_collision_data);
++res.count;
data->constraint = &constraint_ent->contact_constraint_data;
data->e0 = e0->id;
data->e1 = e1->id;
data->normal = collider_res.normal;
data->dt = elapsed_dt;
/* Calculate point */
struct v2 point = collider_res.points[0].point;
if (collider_res.num_points > 1) {
point = v2_add(point, v2_mul(v2_sub(collider_res.points[1].point, point), 0.5f));
}
data->point = point;
/* Calculate relative velocity */
struct v2 vrel;
{
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
f32 w0 = e0->angular_velocity;
f32 w1 = e1->angular_velocity;
struct v2 vcp0 = v2_sub(point, e0_xf.og);
struct v2 vcp1 = v2_sub(point, e1_xf.og);
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
vrel = v2_sub(vel0, vel1);
}
data->vrel = vrel;
}
} }
constraint = &constraint_ent->contact_constraint_data; constraint = &constraint_ent->contact_constraint_data;
constraint->normal = collider_res.normal; constraint->normal = collider_res.normal;
@ -218,6 +186,41 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
contact->dbg_pt = point; contact->dbg_pt = point;
#endif #endif
} }
/* Push collision data */
/* TODO: Analyze benefits of calling callback here directly rather than deferring */
if (ctx->collision_callback) {
struct phys_collision_data *data = arena_push(arena, struct phys_collision_data);
++res.count;
data->constraint = &constraint_ent->contact_constraint_data;
data->e0 = e0->id;
data->e1 = e1->id;
data->normal = collider_res.normal;
data->is_start = is_start;
data->dt = elapsed_dt;
/* Calculate point */
struct v2 point = collider_res.points[0].point;
if (collider_res.num_points > 1) {
point = v2_add(point, v2_mul(v2_sub(collider_res.points[1].point, point), 0.5f));
}
data->point = point;
/* Calculate relative velocity */
struct v2 vrel;
{
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
f32 w0 = e0->angular_velocity;
f32 w1 = e1->angular_velocity;
struct v2 vcp0 = v2_sub(point, e0_xf.og);
struct v2 vcp1 = v2_sub(point, e1_xf.og);
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
vrel = v2_sub(vel0, vel1);
}
data->vrel = vrel;
}
} else if (constraint_ent->valid) { } else if (constraint_ent->valid) {
constraint_ent->contact_constraint_data.num_points = 0; constraint_ent->contact_constraint_data.num_points = 0;
} }

View File

@ -17,6 +17,7 @@ struct phys_collision_data {
struct v2 point; struct v2 point;
struct v2 normal; /* Normal of the collision from e0 to e1 */ struct v2 normal; /* Normal of the collision from e0 to e1 */
struct v2 vrel; /* Relative velocity at point of collision */ struct v2 vrel; /* Relative velocity at point of collision */
b32 is_start; /* Did this collision just begin */
f32 dt; /* How much time elapsed in the step when this event occurred (this will equal the physics timestep unless an early time of impact occurred) */ f32 dt; /* How much time elapsed in the step when this event occurred (this will equal the physics timestep unless an early time of impact occurred) */
}; };

View File

@ -50,6 +50,8 @@ enum sim_ent_prop {
SEPROP_WEAPON_LAUNCHER, SEPROP_WEAPON_LAUNCHER,
SEPROP_WEAPON_CHUCKER, SEPROP_WEAPON_CHUCKER,
SEPROP_CHUCKER_ZONE,
SEPROP_EXPLOSION, SEPROP_EXPLOSION,
SEPROP_TRACER, SEPROP_TRACER,
@ -281,6 +283,21 @@ struct sim_ent {
struct sim_ent_id equipped; struct sim_ent_id equipped;
/* ====================================================================== */
/* Chucker */
/* SEPROP_WEAPON_CHUCKER */
struct sim_ent_id chucker_zone;
/* ====================================================================== */
/* Chucker zone */
/* SEPROP_CHUCKER_ZONE */
struct sim_ent_id chucker_zone_ent;
u64 chucker_zone_ent_tick;
/* ====================================================================== */ /* ====================================================================== */
/* Triggerable */ /* Triggerable */

View File

@ -80,18 +80,23 @@ INTERNAL struct sim_ent *spawn_test_chucker(struct sim_ent *parent)
chucker->primary_fire_delay = 1.0f / 10.0f; chucker->primary_fire_delay = 1.0f / 10.0f;
chucker->secondary_fire_delay = 1.0f / 10.0f; chucker->secondary_fire_delay = 1.0f / 10.0f;
/* Chucker sensor */ /* Chucker zone */
{ {
struct sim_ent *sensor = sim_ent_alloc_sync_src(chucker); struct sim_ent *zone = sim_ent_alloc_sync_src(chucker);
sim_ent_enable_prop(sensor, SEPROP_ATTACHED); sim_ent_enable_prop(zone, SEPROP_CHUCKER_ZONE);
sensor->attach_slice = LIT("out");
sim_ent_enable_prop(sensor, SEPROP_SENSOR); sim_ent_enable_prop(zone, SEPROP_ATTACHED);
zone->attach_slice = LIT("out");
sim_ent_enable_prop(zone, SEPROP_SENSOR);
struct collider_shape collider = ZI; struct collider_shape collider = ZI;
collider.count = 1; collider.count = 2;
collider.points[1] = V2(0, -0.5);
collider.radius = 0.1; collider.radius = 0.1;
sensor->local_collider = collider; zone->local_collider = collider;
chucker->chucker_zone = zone->id;
} }
return chucker; return chucker;
@ -396,6 +401,14 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
sim_ent_apply_linear_impulse(victim, impulse, closest_points.p1); sim_ent_apply_linear_impulse(victim, impulse, closest_points.p1);
} }
} }
/* Chucker zone */
if (sim_ent_has_prop(e0, SEPROP_CHUCKER_ZONE)) {
if (!sim_ent_id_eq(e0->top, e1->top) && sim_ent_has_prop(e1, SEPROP_SOLID)) {
e0->chucker_zone_ent = e1->id;
e0->chucker_zone_ent_tick = world->tick;
}
}
} }
return skip_solve; return skip_solve;
@ -1020,6 +1033,13 @@ void sim_step(struct sim_step_ctx *ctx)
if (sim_ent_has_prop(ent, SEPROP_WEAPON_CHUCKER)) { if (sim_ent_has_prop(ent, SEPROP_WEAPON_CHUCKER)) {
if (primary_triggered) { if (primary_triggered) {
} }
if (secondary_triggered) {
struct sim_ent *zone = sim_ent_from_id(world, ent->chucker_zone);
struct sim_ent *target = sim_ent_from_id(world, zone->chucker_zone_ent);
if (sim_ent_is_valid_and_active(target)) {
sim_ent_enable_prop(target, SEPROP_RELEASE);
}
}
} }
} }