sort hit events by dt to prevent out of order bullet hit processing
This commit is contained in:
parent
5d6835ece3
commit
bbd11d2526
@ -229,7 +229,6 @@ struct entity {
|
||||
struct v2 bullet_src_pos;
|
||||
struct v2 bullet_src_dir;
|
||||
f32 bullet_impulse;
|
||||
b32 bullet_has_hit; /* Has the bullet hit a target this tick */
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Testing */
|
||||
|
||||
45
src/game.c
45
src/game.c
@ -944,14 +944,38 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
/* ========================== *
|
||||
* Respond to hit events
|
||||
* ========================== */
|
||||
{
|
||||
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
||||
|
||||
/* Sort hit events by dt (to ensure early time of impact collisions are processed first) */
|
||||
struct phys_hit_event_node *first_sorted = NULL;
|
||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||
struct entity *ent = &store->entities[entity_index];
|
||||
if (!entity_is_valid_and_active(ent)) continue;
|
||||
if (!entity_has_prop(ent, ENTITY_PROP_HIT_EVENT)) continue;
|
||||
struct phys_hit_event *e = &ent->hit_event;
|
||||
struct phys_hit_event_node *next = first_sorted;
|
||||
struct phys_hit_event_node *prev = NULL;
|
||||
while (next) {
|
||||
if (e->dt < next->e->dt) {
|
||||
break;
|
||||
}
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
struct phys_hit_event_node *n = arena_push_zero(temp.arena, struct phys_hit_event_node);
|
||||
n->e = e;
|
||||
n->next = next;
|
||||
if (prev) {
|
||||
prev->next = n;
|
||||
} else {
|
||||
first_sorted = n;
|
||||
}
|
||||
}
|
||||
|
||||
struct phys_hit_event *event = &ent->hit_event;
|
||||
|
||||
/* Process events */
|
||||
for (struct phys_hit_event_node *n = first_sorted; n; n = n->next) {
|
||||
struct phys_hit_event *event = n->e;
|
||||
struct entity *e0 = entity_from_handle(store, event->e0);
|
||||
struct entity *e1 = entity_from_handle(store, event->e1);
|
||||
|
||||
@ -960,22 +984,11 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
if (entity_has_prop(e0, ENTITY_PROP_BULLET) || entity_has_prop(e1, ENTITY_PROP_BULLET)) {
|
||||
struct entity *bullet = entity_has_prop(e0, ENTITY_PROP_BULLET) ? e0 : e1;
|
||||
struct entity *target = e0 == bullet ? e1 : e0;
|
||||
if (!bullet->bullet_has_hit) {
|
||||
bullet->bullet_has_hit = true;
|
||||
(UNUSED)bullet;
|
||||
(UNUSED)target;
|
||||
#if 0
|
||||
{
|
||||
/* Set bullet position to hit position */
|
||||
struct xform xf = entity_get_xform(bullet);
|
||||
xf.og = event->point;
|
||||
entity_set_xform(bullet, xf);
|
||||
/* Release after publish so user sees bullet in final postiion */
|
||||
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_AFTER_PUBLISH);
|
||||
}
|
||||
#else
|
||||
|
||||
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
||||
#endif
|
||||
entity_disable_prop(bullet, ENTITY_PROP_ACTIVE);
|
||||
|
||||
/* Create test blood */
|
||||
/* TODO: Remove this */
|
||||
@ -992,6 +1005,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arena_temp_end(temp);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
|
||||
@ -37,7 +37,7 @@ struct phys_startup_receipt phys_startup(void)
|
||||
* Contact
|
||||
* ========================== */
|
||||
|
||||
void phys_create_contacts(struct phys_ctx *ctx)
|
||||
void phys_create_contacts(struct phys_ctx *ctx, f32 elapsed_dt)
|
||||
{
|
||||
u64 tick_id = ctx->tick_id;
|
||||
struct entity_lookup *contact_lookup = ctx->contact_lookup;
|
||||
@ -121,6 +121,7 @@ void phys_create_contacts(struct phys_ctx *ctx)
|
||||
event->hit_event.e0 = e0->handle;
|
||||
event->hit_event.e1 = e1->handle;
|
||||
event->hit_event.normal = collider_res.normal;
|
||||
event->hit_event.dt = elapsed_dt;
|
||||
entity_enable_prop(event, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
||||
entity_enable_prop(event, ENTITY_PROP_ACTIVE);
|
||||
|
||||
@ -1120,13 +1121,14 @@ void phys_step(struct phys_ctx *ctx, f32 timestep)
|
||||
const u32 max_iterations = 16;
|
||||
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi);
|
||||
step_dt = remaining_dt * earliest_toi;
|
||||
remaining_dt -= step_dt;
|
||||
#else
|
||||
(UNUSED)toi;
|
||||
(UNUSED)determine_earliest_toi_for_bullets;
|
||||
#endif
|
||||
}
|
||||
|
||||
phys_create_contacts(ctx);
|
||||
phys_create_contacts(ctx, timestep - remaining_dt);
|
||||
phys_create_mouse_joints(ctx);
|
||||
|
||||
phys_prepare_contacts(ctx);
|
||||
@ -1153,6 +1155,5 @@ void phys_step(struct phys_ctx *ctx, f32 timestep)
|
||||
phys_solve_contacts(ctx, substep_dt, false); /* Relaxation */
|
||||
#endif
|
||||
}
|
||||
remaining_dt -= step_dt;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,12 @@ struct phys_hit_event {
|
||||
struct v2 point;
|
||||
struct v2 normal;
|
||||
struct v2 vrel; /* Relative velocity */
|
||||
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 collision occurred) */
|
||||
};
|
||||
|
||||
struct phys_hit_event_node {
|
||||
struct phys_hit_event *e;
|
||||
struct phys_hit_event_node *next;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
@ -91,7 +97,7 @@ struct phys_collision_debug {
|
||||
struct xform xf1;
|
||||
};
|
||||
|
||||
void phys_create_contacts(struct phys_ctx *ctx);
|
||||
void phys_create_contacts(struct phys_ctx *ctx, f32 elapsed_dt);
|
||||
void phys_prepare_contacts(struct phys_ctx *ctx);
|
||||
void phys_warm_start_contacts(struct phys_ctx *ctx);
|
||||
void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user