cubic explosion strength

This commit is contained in:
jacob 2025-05-16 14:28:22 -05:00
parent 98c238ff79
commit e24591c13c
2 changed files with 30 additions and 17 deletions

View File

@ -295,14 +295,15 @@ struct sim_ent {
struct v2 bullet_src_dir; struct v2 bullet_src_dir;
f32 bullet_impulse; f32 bullet_impulse;
f32 bullet_knockback; f32 bullet_knockback;
f32 bullet_impact_explosion_strength;
f32 bullet_impact_explosion_radius; f32 bullet_impact_explosion_radius;
b32 bullet_has_hit; b32 bullet_has_hit;
/* ====================================================================== */ /* ====================================================================== */
/* Explosion */ /* Explosion */
f32 explosion_strength;
f32 explosion_radius; f32 explosion_radius;
u64 explosion_tick;
/* ====================================================================== */ /* ====================================================================== */
/* Tracer */ /* Tracer */

View File

@ -151,7 +151,7 @@ INTERNAL struct sim_ent *spawn_test_camera(struct sim_snapshot *world, struct si
return camera_ent; return camera_ent;
} }
INTERNAL struct sim_ent *spawn_test_explosion(struct sim_snapshot *world, struct v2 pos, f32 radius) INTERNAL struct sim_ent *spawn_test_explosion(struct sim_snapshot *world, struct v2 pos, f32 strength, f32 radius)
{ {
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
@ -159,6 +159,7 @@ INTERNAL struct sim_ent *spawn_test_explosion(struct sim_snapshot *world, struct
sim_ent_set_xform(ent, XFORM_POS(pos)); sim_ent_set_xform(ent, XFORM_POS(pos));
sim_ent_enable_prop(ent, SEPROP_EXPLOSION); sim_ent_enable_prop(ent, SEPROP_EXPLOSION);
ent->explosion_strength = strength;
ent->explosion_radius = radius; ent->explosion_radius = radius;
sim_ent_enable_prop(ent, SEPROP_SENSOR); sim_ent_enable_prop(ent, SEPROP_SENSOR);
@ -323,7 +324,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
/* Create explosion */ /* Create explosion */
if (bullet->bullet_impact_explosion_radius > 0) { if (bullet->bullet_impact_explosion_radius > 0) {
spawn_test_explosion(world, point, bullet->bullet_impact_explosion_radius); spawn_test_explosion(world, point, bullet->bullet_impact_explosion_strength, bullet->bullet_impact_explosion_radius);
} }
/* Update bullet */ /* Update bullet */
@ -333,17 +334,12 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
} }
/* Explosion blast collision */ /* Explosion blast collision */
if (sim_ent_has_prop(e0, SEPROP_EXPLOSION) && (e0->explosion_tick == world->tick || e0->explosion_tick == 0)) { if (sim_ent_has_prop(e0, SEPROP_EXPLOSION)) {
struct sim_ent *exp = e0; struct sim_ent *exp = e0;
struct sim_ent *victim = e1; struct sim_ent *victim = e1;
exp->explosion_tick = world->tick;
//sim_ent_disable_prop(exp, SEPROP_SENSOR);
struct xform xf = sim_ent_get_xform(exp); struct xform xf = sim_ent_get_xform(exp);
f32 radius = exp->explosion_radius;
struct collider_shape origin_collider = ZI; struct collider_shape origin_collider = ZI;
origin_collider.count = 1; origin_collider.count = 1;
@ -357,12 +353,14 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
} else { } else {
distance = v2_len(dir); distance = v2_len(dir);
} }
/* TODO: Blast obstruction */ /* TODO: Blast obstruction */
if (distance <= radius) { f32 radius = exp->explosion_radius;
/* TODO: Exponential decay */ f32 strength_center = exp->explosion_strength;
f32 strength = 100; if (distance < radius) {
f32 ratio = (radius - distance) / radius; const f32 falloff_curve = 3; /* Cubic falloff */
struct v2 impulse = v2_with_len(dir, strength * ratio); f32 strength_factor = math_pow(1 - distance/radius, falloff_curve);
struct v2 impulse = v2_with_len(dir, strength_center * strength_factor);
sim_ent_apply_linear_impulse(victim, impulse, closest_points.p1); sim_ent_apply_linear_impulse(victim, impulse, closest_points.p1);
} }
} }
@ -613,7 +611,7 @@ void sim_step(struct sim_step_ctx *ctx)
if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) { if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) {
if (!(old_control.flags & SIM_CONTROL_FLAG_EXPLODE_TEST)) { if (!(old_control.flags & SIM_CONTROL_FLAG_EXPLODE_TEST)) {
logf_info("Explosion (test)"); logf_info("Explosion (test)");
spawn_test_explosion(world, player->player_cursor_pos, 1); spawn_test_explosion(world, player->player_cursor_pos, 100, 2);
} }
} }
} }
@ -955,7 +953,7 @@ void sim_step(struct sim_step_ctx *ctx)
bullet->bullet_src_dir = rel_dir; bullet->bullet_src_dir = rel_dir;
//bullet->bullet_impulse = 0.75f; //bullet->bullet_impulse = 0.75f;
bullet->bullet_impulse = 2.0f; bullet->bullet_impulse = 2.0f;
//bullet->bullet_knockback = 10; bullet->bullet_knockback = 10;
bullet->mass_unscaled = 0.04f; bullet->mass_unscaled = 0.04f;
bullet->inertia_unscaled = 0.00001f; bullet->inertia_unscaled = 0.00001f;
bullet->layer = SIM_LAYER_BULLETS; bullet->layer = SIM_LAYER_BULLETS;
@ -1005,7 +1003,8 @@ void sim_step(struct sim_step_ctx *ctx)
//bullet->bullet_impulse = 0.75f; //bullet->bullet_impulse = 0.75f;
bullet->bullet_impulse = 0.75; bullet->bullet_impulse = 0.75;
bullet->bullet_knockback = 10; bullet->bullet_knockback = 10;
bullet->bullet_impact_explosion_radius = 1.0; bullet->bullet_impact_explosion_strength = 200;
bullet->bullet_impact_explosion_radius = 4.0;
bullet->mass_unscaled = 0.04f; bullet->mass_unscaled = 0.04f;
bullet->inertia_unscaled = 0.00001f; bullet->inertia_unscaled = 0.00001f;
bullet->layer = SIM_LAYER_BULLETS; bullet->layer = SIM_LAYER_BULLETS;
@ -1258,6 +1257,19 @@ void sim_step(struct sim_step_ctx *ctx)
phys_step(&phys, sim_dt); phys_step(&phys, sim_dt);
} }
/* ========================== *
* Update explosions
* ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
struct sim_ent *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue;
if (!sim_ent_has_prop(ent, SEPROP_EXPLOSION)) continue;
/* Explosion doesn't need to generate any more collisions after initial physics step */
//sim_ent_disable_prop(ent, SEPROP_SENSOR);
}
/* ========================== * /* ========================== *
* Update tracers * Update tracers
* ========================== */ * ========================== */