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_pos;
|
||||||
struct v2 bullet_src_dir;
|
struct v2 bullet_src_dir;
|
||||||
f32 bullet_impulse;
|
f32 bullet_impulse;
|
||||||
b32 bullet_has_hit; /* Has the bullet hit a target this tick */
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Testing */
|
/* 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
|
* 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) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!entity_is_valid_and_active(ent)) continue;
|
||||||
if (!entity_has_prop(ent, ENTITY_PROP_HIT_EVENT)) 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 *e0 = entity_from_handle(store, event->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, event->e1);
|
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)) {
|
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 *bullet = entity_has_prop(e0, ENTITY_PROP_BULLET) ? e0 : e1;
|
||||||
struct entity *target = e0 == bullet ? e1 : e0;
|
struct entity *target = e0 == bullet ? e1 : e0;
|
||||||
if (!bullet->bullet_has_hit) {
|
|
||||||
bullet->bullet_has_hit = true;
|
|
||||||
(UNUSED)bullet;
|
(UNUSED)bullet;
|
||||||
(UNUSED)target;
|
(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);
|
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
||||||
#endif
|
entity_disable_prop(bullet, ENTITY_PROP_ACTIVE);
|
||||||
|
|
||||||
/* Create test blood */
|
/* Create test blood */
|
||||||
/* TODO: Remove this */
|
/* 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
|
* 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;
|
u64 tick_id = ctx->tick_id;
|
||||||
struct entity_lookup *contact_lookup = ctx->contact_lookup;
|
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.e0 = e0->handle;
|
||||||
event->hit_event.e1 = e1->handle;
|
event->hit_event.e1 = e1->handle;
|
||||||
event->hit_event.normal = collider_res.normal;
|
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_RELEASE_BEFORE_PUBLISH);
|
||||||
entity_enable_prop(event, ENTITY_PROP_ACTIVE);
|
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;
|
const u32 max_iterations = 16;
|
||||||
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi);
|
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;
|
step_dt = remaining_dt * earliest_toi;
|
||||||
|
remaining_dt -= step_dt;
|
||||||
#else
|
#else
|
||||||
(UNUSED)toi;
|
(UNUSED)toi;
|
||||||
(UNUSED)determine_earliest_toi_for_bullets;
|
(UNUSED)determine_earliest_toi_for_bullets;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
phys_create_contacts(ctx);
|
phys_create_contacts(ctx, timestep - remaining_dt);
|
||||||
phys_create_mouse_joints(ctx);
|
phys_create_mouse_joints(ctx);
|
||||||
|
|
||||||
phys_prepare_contacts(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 */
|
phys_solve_contacts(ctx, substep_dt, false); /* Relaxation */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
remaining_dt -= step_dt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,12 @@ struct phys_hit_event {
|
|||||||
struct v2 point;
|
struct v2 point;
|
||||||
struct v2 normal;
|
struct v2 normal;
|
||||||
struct v2 vrel; /* Relative velocity */
|
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;
|
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_prepare_contacts(struct phys_ctx *ctx);
|
||||||
void phys_warm_start_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);
|
void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user