add collision props that are separate from dynamic & kinematic props
This commit is contained in:
parent
e24591c13c
commit
e4a4e33232
103
src/phys.c
103
src/phys.c
@ -55,7 +55,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) {
|
for (u64 check0_index = 0; check0_index < ss->num_ents_reserved; ++check0_index) {
|
||||||
struct sim_ent *check0 = &ss->ents[check0_index];
|
struct sim_ent *check0 = &ss->ents[check0_index];
|
||||||
if (!sim_ent_is_valid_and_active(check0)) continue;
|
if (!sim_ent_is_valid_and_active(check0)) continue;
|
||||||
if (!(sim_ent_has_prop(check0, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check0, SEPROP_PHYSICAL_KINEMATIC) || sim_ent_has_prop(check0, SEPROP_SENSOR))) continue;
|
if (!(sim_ent_has_prop(check0, SEPROP_SOLID) || sim_ent_has_prop(check0, SEPROP_SENSOR))) continue;
|
||||||
if (check0->local_collider.count <= 0) continue;
|
if (check0->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
struct xform check0_xf = sim_ent_get_xform(check0);
|
struct xform check0_xf = sim_ent_get_xform(check0);
|
||||||
@ -68,7 +68,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent);
|
struct sim_ent *check1 = sim_ent_from_id(ss, space_entry->ent);
|
||||||
if (check1 == check0) continue;
|
if (check1 == check0) continue;
|
||||||
if (!sim_ent_is_valid_and_active(check1)) continue;
|
if (!sim_ent_is_valid_and_active(check1)) continue;
|
||||||
if (!(sim_ent_has_prop(check1, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check1, SEPROP_PHYSICAL_KINEMATIC) || sim_ent_has_prop(check1, SEPROP_SENSOR))) continue;
|
if (!(sim_ent_has_prop(check1, SEPROP_SOLID) || sim_ent_has_prop(check1, SEPROP_SENSOR))) continue;
|
||||||
if (check1->local_collider.count <= 0) continue;
|
if (check1->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
/* Deterministic order based on entity id */
|
/* Deterministic order based on entity id */
|
||||||
@ -117,21 +117,21 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
if (collider_res.num_points > 0) {
|
if (collider_res.num_points > 0) {
|
||||||
if (!constraint_ent->valid) {
|
if (!constraint_ent->valid) {
|
||||||
/* Create constraint */
|
/* Create constraint */
|
||||||
{
|
|
||||||
constraint_ent = sim_ent_alloc_local_with_id(root, constraint_id);
|
constraint_ent = sim_ent_alloc_local_with_id(root, constraint_id);
|
||||||
constraint_ent->contact_constraint_data.e0 = e0->id;
|
constraint_ent->contact_constraint_data.e0 = e0->id;
|
||||||
constraint_ent->contact_constraint_data.e1 = e1->id;
|
constraint_ent->contact_constraint_data.e1 = e1->id;
|
||||||
constraint_ent->contact_constraint_data.skip_solve = sim_ent_has_prop(e0, SEPROP_SENSOR) || sim_ent_has_prop(e1, SEPROP_SENSOR)
|
/* Both entities must be solid and one must be dynamic for a solve to be necessary. */
|
||||||
|| !(sim_ent_has_prop(e0, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SEPROP_PHYSICAL_DYNAMIC));
|
constraint_ent->contact_constraint_data.skip_solve = !sim_ent_has_prop(e0, SEPROP_SOLID) || !sim_ent_has_prop(e1, SEPROP_SOLID) ||
|
||||||
|
!(sim_ent_has_prop(e0, SEPROP_DYNAMIC) || sim_ent_has_prop(e1, SEPROP_DYNAMIC));
|
||||||
sim_ent_enable_prop(constraint_ent, SEPROP_ACTIVE);
|
sim_ent_enable_prop(constraint_ent, SEPROP_ACTIVE);
|
||||||
|
|
||||||
/* TODO: Should we recalculate normal as more contact points are added? */
|
/* TODO: Should we recalculate normal as more contact points are added? */
|
||||||
sim_ent_enable_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT);
|
sim_ent_enable_prop(constraint_ent, SEPROP_CONTACT_CONSTRAINT);
|
||||||
sim_ent_activate(constraint_ent, tick);
|
sim_ent_activate(constraint_ent, tick);
|
||||||
}
|
|
||||||
|
|
||||||
/* Push collision data */
|
/* Push collision data */
|
||||||
if (ctx->pre_solve_callback || ctx->post_solve_callback) {
|
/* TODO: Analyze benefits of calling callback here directly rather than deferring */
|
||||||
|
if (ctx->collision_callback) {
|
||||||
struct phys_collision_data *data = arena_push(arena, struct phys_collision_data);
|
struct phys_collision_data *data = arena_push(arena, struct phys_collision_data);
|
||||||
++res.count;
|
++res.count;
|
||||||
data->constraint = &constraint_ent->contact_constraint_data;
|
data->constraint = &constraint_ent->contact_constraint_data;
|
||||||
@ -287,29 +287,25 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
|
|||||||
|
|
||||||
/* TODO: Cache this */
|
/* TODO: Cache this */
|
||||||
/* Calculate masses */
|
/* Calculate masses */
|
||||||
f32 inv_m0;
|
f32 inv_m0 = 0;
|
||||||
f32 inv_m1;
|
f32 inv_m1 = 0;
|
||||||
f32 inv_i0;
|
f32 inv_i0 = 0;
|
||||||
f32 inv_i1;
|
f32 inv_i1 = 0;
|
||||||
{
|
{
|
||||||
if (sim_ent_should_simulate(e0)) {
|
/* If not simulated locally or ent is not dynamic, pretend contact mass is infinite */
|
||||||
f32 scale0 = math_fabs(xform_get_determinant(e0_xf));
|
if (sim_ent_should_simulate(e0) && sim_ent_has_prop(e0, SEPROP_DYNAMIC)) {
|
||||||
inv_m0 = 1.f / (e0->mass_unscaled * scale0);
|
f32 scale = math_fabs(xform_get_determinant(e0_xf));
|
||||||
inv_i0 = 1.f / (e0->inertia_unscaled * scale0);
|
f32 scaled_mass = e0->mass_unscaled * scale;
|
||||||
} else {
|
f32 scaled_inertia = e0->inertia_unscaled * scale;
|
||||||
/* e0 is not simulated locally, pretend it has infinite mass for this contact */
|
inv_m0 = 1.f / scaled_mass;
|
||||||
inv_m0 = 0;
|
inv_i0 = 1.f / scaled_inertia;
|
||||||
inv_i0 = 0;
|
|
||||||
}
|
}
|
||||||
|
if (sim_ent_should_simulate(e1) && sim_ent_has_prop(e1, SEPROP_DYNAMIC)) {
|
||||||
if (sim_ent_should_simulate(e1)) {
|
f32 scale = math_fabs(xform_get_determinant(e1_xf));
|
||||||
f32 scale1 = math_fabs(xform_get_determinant(e1_xf));
|
f32 scaled_mass = e1->mass_unscaled * scale;
|
||||||
inv_m1 = 1.f / (e1->mass_unscaled * scale1);
|
f32 scaled_inertia = e1->inertia_unscaled * scale;
|
||||||
inv_i1 = 1.f / (e1->inertia_unscaled * scale1);
|
inv_m1 = 1.f / scaled_mass;
|
||||||
} else {
|
inv_i1 = 1.f / scaled_inertia;
|
||||||
/* e0 is not simulated locally, pretend it has infinite mass for this contact */
|
|
||||||
inv_m1 = 0;
|
|
||||||
inv_i1 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -318,15 +314,6 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
|
|||||||
constraint->inv_i0 = inv_i0;
|
constraint->inv_i0 = inv_i0;
|
||||||
constraint->inv_i1 = inv_i1;
|
constraint->inv_i1 = inv_i1;
|
||||||
|
|
||||||
if (!sim_ent_has_prop(e0, SEPROP_PHYSICAL_DYNAMIC)) {
|
|
||||||
constraint->inv_m0 = 0;
|
|
||||||
constraint->inv_i0 = 0;
|
|
||||||
}
|
|
||||||
if (!sim_ent_has_prop(e1, SEPROP_PHYSICAL_DYNAMIC)) {
|
|
||||||
constraint->inv_m1 = 0;
|
|
||||||
constraint->inv_i1 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update / insert returned contacts */
|
/* Update / insert returned contacts */
|
||||||
for (u32 i = 0; i < num_points; ++i) {
|
for (u32 i = 0; i < num_points; ++i) {
|
||||||
struct phys_contact_point *contact = &constraint->points[i];
|
struct phys_contact_point *contact = &constraint->points[i];
|
||||||
@ -375,9 +362,9 @@ void phys_prepare_contacts(struct phys_step_ctx *ctx, u64 phys_iteration)
|
|||||||
struct sim_ent *e0 = sim_ent_from_id(ss, dbg->e0);
|
struct sim_ent *e0 = sim_ent_from_id(ss, dbg->e0);
|
||||||
struct sim_ent *e1 = sim_ent_from_id(ss, dbg->e1);
|
struct sim_ent *e1 = sim_ent_from_id(ss, dbg->e1);
|
||||||
|
|
||||||
if (!sim_ent_should_simulate(e0) || !sim_ent_should_simulate(e1)
|
if (!(sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) ||
|
||||||
|| !(sim_ent_has_prop(e0, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SEPROP_PHYSICAL_KINEMATIC) || !sim_ent_has_prop(e0, SEPROP_SENSOR))
|
!(sim_ent_has_prop(e0, SEPROP_SOLID) || sim_ent_has_prop(e0, SEPROP_SENSOR)) ||
|
||||||
|| !(sim_ent_has_prop(e1, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SEPROP_PHYSICAL_KINEMATIC) || !sim_ent_has_prop(e1, SEPROP_SENSOR))) {
|
!(sim_ent_has_prop(e1, SEPROP_SOLID) || sim_ent_has_prop(e1, SEPROP_SENSOR))) {
|
||||||
/* Mark dbg ent for removal */
|
/* Mark dbg ent for removal */
|
||||||
sim_ent_disable_prop(dbg_ent, SEPROP_ACTIVE);
|
sim_ent_disable_prop(dbg_ent, SEPROP_ACTIVE);
|
||||||
sim_ent_enable_prop(dbg_ent, SEPROP_RELEASE);
|
sim_ent_enable_prop(dbg_ent, SEPROP_RELEASE);
|
||||||
@ -926,8 +913,8 @@ void phys_integrate_forces(struct phys_step_ctx *ctx, f32 dt)
|
|||||||
struct sim_ent *ent = &ss->ents[sim_ent_index];
|
struct sim_ent *ent = &ss->ents[sim_ent_index];
|
||||||
if (!sim_ent_should_simulate(ent)) continue;
|
if (!sim_ent_should_simulate(ent)) continue;
|
||||||
|
|
||||||
b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_PHYSICAL_DYNAMIC);
|
b32 is_dynamic = sim_ent_has_prop(ent, SEPROP_DYNAMIC);
|
||||||
b32 is_kinematic = sim_ent_has_prop(ent, SEPROP_PHYSICAL_KINEMATIC);
|
b32 is_kinematic = sim_ent_has_prop(ent, SEPROP_KINEMATIC);
|
||||||
if (is_dynamic || is_kinematic) {
|
if (is_dynamic || is_kinematic) {
|
||||||
struct v2 linear_velocity = ent->linear_velocity;
|
struct v2 linear_velocity = ent->linear_velocity;
|
||||||
f32 angular_velocity = ent->angular_velocity;
|
f32 angular_velocity = ent->angular_velocity;
|
||||||
@ -967,7 +954,7 @@ void phys_integrate_velocities(struct phys_step_ctx *ctx, f32 dt)
|
|||||||
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_should_simulate(ent)) continue;
|
if (!sim_ent_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SEPROP_PHYSICAL_DYNAMIC) && !sim_ent_has_prop(ent, SEPROP_PHYSICAL_KINEMATIC)) continue;
|
if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC) && !sim_ent_has_prop(ent, SEPROP_KINEMATIC)) continue;
|
||||||
|
|
||||||
struct xform xf = get_derived_xform(ent, dt);
|
struct xform xf = get_derived_xform(ent, dt);
|
||||||
sim_ent_set_xform(ent, xf);
|
sim_ent_set_xform(ent, xf);
|
||||||
@ -978,7 +965,7 @@ void phys_integrate_velocities(struct phys_step_ctx *ctx, f32 dt)
|
|||||||
* Earliest time of impact
|
* Earliest time of impact
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations)
|
f32 phys_determine_earliest_toi(struct phys_step_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
struct sim_snapshot *ss = ctx->sim_step_ctx->world;
|
||||||
@ -988,8 +975,8 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_
|
|||||||
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
|
for (u64 e0_index = 0; e0_index < ss->num_ents_reserved; ++e0_index) {
|
||||||
struct sim_ent *e0 = &ss->ents[e0_index];
|
struct sim_ent *e0 = &ss->ents[e0_index];
|
||||||
if (!sim_ent_should_simulate(e0)) continue;
|
if (!sim_ent_should_simulate(e0)) continue;
|
||||||
if (!(sim_ent_has_prop(e0, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SEPROP_PHYSICAL_KINEMATIC) || sim_ent_has_prop(e0, SEPROP_SENSOR))) continue;
|
if (!(sim_ent_has_prop(e0, SEPROP_SOLID) || sim_ent_has_prop(e0, SEPROP_SENSOR))) continue;
|
||||||
if (!sim_ent_has_prop(e0, SEPROP_BULLET)) continue;
|
if (!sim_ent_has_prop(e0, SEPROP_TOI)) continue;
|
||||||
if (e0->local_collider.count <= 0) continue;
|
if (e0->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
struct collider_shape e0_collider = e0->local_collider;
|
struct collider_shape e0_collider = e0->local_collider;
|
||||||
@ -1007,7 +994,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_
|
|||||||
struct sim_ent *e1 = sim_ent_from_id(ss, entry->ent);
|
struct sim_ent *e1 = sim_ent_from_id(ss, entry->ent);
|
||||||
if (e1 == e0) continue;
|
if (e1 == e0) continue;
|
||||||
if (!sim_ent_should_simulate(e1)) continue;
|
if (!sim_ent_should_simulate(e1)) continue;
|
||||||
if (!(sim_ent_has_prop(e1, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SEPROP_PHYSICAL_KINEMATIC) || sim_ent_has_prop(e1, SEPROP_SENSOR))) continue;
|
if (!(sim_ent_has_prop(e1, SEPROP_SOLID) || sim_ent_has_prop(e1, SEPROP_SENSOR))) continue;
|
||||||
if (e1->local_collider.count <= 0) continue;
|
if (e1->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
struct collider_shape e1_collider = e1->local_collider;
|
struct collider_shape e1_collider = e1->local_collider;
|
||||||
@ -1056,6 +1043,7 @@ void phys_update_aabbs(struct phys_step_ctx *ctx)
|
|||||||
|
|
||||||
INTERNAL void run_collision_callbacks(struct phys_step_ctx *ctx, phys_collision_callback_func *callback, struct phys_collision_data_array collision_data)
|
INTERNAL void run_collision_callbacks(struct phys_step_ctx *ctx, phys_collision_callback_func *callback, struct phys_collision_data_array collision_data)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
struct sim_step_ctx *sim_step_ctx = ctx->sim_step_ctx;
|
struct sim_step_ctx *sim_step_ctx = ctx->sim_step_ctx;
|
||||||
for (u64 i = 0; i < collision_data.count; ++i) {
|
for (u64 i = 0; i < collision_data.count; ++i) {
|
||||||
/* Collision data from e0's perspective */
|
/* Collision data from e0's perspective */
|
||||||
@ -1069,8 +1057,11 @@ INTERNAL void run_collision_callbacks(struct phys_step_ctx *ctx, phys_collision_
|
|||||||
data_inverted.vrel = v2_neg(data->vrel);
|
data_inverted.vrel = v2_neg(data->vrel);
|
||||||
|
|
||||||
/* Run callback twice for both e0 & e1 */
|
/* Run callback twice for both e0 & e1 */
|
||||||
callback(data, sim_step_ctx);
|
b32 skip_solve0 = callback(data, sim_step_ctx);
|
||||||
callback(&data_inverted, sim_step_ctx);
|
b32 skip_solve1 = callback(&data_inverted, sim_step_ctx);
|
||||||
|
if (skip_solve0 || skip_solve1) {
|
||||||
|
data->constraint->skip_solve = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,10 +1088,10 @@ void phys_step(struct phys_step_ctx *ctx, f32 timestep)
|
|||||||
const f32 min_toi = 0.000001f;
|
const f32 min_toi = 0.000001f;
|
||||||
const f32 tolerance = 0.0001f;
|
const f32 tolerance = 0.0001f;
|
||||||
const u32 max_iterations = 16;
|
const u32 max_iterations = 16;
|
||||||
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi);
|
f32 earliest_toi = max_f32(phys_determine_earliest_toi(ctx, step_dt, tolerance, max_iterations), min_toi);
|
||||||
step_dt = remaining_dt * earliest_toi;
|
step_dt = remaining_dt * earliest_toi;
|
||||||
#else
|
#else
|
||||||
(UNUSED)phys_determine_earliest_toi_for_bullets;
|
(UNUSED)phys_determine_earliest_toi;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
remaining_dt -= step_dt;
|
remaining_dt -= step_dt;
|
||||||
@ -1111,9 +1102,8 @@ void phys_step(struct phys_step_ctx *ctx, f32 timestep)
|
|||||||
phys_prepare_motor_joints(ctx);
|
phys_prepare_motor_joints(ctx);
|
||||||
phys_prepare_mouse_joints(ctx);
|
phys_prepare_mouse_joints(ctx);
|
||||||
|
|
||||||
if (ctx->pre_solve_callback) {
|
if (ctx->collision_callback) {
|
||||||
__profscope(pre_solve_callback);
|
run_collision_callbacks(ctx, ctx->collision_callback, collision_data);
|
||||||
run_collision_callbacks(ctx, ctx->pre_solve_callback, collision_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 substep_dt = step_dt / SIM_PHYSICS_SUBSTEPS;
|
f32 substep_dt = step_dt / SIM_PHYSICS_SUBSTEPS;
|
||||||
@ -1145,11 +1135,6 @@ void phys_step(struct phys_step_ctx *ctx, f32 timestep)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->post_solve_callback) {
|
|
||||||
__profscope(post_solve_callback);
|
|
||||||
run_collision_callbacks(ctx, ctx->post_solve_callback, collision_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,15 +25,14 @@ struct phys_collision_data_array {
|
|||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct phys_collision_data;
|
/* Callback can return true to prevent the physics system from resolving */
|
||||||
#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg_collision_data, arg_sim_step_ctx) void name(struct phys_collision_data *arg_collision_data, struct sim_step_ctx *arg_sim_step_ctx)
|
#define PHYS_COLLISION_CALLBACK_FUNC_DEF(name, arg_collision_data, arg_sim_step_ctx) b32 name(struct phys_collision_data *arg_collision_data, struct sim_step_ctx *arg_sim_step_ctx)
|
||||||
typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, collision_data, ctx);
|
typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, collision_data, ctx);
|
||||||
|
|
||||||
/* Structure containing data used for a single physics step */
|
/* Structure containing data used for a single physics step */
|
||||||
struct phys_step_ctx {
|
struct phys_step_ctx {
|
||||||
struct sim_step_ctx *sim_step_ctx;
|
struct sim_step_ctx *sim_step_ctx;
|
||||||
phys_collision_callback_func *pre_solve_callback;
|
phys_collision_callback_func *collision_callback;
|
||||||
phys_collision_callback_func *post_solve_callback;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -190,7 +189,7 @@ void phys_integrate_velocities(struct phys_step_ctx *ctx, f32 dt);
|
|||||||
* Earliest time of impact
|
* Earliest time of impact
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
f32 phys_determine_earliest_toi_for_bullets(struct phys_step_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations);
|
f32 phys_determine_earliest_toi(struct phys_step_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Space
|
* Space
|
||||||
|
|||||||
@ -501,6 +501,7 @@ void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf)
|
|||||||
|
|
||||||
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 point)
|
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 point)
|
||||||
{
|
{
|
||||||
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
struct xform xf = sim_ent_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
struct v2 center = xf.og;
|
struct v2 center = xf.og;
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(xform_get_determinant(xf));
|
||||||
@ -510,33 +511,42 @@ void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct
|
|||||||
struct v2 vcp = v2_sub(point, center);
|
struct v2 vcp = v2_sub(point, center);
|
||||||
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
||||||
sim_ent_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
|
sim_ent_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse)
|
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse)
|
||||||
{
|
{
|
||||||
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
struct xform xf = sim_ent_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(xform_get_determinant(xf));
|
||||||
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
||||||
|
|
||||||
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force)
|
void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force)
|
||||||
{
|
{
|
||||||
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
ent->force = v2_add(ent->force, force);
|
ent->force = v2_add(ent->force, force);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse)
|
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse)
|
||||||
{
|
{
|
||||||
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
struct xform xf = sim_ent_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(xform_get_determinant(xf));
|
||||||
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
||||||
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
|
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque)
|
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque)
|
||||||
{
|
{
|
||||||
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC)) {
|
||||||
ent->torque += torque;
|
ent->torque += torque;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
@ -16,8 +16,8 @@ enum sim_ent_prop {
|
|||||||
SEPROP_ACTIVE,
|
SEPROP_ACTIVE,
|
||||||
SEPROP_RELEASE,
|
SEPROP_RELEASE,
|
||||||
|
|
||||||
SEPROP_SYNC_SRC, /* This entity should be networked to other clients */
|
SEPROP_SYNC_SRC, /* This entity is networked to other clients */
|
||||||
SEPROP_SYNC_DST, /* This entity is not locally created, and should sync with incoming net src ents */
|
SEPROP_SYNC_DST, /* This entity is not locally created, and will sync with incoming net src ents */
|
||||||
|
|
||||||
SEPROP_PLAYER,
|
SEPROP_PLAYER,
|
||||||
SEPROP_PLAYER_IS_MASTER,
|
SEPROP_PLAYER_IS_MASTER,
|
||||||
@ -26,8 +26,14 @@ enum sim_ent_prop {
|
|||||||
|
|
||||||
SEPROP_TILE_CHUNK,
|
SEPROP_TILE_CHUNK,
|
||||||
|
|
||||||
SEPROP_PHYSICAL_DYNAMIC,
|
/* Physics collision */
|
||||||
SEPROP_PHYSICAL_KINEMATIC,
|
SEPROP_SENSOR, /* This entity's collisions generate contacts */
|
||||||
|
SEPROP_SOLID, /* This entity's collisions generate contacts to be solved by the physics system (overrides SEPROP_SENSOR) */
|
||||||
|
SEPROP_TOI, /* This entity's collisions are processed using TOI (time of impact) for precise collisions */
|
||||||
|
|
||||||
|
/* Physics movement */
|
||||||
|
SEPROP_KINEMATIC, /* This entity reacts to velocity */
|
||||||
|
SEPROP_DYNAMIC, /* This entity reacts to velocity and forces (overrides SEPROP_KINEMATIC) */
|
||||||
|
|
||||||
SEPROP_CONTROLLED,
|
SEPROP_CONTROLLED,
|
||||||
|
|
||||||
@ -35,11 +41,11 @@ enum sim_ent_prop {
|
|||||||
SEPROP_CONTACT_CONSTRAINT,
|
SEPROP_CONTACT_CONSTRAINT,
|
||||||
SEPROP_MOTOR_JOINT,
|
SEPROP_MOTOR_JOINT,
|
||||||
SEPROP_MOUSE_JOINT,
|
SEPROP_MOUSE_JOINT,
|
||||||
SEPROP_SENSOR,
|
|
||||||
|
|
||||||
SEPROP_CAMERA,
|
SEPROP_CAMERA,
|
||||||
SEPROP_CAMERA_ACTIVE,
|
SEPROP_CAMERA_ACTIVE,
|
||||||
|
|
||||||
|
SEPROP_BULLET,
|
||||||
SEPROP_WEAPON_SMG,
|
SEPROP_WEAPON_SMG,
|
||||||
SEPROP_WEAPON_LAUNCHER,
|
SEPROP_WEAPON_LAUNCHER,
|
||||||
|
|
||||||
@ -49,7 +55,6 @@ enum sim_ent_prop {
|
|||||||
|
|
||||||
SEPROP_EXPLOSION,
|
SEPROP_EXPLOSION,
|
||||||
|
|
||||||
SEPROP_BULLET,
|
|
||||||
SEPROP_TRACER,
|
SEPROP_TRACER,
|
||||||
|
|
||||||
SEPROP_QUAKE,
|
SEPROP_QUAKE,
|
||||||
@ -226,7 +231,7 @@ struct sim_ent {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Physics */
|
/* Physics */
|
||||||
|
|
||||||
/* SEPROP_PHYSICAL_DYNAMIC */
|
/* SEPROP_DYNAMIC */
|
||||||
|
|
||||||
//f32 density; /* Density in kg/m^2 */
|
//f32 density; /* Density in kg/m^2 */
|
||||||
|
|
||||||
@ -293,10 +298,10 @@ struct sim_ent {
|
|||||||
struct sim_ent_id bullet_tracer;
|
struct sim_ent_id bullet_tracer;
|
||||||
struct v2 bullet_src_pos;
|
struct v2 bullet_src_pos;
|
||||||
struct v2 bullet_src_dir;
|
struct v2 bullet_src_dir;
|
||||||
f32 bullet_impulse;
|
f32 bullet_launch_velocity;
|
||||||
f32 bullet_knockback;
|
f32 bullet_knockback;
|
||||||
f32 bullet_impact_explosion_strength;
|
f32 bullet_explosion_strength;
|
||||||
f32 bullet_impact_explosion_radius;
|
f32 bullet_explosion_radius;
|
||||||
b32 bullet_has_hit;
|
b32 bullet_has_hit;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
|
|||||||
@ -106,7 +106,8 @@ INTERNAL struct sim_ent *spawn_test_employee(struct sim_step_ctx *ctx)
|
|||||||
//e->control_torque = 5000;
|
//e->control_torque = 5000;
|
||||||
e->control_torque = F32_INFINITY;
|
e->control_torque = F32_INFINITY;
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_PHYSICAL_DYNAMIC);
|
sim_ent_enable_prop(e, SEPROP_DYNAMIC);
|
||||||
|
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||||
|
|
||||||
employee = e;
|
employee = e;
|
||||||
}
|
}
|
||||||
@ -218,7 +219,9 @@ INTERNAL void spawn_test_entities2(struct sim_step_ctx *ctx, struct v2 pos)
|
|||||||
e->sprite_collider_slice = LIT("shape");
|
e->sprite_collider_slice = LIT("shape");
|
||||||
e->layer = SIM_LAYER_SHOULDERS;
|
e->layer = SIM_LAYER_SHOULDERS;
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_PHYSICAL_DYNAMIC);
|
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(e, SEPROP_DYNAMIC);
|
||||||
e->mass_unscaled = 100;
|
e->mass_unscaled = 100;
|
||||||
e->inertia_unscaled = 50;
|
e->inertia_unscaled = 50;
|
||||||
e->linear_ground_friction = 100;
|
e->linear_ground_friction = 100;
|
||||||
@ -240,7 +243,9 @@ INTERNAL void spawn_test_entities2(struct sim_step_ctx *ctx, struct v2 pos)
|
|||||||
e->sprite_collider_slice = LIT("shape");
|
e->sprite_collider_slice = LIT("shape");
|
||||||
e->layer = SIM_LAYER_SHOULDERS;
|
e->layer = SIM_LAYER_SHOULDERS;
|
||||||
|
|
||||||
sim_ent_enable_prop(e, SEPROP_PHYSICAL_DYNAMIC);
|
sim_ent_enable_prop(e, SEPROP_SOLID);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(e, SEPROP_DYNAMIC);
|
||||||
e->mass_unscaled = 0.5;
|
e->mass_unscaled = 0.5;
|
||||||
e->inertia_unscaled = 1000;
|
e->inertia_unscaled = 1000;
|
||||||
e->linear_ground_friction = 0.001;
|
e->linear_ground_friction = 0.001;
|
||||||
@ -269,6 +274,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
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);
|
||||||
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);
|
||||||
|
b32 skip_solve = false;
|
||||||
|
|
||||||
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
if (sim_ent_should_simulate(e0) && sim_ent_should_simulate(e1)) {
|
||||||
/* Bullet impact */
|
/* Bullet impact */
|
||||||
@ -281,7 +287,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
struct sim_ent *src = sim_ent_from_id(world, bullet->bullet_src);
|
struct sim_ent *src = sim_ent_from_id(world, bullet->bullet_src);
|
||||||
|
|
||||||
/* Process collision if bullet already spent or * target share same top level parent */
|
/* Process collision if bullet already spent or * target share same top level parent */
|
||||||
if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top)) {
|
if (!bullet->bullet_has_hit && !sim_ent_id_eq(src->top, target->top) && sim_ent_has_prop(target, SEPROP_SOLID)) {
|
||||||
struct v2 point = data->point;
|
struct v2 point = data->point;
|
||||||
|
|
||||||
/* Update tracer */
|
/* Update tracer */
|
||||||
@ -314,7 +320,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
f32 angular_velocity_range = 5;
|
f32 angular_velocity_range = 5;
|
||||||
f32 angular_velocity = rand_f64_from_seed(&step_ctx->rand, -angular_velocity_range, angular_velocity_range);
|
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_enable_prop(decal, SEPROP_KINEMATIC);
|
||||||
sim_ent_set_linear_velocity(decal, linear_velocity);
|
sim_ent_set_linear_velocity(decal, linear_velocity);
|
||||||
sim_ent_set_angular_velocity(decal, angular_velocity);
|
sim_ent_set_angular_velocity(decal, angular_velocity);
|
||||||
|
|
||||||
@ -323,8 +329,8 @@ 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_explosion_strength > 0) {
|
||||||
spawn_test_explosion(world, point, bullet->bullet_impact_explosion_strength, bullet->bullet_impact_explosion_radius);
|
spawn_test_explosion(world, point, bullet->bullet_explosion_strength, bullet->bullet_explosion_radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update bullet */
|
/* Update bullet */
|
||||||
@ -347,12 +353,17 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
struct collider_closest_points_result closest_points = collider_closest_points(&origin_collider, &victim->local_collider, xf, victim_xf);
|
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);
|
struct v2 dir = v2_sub(closest_points.p1, closest_points.p0);
|
||||||
f32 distance = v2_len(dir);
|
f32 distance = v2_len(dir);
|
||||||
|
#if 0
|
||||||
if (closest_points.colliding) {
|
if (closest_points.colliding) {
|
||||||
dir = v2_neg(dir);
|
dir = v2_neg(dir);
|
||||||
distance = 0;
|
//distance = 0;
|
||||||
} else {
|
|
||||||
distance = v2_len(dir);
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (v2_dot(data->normal, dir) < 0) {
|
||||||
|
dir = v2_neg(dir);
|
||||||
|
distance = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: Blast obstruction */
|
/* TODO: Blast obstruction */
|
||||||
f32 radius = exp->explosion_radius;
|
f32 radius = exp->explosion_radius;
|
||||||
@ -365,6 +376,8 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, data, step_ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return skip_solve;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -948,14 +961,13 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
{
|
{
|
||||||
bullet = sim_ent_alloc_sync_src(root);
|
bullet = sim_ent_alloc_sync_src(root);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(bullet, SEPROP_BULLET);
|
||||||
bullet->bullet_src = ent->id;
|
bullet->bullet_src = ent->id;
|
||||||
bullet->bullet_src_pos = rel_pos;
|
bullet->bullet_src_pos = rel_pos;
|
||||||
bullet->bullet_src_dir = rel_dir;
|
bullet->bullet_src_dir = rel_dir;
|
||||||
//bullet->bullet_impulse = 0.75f;
|
//bullet->bullet_launch_velocity = 0.75f;
|
||||||
bullet->bullet_impulse = 2.0f;
|
bullet->bullet_launch_velocity = 50.0f;
|
||||||
bullet->bullet_knockback = 10;
|
bullet->bullet_knockback = 10;
|
||||||
bullet->mass_unscaled = 0.04f;
|
|
||||||
bullet->inertia_unscaled = 0.00001f;
|
|
||||||
bullet->layer = SIM_LAYER_BULLETS;
|
bullet->layer = SIM_LAYER_BULLETS;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@ -966,9 +978,6 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase"));
|
bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase"));
|
||||||
bullet->sprite_collider_slice = LIT("shape");
|
bullet->sprite_collider_slice = LIT("shape");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sim_ent_enable_prop(bullet, SEPROP_BULLET);
|
|
||||||
sim_ent_enable_prop(bullet, SEPROP_SENSOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spawn tracer */
|
/* Spawn tracer */
|
||||||
@ -997,16 +1006,15 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
{
|
{
|
||||||
bullet = sim_ent_alloc_sync_src(root);
|
bullet = sim_ent_alloc_sync_src(root);
|
||||||
|
|
||||||
|
sim_ent_enable_prop(bullet, SEPROP_BULLET);
|
||||||
bullet->bullet_src = ent->id;
|
bullet->bullet_src = ent->id;
|
||||||
bullet->bullet_src_pos = rel_pos;
|
bullet->bullet_src_pos = rel_pos;
|
||||||
bullet->bullet_src_dir = rel_dir;
|
bullet->bullet_src_dir = rel_dir;
|
||||||
//bullet->bullet_impulse = 0.75f;
|
//bullet->bullet_launch_velocity = 0.75f;
|
||||||
bullet->bullet_impulse = 0.75;
|
bullet->bullet_launch_velocity = 15;
|
||||||
bullet->bullet_knockback = 10;
|
bullet->bullet_knockback = 50;
|
||||||
bullet->bullet_impact_explosion_strength = 200;
|
bullet->bullet_explosion_strength = 100;
|
||||||
bullet->bullet_impact_explosion_radius = 4.0;
|
bullet->bullet_explosion_radius = 4;
|
||||||
bullet->mass_unscaled = 0.04f;
|
|
||||||
bullet->inertia_unscaled = 0.00001f;
|
|
||||||
bullet->layer = SIM_LAYER_BULLETS;
|
bullet->layer = SIM_LAYER_BULLETS;
|
||||||
|
|
||||||
/* Point collider */
|
/* Point collider */
|
||||||
@ -1014,8 +1022,6 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
bullet->local_collider.count = 1;
|
bullet->local_collider.count = 1;
|
||||||
bullet->local_collider.radius = 0.05;
|
bullet->local_collider.radius = 0.05;
|
||||||
|
|
||||||
sim_ent_enable_prop(bullet, SEPROP_BULLET);
|
|
||||||
sim_ent_enable_prop(bullet, SEPROP_SENSOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spawn tracer */
|
/* Spawn tracer */
|
||||||
@ -1085,7 +1091,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
joint_ent->predictor = ent->predictor;
|
joint_ent->predictor = ent->predictor;
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_PHYSICAL_KINEMATIC); /* Since we'll be setting velocity manually */
|
sim_ent_enable_prop(joint_ent, SEPROP_KINEMATIC); /* Since we'll be setting velocity manually */
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_MOTOR_JOINT);
|
sim_ent_enable_prop(joint_ent, SEPROP_MOTOR_JOINT);
|
||||||
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SEPROP_ACTIVE);
|
||||||
ent->aim_joint = joint_ent->id;
|
ent->aim_joint = joint_ent->id;
|
||||||
@ -1171,7 +1177,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
|
||||||
struct sim_ent *ent = &world->ents[ent_index];
|
struct sim_ent *ent = &world->ents[ent_index];
|
||||||
if (!sim_ent_should_simulate(ent)) continue;
|
if (!sim_ent_should_simulate(ent)) continue;
|
||||||
if (!sim_ent_has_prop(ent, SEPROP_PHYSICAL_DYNAMIC)) continue;
|
if (!sim_ent_has_prop(ent, SEPROP_DYNAMIC)) continue;
|
||||||
|
|
||||||
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint);
|
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->ground_friction_joint);
|
||||||
|
|
||||||
@ -1253,7 +1259,7 @@ 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.collision_callback = on_collision;
|
||||||
phys_step(&phys, sim_dt);
|
phys_step(&phys, sim_dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1267,7 +1273,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
if (!sim_ent_has_prop(ent, SEPROP_EXPLOSION)) continue;
|
if (!sim_ent_has_prop(ent, SEPROP_EXPLOSION)) continue;
|
||||||
|
|
||||||
/* Explosion doesn't need to generate any more collisions after initial physics step */
|
/* Explosion doesn't need to generate any more collisions after initial physics step */
|
||||||
//sim_ent_disable_prop(ent, SEPROP_SENSOR);
|
sim_ent_disable_prop(ent, SEPROP_SENSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -1307,9 +1313,13 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
struct sim_ent *src = sim_ent_from_id(world, ent->bullet_src);
|
struct sim_ent *src = sim_ent_from_id(world, ent->bullet_src);
|
||||||
struct xform src_xf = sim_ent_get_xform(src);
|
struct xform src_xf = sim_ent_get_xform(src);
|
||||||
|
|
||||||
|
/* Activate collision */
|
||||||
|
sim_ent_enable_prop(ent, SEPROP_SENSOR);
|
||||||
|
sim_ent_enable_prop(ent, SEPROP_TOI);
|
||||||
|
|
||||||
struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
|
struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
|
||||||
struct v2 impulse = xform_basis_mul_v2(src_xf, ent->bullet_src_dir);
|
struct v2 vel = xform_basis_mul_v2(src_xf, ent->bullet_src_dir);
|
||||||
impulse = v2_with_len(impulse, ent->bullet_impulse);
|
vel = v2_with_len(vel, ent->bullet_launch_velocity);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Add shooter velocity to bullet */
|
/* Add shooter velocity to bullet */
|
||||||
@ -1320,17 +1330,17 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(impulse) + PI / 2);
|
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(vel) + PI / 2);
|
||||||
sim_ent_set_xform(ent, xf);
|
sim_ent_set_xform(ent, xf);
|
||||||
sim_ent_enable_prop(ent, SEPROP_PHYSICAL_KINEMATIC);
|
|
||||||
|
|
||||||
sim_ent_apply_linear_impulse_to_center(ent, impulse);
|
sim_ent_enable_prop(ent, SEPROP_KINEMATIC);
|
||||||
|
sim_ent_set_linear_velocity(ent, vel);
|
||||||
|
|
||||||
/* Initialize tracer */
|
/* Initialize tracer */
|
||||||
struct sim_ent *tracer = sim_ent_from_id(world, ent->bullet_tracer);
|
struct sim_ent *tracer = sim_ent_from_id(world, ent->bullet_tracer);
|
||||||
if (sim_ent_should_simulate(tracer)) {
|
if (sim_ent_should_simulate(tracer)) {
|
||||||
sim_ent_set_xform(tracer, xf);
|
sim_ent_set_xform(tracer, xf);
|
||||||
sim_ent_enable_prop(tracer, SEPROP_PHYSICAL_KINEMATIC);
|
sim_ent_enable_prop(tracer, SEPROP_KINEMATIC);
|
||||||
sim_ent_set_linear_velocity(tracer, ent->linear_velocity);
|
sim_ent_set_linear_velocity(tracer, ent->linear_velocity);
|
||||||
tracer->tracer_start = pos;
|
tracer->tracer_start = pos;
|
||||||
tracer->tracer_start_velocity = ent->linear_velocity;
|
tracer->tracer_start_velocity = ent->linear_velocity;
|
||||||
|
|||||||
@ -1102,7 +1102,7 @@ INTERNAL void user_update(void)
|
|||||||
if (G.debug_draw && !skip_debug_draw) {
|
if (G.debug_draw && !skip_debug_draw) {
|
||||||
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
||||||
|
|
||||||
if (sim_ent_has_prop(ent, SEPROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(ent, SEPROP_PHYSICAL_KINEMATIC)) {
|
if (sim_ent_has_prop(ent, SEPROP_DYNAMIC) || sim_ent_has_prop(ent, SEPROP_KINEMATIC)) {
|
||||||
debug_draw_movement(ent);
|
debug_draw_movement(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user