use combined aabb test for bullet TOI

This commit is contained in:
jacob 2025-01-27 20:00:00 -06:00
parent 0836eec851
commit dc09b65f69
3 changed files with 24 additions and 10 deletions

View File

@ -106,6 +106,16 @@ struct aabb collider_aabb_from_collider(struct collider_shape *shape, struct xfo
return res; return res;
} }
struct aabb collider_aabb_from_combined_aabb(struct aabb b0, struct aabb b1)
{
struct aabb res;
res.p0.x = min_f32(min_f32(b0.p0.x, b0.p1.x), min_f32(b1.p0.x, b1.p1.x));
res.p0.y = min_f32(min_f32(b0.p0.y, b0.p1.y), min_f32(b1.p0.y, b1.p1.y));
res.p1.x = max_f32(max_f32(b0.p0.x, b0.p1.x), max_f32(b1.p0.x, b1.p1.x));
res.p1.y = max_f32(max_f32(b0.p0.y, b0.p1.y), max_f32(b1.p0.y, b1.p1.y));
return res;
}
b32 collider_test_aabb(struct aabb box0, struct aabb box1) b32 collider_test_aabb(struct aabb box0, struct aabb box1)
{ {
b32 res = (box0.p0.x >= box1.p0.x && box0.p0.x <= box1.p1.x && box0.p0.y >= box1.p0.y && box0.p0.y <= box1.p1.y) || /* Test box0 top left inside box1 */ b32 res = (box0.p0.x >= box1.p0.x && box0.p0.x <= box1.p1.x && box0.p0.y >= box1.p0.y && box0.p0.y <= box1.p1.y) || /* Test box0 top left inside box1 */

View File

@ -62,6 +62,8 @@ struct collider_support_point collider_get_support_point(struct collider_shape *
struct aabb collider_aabb_from_collider(struct collider_shape *shape, struct xform xf); struct aabb collider_aabb_from_collider(struct collider_shape *shape, struct xform xf);
struct aabb collider_aabb_from_combined_aabb(struct aabb b0, struct aabb b1);
b32 collider_test_aabb(struct aabb box0, struct aabb box1); b32 collider_test_aabb(struct aabb box0, struct aabb box1);
struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1); struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1);

View File

@ -1062,33 +1062,34 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
struct space *space = ctx->space;
f32 smallest_t = 1; f32 smallest_t = 1;
for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) { for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) {
struct entity *e0 = &store->entities[e0_index]; struct entity *e0 = &store->entities[e0_index];
if (!entity_is_valid_and_active(e0)) continue; if (!entity_is_valid_and_active(e0)) continue;
if (!(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue; if (!(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
if (!entity_has_prop(e0, ENTITY_PROP_BULLET)) continue;
if (e0->local_collider.count <= 0) continue; if (e0->local_collider.count <= 0) continue;
b32 e0_is_bullet = entity_has_prop(e0, ENTITY_PROP_BULLET);
struct collider_shape e0_collider = e0->local_collider; struct collider_shape e0_collider = e0->local_collider;
struct xform e0_xf_t0 = entity_get_xform(e0); struct xform e0_xf_t0 = entity_get_xform(e0);
struct xform e0_xf_t1 = get_derived_xform(e0, step_dt); struct xform e0_xf_t1 = get_derived_xform(e0, step_dt);
/* Start e1 index at e0 index + 1 to prevent redundant checks */ /* TODO: Use swept aabb rather than combined aabb. This should prevent spikes from bullets returning false positive TOIs with irrelevant entities. */
for (u64 e1_index = e0_index + 1; e1_index < store->reserved; ++e1_index) { struct aabb aabb_t0 = collider_aabb_from_collider(&e0_collider, e0_xf_t0);
struct entity *e1 = &store->entities[e1_index]; struct aabb aabb_t1 = collider_aabb_from_collider(&e0_collider, e0_xf_t1);
struct aabb combined_aabb = collider_aabb_from_combined_aabb(aabb_t0, aabb_t1);
struct space_iter iter = space_iter_begin_aabb(space, combined_aabb);
struct space_client *client;
while ((client = space_iter_next(&iter))) {
struct entity *e1 = entity_from_handle(store, client->ent);
if (e1 == e0) continue; if (e1 == e0) continue;
if (!entity_is_valid_and_active(e1)) continue; if (!entity_is_valid_and_active(e1)) continue;
if (!(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue; if (!(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
if (e1->local_collider.count <= 0) continue; if (e1->local_collider.count <= 0) continue;
b32 e1_is_bullet = entity_has_prop(e1, ENTITY_PROP_BULLET);
/* Skip check if neither e0 or e1 are bullets */
if (!e0_is_bullet && !e1_is_bullet) continue;
struct collider_shape e1_collider = e1->local_collider; struct collider_shape e1_collider = e1->local_collider;
struct xform e1_xf_t0 = entity_get_xform(e1); struct xform e1_xf_t0 = entity_get_xform(e1);
struct xform e1_xf_t1 = get_derived_xform(e1, step_dt); struct xform e1_xf_t1 = get_derived_xform(e1, step_dt);
@ -1098,6 +1099,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
smallest_t = t; smallest_t = t;
} }
} }
space_iter_end(&iter);
} }
return smallest_t; return smallest_t;