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;
f32 bullet_impulse;
f32 bullet_knockback;
f32 bullet_impact_explosion_strength;
f32 bullet_impact_explosion_radius;
b32 bullet_has_hit;
/* ====================================================================== */
/* Explosion */
f32 explosion_strength;
f32 explosion_radius;
u64 explosion_tick;
/* ====================================================================== */
/* Tracer */

View File

@ -151,7 +151,7 @@ INTERNAL struct sim_ent *spawn_test_camera(struct sim_snapshot *world, struct si
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);
@ -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_enable_prop(ent, SEPROP_EXPLOSION);
ent->explosion_strength = strength;
ent->explosion_radius = radius;
sim_ent_enable_prop(ent, SEPROP_SENSOR);
@ -323,7 +324,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
/* Create explosion */
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 */
@ -333,17 +334,12 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
}
/* 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 *victim = e1;
exp->explosion_tick = world->tick;
//sim_ent_disable_prop(exp, SEPROP_SENSOR);
struct xform xf = sim_ent_get_xform(exp);
f32 radius = exp->explosion_radius;
struct collider_shape origin_collider = ZI;
origin_collider.count = 1;
@ -357,12 +353,14 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
} else {
distance = v2_len(dir);
}
/* TODO: Blast obstruction */
if (distance <= radius) {
/* TODO: Exponential decay */
f32 strength = 100;
f32 ratio = (radius - distance) / radius;
struct v2 impulse = v2_with_len(dir, strength * ratio);
f32 radius = exp->explosion_radius;
f32 strength_center = exp->explosion_strength;
if (distance < radius) {
const f32 falloff_curve = 3; /* Cubic falloff */
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);
}
}
@ -613,7 +611,7 @@ void sim_step(struct sim_step_ctx *ctx)
if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) {
if (!(old_control.flags & SIM_CONTROL_FLAG_EXPLODE_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_impulse = 0.75f;
bullet->bullet_impulse = 2.0f;
//bullet->bullet_knockback = 10;
bullet->bullet_knockback = 10;
bullet->mass_unscaled = 0.04f;
bullet->inertia_unscaled = 0.00001f;
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.75;
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->inertia_unscaled = 0.00001f;
bullet->layer = SIM_LAYER_BULLETS;
@ -1258,6 +1257,19 @@ void sim_step(struct sim_step_ctx *ctx)
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
* ========================== */