start explosion work
This commit is contained in:
parent
2c0b2fcc36
commit
855fa051d0
@ -37,10 +37,10 @@
|
|||||||
|
|
||||||
/* 64^2 = 4096 bins */
|
/* 64^2 = 4096 bins */
|
||||||
#define SPACE_CELL_BINS_SQRT (64)
|
#define SPACE_CELL_BINS_SQRT (64)
|
||||||
#define SPACE_CELL_SIZE (1.0f)
|
#define SPACE_CELL_SIZE (4)
|
||||||
|
|
||||||
#define SIM_TILES_PER_UNIT_SQRT (2)
|
#define SIM_TILES_PER_UNIT_SQRT (2)
|
||||||
#define SIM_TILES_PER_CHUNK_SQRT (16)
|
#define SIM_TILES_PER_CHUNK_SQRT (1)
|
||||||
|
|
||||||
#define SIM_TICKS_PER_SECOND 50
|
#define SIM_TICKS_PER_SECOND 50
|
||||||
//#define SIM_TIMESCALE 1
|
//#define SIM_TIMESCALE 1
|
||||||
|
|||||||
19
src/phys.c
19
src/phys.c
@ -1045,21 +1045,22 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_
|
|||||||
|
|
||||||
void phys_update_aabbs(struct phys_step_ctx *ctx)
|
void phys_update_aabbs(struct phys_step_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||||
struct space *space = ctx->sim_step_ctx->accel->space;
|
struct space *space = ctx->sim_step_ctx->accel->space;
|
||||||
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < ss->num_ents_reserved; ++sim_ent_index) {
|
||||||
struct sim_ent *ent = &ss->ents[sim_ent_index];
|
struct sim_ent *ent = &ss->ents[sim_ent_index];
|
||||||
if (!sim_ent_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (ent->local_collider.count <= 0) continue;
|
if (ent->local_collider.count > 0) {
|
||||||
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
struct xform xf = sim_ent_get_xform(ent);
|
struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle);
|
||||||
struct space_entry *space_entry = space_entry_from_handle(space, ent->space_handle);
|
if (!space_entry->valid) {
|
||||||
if (!space_entry->valid) {
|
space_entry = space_entry_alloc(space, ent->id);
|
||||||
space_entry = space_entry_alloc(space, ent->id);
|
ent->space_handle = space_entry->handle;
|
||||||
ent->space_handle = space_entry->handle;
|
}
|
||||||
|
struct aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf);
|
||||||
|
space_entry_update_aabb(space_entry, aabb);
|
||||||
}
|
}
|
||||||
struct aabb aabb = collider_aabb_from_collider(&ent->local_collider, xf);
|
|
||||||
space_entry_update_aabb(space_entry, aabb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -141,6 +141,7 @@ enum sim_control_flag {
|
|||||||
SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2,
|
SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2,
|
||||||
SIM_CONTROL_FLAG_SPAWN_TEST = 1 << 3,
|
SIM_CONTROL_FLAG_SPAWN_TEST = 1 << 3,
|
||||||
SIM_CONTROL_FLAG_TILE_TEST = 1 << 4,
|
SIM_CONTROL_FLAG_TILE_TEST = 1 << 4,
|
||||||
|
SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sim_control {
|
struct sim_control {
|
||||||
|
|||||||
@ -47,6 +47,9 @@ enum sim_ent_prop {
|
|||||||
SEPROP_TRIGGERED_THIS_TICK,
|
SEPROP_TRIGGERED_THIS_TICK,
|
||||||
SEPROP_TRIGGER_NEXT_TICK,
|
SEPROP_TRIGGER_NEXT_TICK,
|
||||||
|
|
||||||
|
SEPROP_EXPLOSION,
|
||||||
|
SEPROP_EXPLOSION_STARTED,
|
||||||
|
|
||||||
SEPROP_BULLET,
|
SEPROP_BULLET,
|
||||||
SEPROP_TRACER,
|
SEPROP_TRACER,
|
||||||
|
|
||||||
@ -293,8 +296,14 @@ 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_radius;
|
||||||
b32 bullet_has_hit;
|
b32 bullet_has_hit;
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
/* Explosion */
|
||||||
|
|
||||||
|
f32 explosion_radius;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Tracer */
|
/* Tracer */
|
||||||
|
|
||||||
|
|||||||
243
src/sim_step.c
243
src/sim_step.c
@ -23,7 +23,7 @@
|
|||||||
struct sim_accel sim_accel_alloc(void)
|
struct sim_accel sim_accel_alloc(void)
|
||||||
{
|
{
|
||||||
struct sim_accel accel = ZI;
|
struct sim_accel accel = ZI;
|
||||||
accel.space = space_alloc(1, 256);
|
accel.space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BINS_SQRT);
|
||||||
return accel;
|
return accel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +94,10 @@ INTERNAL struct sim_ent *spawn_test_employee(struct sim_step_ctx *ctx)
|
|||||||
|
|
||||||
sim_ent_set_xform(e, xf);
|
sim_ent_set_xform(e, xf);
|
||||||
|
|
||||||
|
#if 0
|
||||||
e->linear_ground_friction = 250;
|
e->linear_ground_friction = 250;
|
||||||
e->angular_ground_friction = 200;
|
e->angular_ground_friction = 200;
|
||||||
|
#endif
|
||||||
|
|
||||||
e->friction = 0;
|
e->friction = 0;
|
||||||
|
|
||||||
@ -187,7 +189,9 @@ INTERNAL void spawn_test_entities(struct sim_step_ctx *ctx, struct v2 offset)
|
|||||||
/* Enemy */
|
/* Enemy */
|
||||||
if (ctx->is_master) {
|
if (ctx->is_master) {
|
||||||
struct sim_ent *e = spawn_test_employee(ctx);
|
struct sim_ent *e = spawn_test_employee(ctx);
|
||||||
(UNUSED)e;
|
struct xform xf = sim_ent_get_xform(e);
|
||||||
|
xf.og = offset;
|
||||||
|
sim_ent_set_xform(e, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Big box */
|
/* Big box */
|
||||||
@ -253,88 +257,99 @@ INTERNAL void test_clear_level(struct sim_step_ctx *ctx)
|
|||||||
* Respond to physics collisions
|
* Respond to physics collisions
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, collision_data_array, step_ctx)
|
INTERNAL void on_collision(struct sim_ent *e0, struct sim_ent *e1, struct phys_collision_data *data, struct sim_step_ctx *step_ctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct sim_snapshot *world = step_ctx->world;
|
struct sim_snapshot *world = step_ctx->world;
|
||||||
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);
|
||||||
|
struct phys_contact_constraint *constraint = data->constraint;
|
||||||
|
|
||||||
|
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
||||||
|
|
||||||
|
/* Bullet impact */
|
||||||
|
if (sim_ent_has_prop(e0, SEPROP_BULLET)) {
|
||||||
|
struct v2 normal = data->normal; /* Impact normal */
|
||||||
|
struct v2 vrel = v2_neg(data->vrel); /* Impact velocity */
|
||||||
|
|
||||||
|
struct sim_ent *bullet = e0;
|
||||||
|
struct sim_ent *target = e1;
|
||||||
|
struct sim_ent *src = sim_ent_from_id(world, bullet->bullet_src);
|
||||||
|
|
||||||
|
if (bullet->bullet_has_hit || sim_ent_id_eq(src->top, target->top)) {
|
||||||
|
/* Ignore collision if bullet already spent or if weapon and
|
||||||
|
* target share same top level parent */
|
||||||
|
/* NOTE: Since bullet is most likely just a sensor skip_solve is probably already true */
|
||||||
|
constraint->skip_solve = true;
|
||||||
|
} else {
|
||||||
|
struct v2 point = data->point;
|
||||||
|
|
||||||
|
/* Update tracer */
|
||||||
|
struct sim_ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
|
||||||
|
if (sim_ent_should_simulate(tracer)) {
|
||||||
|
struct xform xf = sim_ent_get_xform(tracer);
|
||||||
|
xf.og = point;
|
||||||
|
sim_ent_set_xform(tracer, xf);
|
||||||
|
sim_ent_set_linear_velocity(tracer, V2(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update target */
|
||||||
|
struct v2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
|
||||||
|
sim_ent_apply_linear_impulse(target, knockback, point);
|
||||||
|
|
||||||
|
/* Create test blood */
|
||||||
|
/* TODO: Remove this */
|
||||||
|
{
|
||||||
|
struct xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU));
|
||||||
|
struct sim_ent *decal = sim_ent_alloc_sync_src(root);
|
||||||
|
decal->sprite = sprite_tag_from_path(LIT("res/graphics/blood.ase"));
|
||||||
|
decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.25f);
|
||||||
|
decal->layer = SIM_LAYER_FLOOR_DECALS;
|
||||||
|
sim_ent_set_xform(decal, xf);
|
||||||
|
|
||||||
|
f32 perp_range = 0.5;
|
||||||
|
struct v2 linear_velocity = v2_mul(normal, 0.5);
|
||||||
|
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rand_f64_from_state(&step_ctx->rand, -perp_range, perp_range)));
|
||||||
|
|
||||||
|
f32 angular_velocity_range = 5;
|
||||||
|
f32 angular_velocity = rand_f64_from_seed(&step_ctx->rand, -angular_velocity_range, angular_velocity_range);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(decal, SEPROP_PHYSICAL_KINEMATIC);
|
||||||
|
sim_ent_set_linear_velocity(decal, linear_velocity);
|
||||||
|
sim_ent_set_angular_velocity(decal, angular_velocity);
|
||||||
|
|
||||||
|
decal->linear_damping = 5.0f;
|
||||||
|
decal->angular_damping = 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create explosion */
|
||||||
|
if (bullet->bullet_impact_explosion_radius > 0) {
|
||||||
|
struct sim_ent *exp = sim_ent_alloc_sync_src(root);
|
||||||
|
sim_ent_set_xform(exp, XFORM_POS(point));
|
||||||
|
|
||||||
|
sim_ent_enable_prop(exp, SEPROP_SENSOR);
|
||||||
|
sim_ent_enable_prop(exp, SEPROP_EXPLOSION);
|
||||||
|
exp->explosion_radius = bullet->bullet_impact_explosion_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update bullet */
|
||||||
|
bullet->bullet_has_hit = true;
|
||||||
|
sim_ent_enable_prop(bullet, SEPROP_RELEASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(pre_solve_callback, collision_data_array, step_ctx)
|
||||||
|
{
|
||||||
|
struct sim_snapshot *world = step_ctx->world;
|
||||||
for (u64 i = 0; i < collision_data_array.count; ++i) {
|
for (u64 i = 0; i < collision_data_array.count; ++i) {
|
||||||
struct phys_collision_data *data = &collision_data_array.a[i];
|
struct phys_collision_data *data = &collision_data_array.a[i];
|
||||||
|
|
||||||
struct phys_contact_constraint *constraint = data->constraint;
|
|
||||||
struct sim_ent *e0 = sim_ent_from_id(world, data->e0);
|
struct sim_ent *e0 = sim_ent_from_id(world, data->e0);
|
||||||
struct sim_ent *e1 = sim_ent_from_id(world, data->e1);
|
struct sim_ent *e1 = sim_ent_from_id(world, data->e1);
|
||||||
|
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
||||||
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
on_collision(e0, e1, data, step_ctx);
|
||||||
/* Bullet hit entity */
|
if (sim_ent_is_valid_and_active(e1) && sim_ent_is_valid_and_active(e0)) {
|
||||||
if (sim_ent_has_prop(e0, SEPROP_BULLET) || sim_ent_has_prop(e1, SEPROP_BULLET)) {
|
on_collision(e1, e0, data, step_ctx);
|
||||||
struct v2 normal = data->normal; /* Impact normal */
|
|
||||||
struct v2 vrel = v2_neg(data->vrel); /* Impact velocity */
|
|
||||||
|
|
||||||
struct sim_ent *target = e0;
|
|
||||||
struct sim_ent *bullet = e1;
|
|
||||||
if (sim_ent_has_prop(e0, SEPROP_BULLET)) {
|
|
||||||
target = e1;
|
|
||||||
bullet = e0;
|
|
||||||
normal = v2_neg(normal);
|
|
||||||
vrel = v2_neg(vrel);
|
|
||||||
}
|
|
||||||
struct sim_ent *src = sim_ent_from_id(world, bullet->bullet_src);
|
|
||||||
|
|
||||||
if (bullet->bullet_has_hit || sim_ent_id_eq(src->top, target->top)) {
|
|
||||||
/* Ignore collision if bullet already spent or if weapon and
|
|
||||||
* target share same top level parent */
|
|
||||||
/* NOTE: Since bullet is most likely just a sensor skip_solve is probably already true */
|
|
||||||
constraint->skip_solve = true;
|
|
||||||
} else {
|
|
||||||
struct v2 point = data->point;
|
|
||||||
|
|
||||||
/* Update tracer */
|
|
||||||
struct sim_ent *tracer = sim_ent_from_id(world, bullet->bullet_tracer);
|
|
||||||
if (sim_ent_should_simulate(tracer)) {
|
|
||||||
struct xform xf = sim_ent_get_xform(tracer);
|
|
||||||
xf.og = point;
|
|
||||||
sim_ent_set_xform(tracer, xf);
|
|
||||||
sim_ent_set_linear_velocity(tracer, V2(0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update target */
|
|
||||||
struct v2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
|
|
||||||
sim_ent_apply_linear_impulse(target, knockback, point);
|
|
||||||
|
|
||||||
/* Explode */
|
|
||||||
//if (sim_ent_has_prop(bullet, SEPROP_EXPLODE_ON_IMPACT)) {
|
|
||||||
//}
|
|
||||||
|
|
||||||
/* Create test blood */
|
|
||||||
/* TODO: Remove this */
|
|
||||||
{
|
|
||||||
struct xform xf = XFORM_TRS(.t = point, .r = rand_f64_from_state(&step_ctx->rand, 0, TAU));
|
|
||||||
struct sim_ent *decal = sim_ent_alloc_sync_src(root);
|
|
||||||
decal->sprite = sprite_tag_from_path(LIT("res/graphics/blood.ase"));
|
|
||||||
decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.25f);
|
|
||||||
decal->layer = SIM_LAYER_FLOOR_DECALS;
|
|
||||||
sim_ent_set_xform(decal, xf);
|
|
||||||
|
|
||||||
f32 perp_range = 0.5;
|
|
||||||
struct v2 linear_velocity = v2_mul(normal, 0.5);
|
|
||||||
linear_velocity = v2_add(linear_velocity, v2_mul(v2_perp(normal), rand_f64_from_state(&step_ctx->rand, -perp_range, perp_range)));
|
|
||||||
|
|
||||||
f32 angular_velocity_range = 5;
|
|
||||||
f32 angular_velocity = rand_f64_from_seed(&step_ctx->rand, -angular_velocity_range, angular_velocity_range);
|
|
||||||
|
|
||||||
sim_ent_enable_prop(decal, SEPROP_PHYSICAL_KINEMATIC);
|
|
||||||
sim_ent_set_linear_velocity(decal, linear_velocity);
|
|
||||||
sim_ent_set_angular_velocity(decal, angular_velocity);
|
|
||||||
|
|
||||||
decal->linear_damping = 5.0f;
|
|
||||||
decal->angular_damping = 5.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update bullet */
|
|
||||||
bullet->bullet_has_hit = true;
|
|
||||||
//sim_ent_enable_prop(bullet, SEPROP_RELEASE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,12 +573,25 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN_TEST)) {
|
if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN_TEST)) {
|
||||||
logf_info("Spawning (test)");
|
logf_info("Spawning (test)");
|
||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 1;
|
f32 spread = 0;
|
||||||
for (u32 j = 0; j < count; ++j) {
|
for (u32 j = 0; j < count; ++j) {
|
||||||
spawn_test_entities(ctx, V2(0, (((f32)j / (f32)count) - 0.5) * spread));
|
struct v2 pos = player->player_cursor_pos;
|
||||||
|
pos.y += (((f32)j / (f32)count) - 0.5) * spread;
|
||||||
|
spawn_test_entities(ctx, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flags & SIM_CONTROL_FLAG_EXPLODE_TEST) {
|
||||||
|
if (!(old_control.flags & SIM_CONTROL_FLAG_EXPLODE_TEST)) {
|
||||||
|
logf_info("Explosion (test)");
|
||||||
|
struct sim_ent *exp = sim_ent_alloc_sync_src(root);
|
||||||
|
sim_ent_set_xform(exp, XFORM_POS(player->player_cursor_pos));
|
||||||
|
|
||||||
|
sim_ent_enable_prop(exp, SEPROP_EXPLOSION);
|
||||||
|
exp->explosion_radius = 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & SIM_CONTROL_FLAG_TILE_TEST) {
|
if (flags & SIM_CONTROL_FLAG_TILE_TEST) {
|
||||||
#if 0
|
#if 0
|
||||||
if (is_master) {
|
if (is_master) {
|
||||||
@ -901,7 +929,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;
|
||||||
@ -951,6 +979,7 @@ 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->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;
|
||||||
@ -1199,10 +1228,64 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
{
|
{
|
||||||
struct phys_step_ctx phys = ZI;
|
struct phys_step_ctx phys = ZI;
|
||||||
phys.sim_step_ctx = ctx;
|
phys.sim_step_ctx = ctx;
|
||||||
phys.pre_solve_callback = on_collision;
|
phys.pre_solve_callback = pre_solve_callback;
|
||||||
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)) {
|
||||||
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
|
if (!sim_ent_has_prop(ent, SEPROP_EXPLOSION_STARTED)) {
|
||||||
|
f32 radius = ent->explosion_radius;
|
||||||
|
sim_ent_enable_prop(ent, SEPROP_EXPLOSION_STARTED);
|
||||||
|
|
||||||
|
struct collider_shape origin_collider = ZI;
|
||||||
|
origin_collider.count = 1;
|
||||||
|
|
||||||
|
struct aabb aabb = ZI;
|
||||||
|
{
|
||||||
|
struct collider_shape radius_collider = ZI;
|
||||||
|
radius_collider.radius = radius;
|
||||||
|
radius_collider.count = 1;
|
||||||
|
ent->local_collider = radius_collider;
|
||||||
|
aabb = collider_aabb_from_collider(&radius_collider, xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find ents in blast range */
|
||||||
|
struct space_iter iter = space_iter_begin_aabb(ctx->accel->space, aabb);
|
||||||
|
struct space_entry *space_entry;
|
||||||
|
while ((space_entry = space_iter_next(&iter))) {
|
||||||
|
struct sim_ent *victim = sim_ent_from_id(world, space_entry->ent);
|
||||||
|
if (sim_ent_should_simulate(victim) && sim_ent_has_prop(victim, SEPROP_PHYSICAL_DYNAMIC) && !sim_ent_id_eq(ent->id, victim->id)) {
|
||||||
|
struct xform victim_xf = sim_ent_get_xform(victim);
|
||||||
|
struct collider_closest_points_result closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
|
||||||
|
struct v2 dir = v2_sub(closest_points.p1, closest_points.p0);
|
||||||
|
f32 distance = v2_len(dir);
|
||||||
|
/* TODO: Blast obstruction */
|
||||||
|
if (distance <= radius) {
|
||||||
|
/* TODO: Exponential decay */
|
||||||
|
//f32 ratio = (radius - distance) / radius;
|
||||||
|
//f32 strength = 100;
|
||||||
|
//struct v2 impulse = v2_with_len(dir, strength * ratio);
|
||||||
|
struct v2 impulse = V2(-100, 0);
|
||||||
|
|
||||||
|
//sim_ent_apply_linear_impulse(victim, impulse, closest_points.p1);
|
||||||
|
sim_ent_apply_linear_impulse_to_center(victim, impulse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
space_iter_end(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update tracers
|
* Update tracers
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -145,6 +145,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
|
|||||||
[SYS_BTN_M4] = USER_BIND_KIND_TILE_TEST,
|
[SYS_BTN_M4] = USER_BIND_KIND_TILE_TEST,
|
||||||
|
|
||||||
[SYS_BTN_M2] = USER_BIND_KIND_DEBUG_DRAG,
|
[SYS_BTN_M2] = USER_BIND_KIND_DEBUG_DRAG,
|
||||||
|
[SYS_BTN_F] = USER_BIND_KIND_DEBUG_EXPLODE,
|
||||||
[SYS_BTN_C] = USER_BIND_KIND_DEBUG_CLEAR,
|
[SYS_BTN_C] = USER_BIND_KIND_DEBUG_CLEAR,
|
||||||
[SYS_BTN_V] = USER_BIND_KIND_DEBUG_SPAWN,
|
[SYS_BTN_V] = USER_BIND_KIND_DEBUG_SPAWN,
|
||||||
[SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP,
|
[SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP,
|
||||||
@ -1590,9 +1591,10 @@ INTERNAL void user_update(void)
|
|||||||
struct bind_state drag_state = G.bind_states[USER_BIND_KIND_DEBUG_DRAG];
|
struct bind_state drag_state = G.bind_states[USER_BIND_KIND_DEBUG_DRAG];
|
||||||
struct bind_state clear_state = G.bind_states[USER_BIND_KIND_DEBUG_CLEAR];
|
struct bind_state clear_state = G.bind_states[USER_BIND_KIND_DEBUG_CLEAR];
|
||||||
struct bind_state spawn_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN];
|
struct bind_state spawn_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN];
|
||||||
struct bind_state tile_state = G.bind_states[USER_BIND_KIND_TILE_TEST];
|
|
||||||
struct bind_state pause_state = G.bind_states[USER_BIND_KIND_DEBUG_PAUSE];
|
struct bind_state pause_state = G.bind_states[USER_BIND_KIND_DEBUG_PAUSE];
|
||||||
struct bind_state step_state = G.bind_states[USER_BIND_KIND_DEBUG_STEP];
|
struct bind_state step_state = G.bind_states[USER_BIND_KIND_DEBUG_STEP];
|
||||||
|
struct bind_state tile_state = G.bind_states[USER_BIND_KIND_TILE_TEST];
|
||||||
|
struct bind_state explode_state = G.bind_states[USER_BIND_KIND_DEBUG_EXPLODE];
|
||||||
|
|
||||||
if (fire_state.num_presses || fire_state.is_held) {
|
if (fire_state.num_presses || fire_state.is_held) {
|
||||||
control.flags |= SIM_CONTROL_FLAG_FIRE;
|
control.flags |= SIM_CONTROL_FLAG_FIRE;
|
||||||
@ -1609,6 +1611,9 @@ INTERNAL void user_update(void)
|
|||||||
if (tile_state.num_presses) {
|
if (tile_state.num_presses) {
|
||||||
control.flags |= SIM_CONTROL_FLAG_TILE_TEST;
|
control.flags |= SIM_CONTROL_FLAG_TILE_TEST;
|
||||||
}
|
}
|
||||||
|
if (explode_state.num_presses) {
|
||||||
|
control.flags |= SIM_CONTROL_FLAG_EXPLODE_TEST;
|
||||||
|
}
|
||||||
|
|
||||||
if (pause_state.num_presses) {
|
if (pause_state.num_presses) {
|
||||||
atomic_i32_eval_xor(&G.user_paused, 1);
|
atomic_i32_eval_xor(&G.user_paused, 1);
|
||||||
|
|||||||
@ -36,6 +36,7 @@ enum user_bind_kind {
|
|||||||
USER_BIND_KIND_DEBUG_PAUSE,
|
USER_BIND_KIND_DEBUG_PAUSE,
|
||||||
USER_BIND_KIND_DEBUG_STEP,
|
USER_BIND_KIND_DEBUG_STEP,
|
||||||
USER_BIND_KIND_DEBUG_DRAG,
|
USER_BIND_KIND_DEBUG_DRAG,
|
||||||
|
USER_BIND_KIND_DEBUG_EXPLODE,
|
||||||
USER_BIND_KIND_FULLSCREEN,
|
USER_BIND_KIND_FULLSCREEN,
|
||||||
USER_BIND_KIND_ZOOM_IN,
|
USER_BIND_KIND_ZOOM_IN,
|
||||||
USER_BIND_KIND_ZOOM_OUT,
|
USER_BIND_KIND_ZOOM_OUT,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user