disable collision between bullet shooter & bullet

This commit is contained in:
jacob 2025-01-12 09:40:33 -06:00
parent b66f130e9c
commit e70047f763
6 changed files with 49 additions and 26 deletions

View File

@ -267,7 +267,6 @@ void app_entry_point(void)
arena_temp_end(temp); arena_temp_end(temp);
} }
logf_info("Program exited normally"); logf_info("Program exited normally");
scratch_end(scratch); scratch_end(scratch);
} }

View File

@ -78,7 +78,7 @@ void entity_store_copy_replace(struct entity_store *dest, struct entity_store *s
} }
/* ========================== * /* ========================== *
* Allocation * Entity allocation
* ========================== */ * ========================== */
INTERNAL struct entity *entity_alloc_internal(struct entity_store *store) INTERNAL struct entity *entity_alloc_internal(struct entity_store *store)
@ -132,7 +132,7 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity
void entity_release(struct entity_store *store, struct entity *ent) void entity_release(struct entity_store *store, struct entity *ent)
{ {
if (ent->parent.gen) { if (ent->parent.gen) {
entity_unlink_parent(ent); entity_unlink_from_parent(ent);
} }
entity_release_internal(store, ent); entity_release_internal(store, ent);
} }
@ -352,7 +352,7 @@ void entity_link_parent(struct entity *ent, struct entity *parent)
if (ent->parent.gen) { if (ent->parent.gen) {
/* Unlink from current parent */ /* Unlink from current parent */
entity_unlink_parent(ent); entity_unlink_from_parent(ent);
} }
struct entity_handle handle = ent->handle; struct entity_handle handle = ent->handle;
@ -370,11 +370,16 @@ void entity_link_parent(struct entity *ent, struct entity *parent)
} }
parent->last = handle; parent->last = handle;
ent->is_top = parent->is_root; if (parent->is_root) {
ent->is_top = true;
ent->top = handle;
} else {
ent->top = parent->top;
}
} }
/* NOTE: Entity will be dangling after calling this, should re-link to root entity. */ /* NOTE: Entity will be dangling after calling this, should re-link to root entity. */
void entity_unlink_parent(struct entity *ent) void entity_unlink_from_parent(struct entity *ent)
{ {
struct entity_store *store = entity_get_store(ent); struct entity_store *store = entity_get_store(ent);

View File

@ -91,6 +91,9 @@ struct entity {
/* Is entity a child of the root entity */ /* Is entity a child of the root entity */
b32 is_top; b32 is_top;
/* The handle of the top level parent of the entity */
struct entity_handle top;
/* Tree */ /* Tree */
struct entity_handle parent; struct entity_handle parent;
struct entity_handle next; struct entity_handle next;
@ -353,7 +356,7 @@ struct entity *entity_find_first_match_all(struct entity_store *store, struct en
/* Tree */ /* Tree */
void entity_link_parent(struct entity *parent, struct entity *child); void entity_link_parent(struct entity *parent, struct entity *child);
void entity_unlink_parent(struct entity *ent); void entity_unlink_from_parent(struct entity *ent);
/* Lookup */ /* Lookup */
struct entity_lookup entity_lookup_alloc(u64 num_buckets); struct entity_lookup entity_lookup_alloc(u64 num_buckets);

View File

@ -335,6 +335,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
for (u64 i = 0; i < array.count; ++i) { for (u64 i = 0; i < array.count; ++i) {
struct phys_collision_data *data = &array.a[i]; struct phys_collision_data *data = &array.a[i];
struct phys_contact_constraint *constraint = data->constraint;
struct entity *e0 = entity_from_handle(store, data->e0); struct entity *e0 = entity_from_handle(store, data->e0);
struct entity *e1 = entity_from_handle(store, data->e1); struct entity *e1 = entity_from_handle(store, data->e1);
@ -343,8 +344,16 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
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;
struct entity *src = entity_from_handle(store, bullet->bullet_src);
(UNUSED)bullet; (UNUSED)bullet;
(UNUSED)target; (UNUSED)target;
(UNUSED)src;
if (entity_handle_eq(src->top, target->top)) {
/* Ignore collision if weapon and target share same top level parent */
constraint->skip_solve = true;
continue;
}
/* Disable bullet */ /* Disable bullet */
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_BEFORE_PUBLISH); entity_enable_prop(bullet, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);

View File

@ -119,10 +119,27 @@ struct phys_collision_data_array phys_create_contacts(struct arena *arena, struc
struct phys_contact_constraint *constraint = NULL; struct phys_contact_constraint *constraint = NULL;
if (collider_res.num_points > 0) { if (collider_res.num_points > 0) {
if (!entity_is_valid_and_active(constraint_ent)) { if (!entity_is_valid_and_active(constraint_ent)) {
/* Create constraint */
{
constraint_ent = entity_alloc(root);
constraint_ent->contact_constraint_data.e1 = e1->handle;
constraint_ent->contact_constraint_data.e0 = e0->handle;
constraint_ent->contact_constraint_data.skip_solve = entity_has_prop(e0, ENTITY_PROP_SENSOR) || entity_has_prop(e1, ENTITY_PROP_SENSOR)
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC));
entity_enable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
/* TODO: Should we recalculate normal as more contact points are added? */
entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT);
entity_activate(constraint_ent, tick_id);
ASSERT(!entry); /* Existing entry should never be present here */
entity_lookup_set(contact_lookup, key, constraint_ent->handle);
}
/* Push collision data */ /* Push collision data */
if (ctx->pre_solve_callback || ctx->post_solve_callback) { if (ctx->pre_solve_callback || ctx->post_solve_callback) {
struct phys_collision_data *data = arena_push_zero(arena, struct phys_collision_data); struct phys_collision_data *data = arena_push_zero(arena, struct phys_collision_data);
++res.count; ++res.count;
data->constraint = &constraint_ent->contact_constraint_data;
data->e0 = e0->handle; data->e0 = e0->handle;
data->e1 = e1->handle; data->e1 = e1->handle;
data->normal = collider_res.normal; data->normal = collider_res.normal;
@ -150,22 +167,6 @@ struct phys_collision_data_array phys_create_contacts(struct arena *arena, struc
} }
data->vrel = vrel; data->vrel = vrel;
} }
/* Create constraint */
{
constraint_ent = entity_alloc(root);
constraint_ent->contact_constraint_data.e1 = e1->handle;
constraint_ent->contact_constraint_data.e0 = e0->handle;
constraint_ent->contact_constraint_data.skip_solve = entity_has_prop(e0, ENTITY_PROP_SENSOR) || entity_has_prop(e1, ENTITY_PROP_SENSOR)
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC));
entity_enable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
/* TODO: Should we recalculate normal as more contact points are added? */
entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT);
entity_activate(constraint_ent, tick_id);
ASSERT(!entry); /* Existing entry should never be present here */
entity_lookup_set(contact_lookup, key, constraint_ent->handle);
}
} }
constraint = &constraint_ent->contact_constraint_data; constraint = &constraint_ent->contact_constraint_data;
constraint->normal = collider_res.normal; constraint->normal = collider_res.normal;
@ -1127,7 +1128,7 @@ void phys_step(struct phys_ctx *ctx, f32 timestep)
f32 remaining_dt = timestep; f32 remaining_dt = timestep;
while (remaining_dt > 0) { while (remaining_dt > 0) {
__profscope(step); __profscope(step_part);
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
/* TOI */ /* TOI */
f32 step_dt = remaining_dt; f32 step_dt = remaining_dt;
@ -1160,22 +1161,27 @@ void phys_step(struct phys_ctx *ctx, f32 timestep)
f32 substep_dt = step_dt / GAME_PHYSICS_SUBSTEPS; f32 substep_dt = step_dt / GAME_PHYSICS_SUBSTEPS;
for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) { for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) {
__profscope(substep); __profscope(substep);
/* Warm start */
#if GAME_PHYSICS_ENABLE_WARM_STARTING #if GAME_PHYSICS_ENABLE_WARM_STARTING
phys_warm_start_contacts(ctx); phys_warm_start_contacts(ctx);
phys_warm_start_motor_joints(ctx); phys_warm_start_motor_joints(ctx);
phys_warm_start_mouse_joints(ctx); phys_warm_start_mouse_joints(ctx);
#endif #endif
/* Solve */
#if GAME_PHYSICS_ENABLE_COLLISION #if GAME_PHYSICS_ENABLE_COLLISION
phys_solve_contacts(ctx, substep_dt, true); phys_solve_contacts(ctx, substep_dt, true);
#endif #endif
phys_solve_motor_joints(ctx, substep_dt); phys_solve_motor_joints(ctx, substep_dt);
phys_solve_mouse_joints(ctx, substep_dt); phys_solve_mouse_joints(ctx, substep_dt);
/* Integrate */
phys_integrate_velocities(ctx, substep_dt); phys_integrate_velocities(ctx, substep_dt);
/* Relaxation solve */
#if GAME_PHYSICS_ENABLE_COLLISION && GAME_PHYSICS_ENABLE_RELAXATION #if GAME_PHYSICS_ENABLE_COLLISION && GAME_PHYSICS_ENABLE_RELAXATION
phys_solve_contacts(ctx, substep_dt, false); /* Relaxation */ phys_solve_contacts(ctx, substep_dt, false);
#endif #endif
} }

View File

@ -7,8 +7,9 @@
struct entity_store; struct entity_store;
struct entity_lookup; struct entity_lookup;
struct phys_contact_constraint;
struct phys_collision_data { struct phys_collision_data {
struct entity_handle constraint_ent; struct phys_contact_constraint *constraint;
struct entity_handle e0; struct entity_handle e0;
struct entity_handle e1; struct entity_handle e1;
struct v2 point; struct v2 point;