bullet knockback. physics damping.

This commit is contained in:
jacob 2025-01-13 08:46:11 -06:00
parent 33ad436040
commit 5b29d4f36e
5 changed files with 127 additions and 121 deletions

View File

@ -304,23 +304,17 @@ void entity_apply_linear_impulse(struct entity *ent, struct v2 impulse, struct v
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale); f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
struct v2 vcp = v2_sub(point, center); struct v2 vcp = v2_sub(point, center);
ent->linear_velocity = v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)); entity_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
ent->angular_velocity += v2_wedge(vcp, impulse) * inv_inertia; entity_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
} }
#if 0
void entity_apply_force(struct entity *ent, struct v2 impulse, struct v2 world_point)
{
}
#endif
void entity_apply_linear_impulse_to_center(struct entity *ent, struct v2 impulse) void entity_apply_linear_impulse_to_center(struct entity *ent, struct v2 impulse)
{ {
struct xform xf = entity_get_xform(ent); struct xform xf = entity_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);
ent->linear_velocity = v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)); entity_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
} }
void entity_apply_force_to_center(struct entity *ent, struct v2 force) void entity_apply_force_to_center(struct entity *ent, struct v2 force)
@ -333,8 +327,7 @@ void entity_apply_angular_impulse(struct entity *ent, f32 impulse)
struct xform xf = entity_get_xform(ent); struct xform xf = entity_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);
entity_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
ent->angular_velocity += impulse * inv_inertia;
} }
void entity_apply_torque(struct entity *ent, f32 torque) void entity_apply_torque(struct entity *ent, f32 torque)

View File

@ -175,12 +175,16 @@ struct entity {
f32 linear_ground_friction; f32 linear_ground_friction;
f32 angular_ground_friction; f32 angular_ground_friction;
/* Use entity_set_linear_velocity & entity_set_angular_velocity to set */
struct v2 linear_velocity; /* m/s */ struct v2 linear_velocity; /* m/s */
f32 angular_velocity; /* rad/s */ f32 angular_velocity; /* rad/s */
struct v2 force; struct v2 force;
f32 torque; f32 torque;
f32 linear_damping;
f32 angular_damping;
/* ====================================================================== */ /* ====================================================================== */
/* Sprite */ /* Sprite */
@ -226,6 +230,7 @@ struct entity {
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_impulse;
f32 bullet_knockback;
b32 bullet_has_hit; b32 bullet_has_hit;
/* ====================================================================== */ /* ====================================================================== */
@ -356,8 +361,9 @@ void entity_set_xform(struct entity *ent, struct xform xf);
void entity_set_local_xform(struct entity *ent, struct xform xf); void entity_set_local_xform(struct entity *ent, struct xform xf);
/* Movement */ /* Movement */
INLINE void entity_set_linear_velocity(struct entity *ent, struct v2 velocity) { ent->linear_velocity = v2_clamp_len(velocity, GAME_MAX_LINEAR_VELOCITY); }
INLINE void entity_set_angular_velocity(struct entity *ent, f32 velocity) { ent->angular_velocity = clamp_f32(velocity, -GAME_MAX_ANGULAR_VELOCITY, GAME_MAX_ANGULAR_VELOCITY); }
void entity_apply_linear_impulse(struct entity *ent, struct v2 impulse, struct v2 world_point); void entity_apply_linear_impulse(struct entity *ent, struct v2 impulse, struct v2 world_point);
void entity_apply_force(struct entity *ent, struct v2 impulse, struct v2 world_point);
void entity_apply_linear_impulse_to_center(struct entity *ent, struct v2 impulse); void entity_apply_linear_impulse_to_center(struct entity *ent, struct v2 impulse);
void entity_apply_force_to_center(struct entity *ent, struct v2 force); void entity_apply_force_to_center(struct entity *ent, struct v2 force);
void entity_apply_angular_impulse(struct entity *ent, f32 impulse); void entity_apply_angular_impulse(struct entity *ent, f32 impulse);

View File

@ -345,19 +345,18 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
if (entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) { if (entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
/* Bullet hit entity */ /* Bullet hit entity */
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 v2 normal = data->normal; struct v2 normal = data->normal; /* Impact normal */
struct v2 vrel = v2_neg(data->vrel); /* Impact velocity */
struct entity *target = e0; struct entity *target = e0;
struct entity *bullet = e1; struct entity *bullet = e1;
if (entity_has_prop(e0, ENTITY_PROP_BULLET)) { if (entity_has_prop(e0, ENTITY_PROP_BULLET)) {
target = e1; target = e1;
bullet = e0; bullet = e0;
normal = v2_neg(normal); normal = v2_neg(normal);
vrel = v2_neg(vrel);
} }
struct entity *src = entity_from_handle(store, bullet->bullet_src); struct entity *src = entity_from_handle(store, bullet->bullet_src);
(UNUSED)bullet;
(UNUSED)target;
(UNUSED)src;
if (bullet->bullet_has_hit || entity_handle_eq(src->top, target->top)) { if (bullet->bullet_has_hit || entity_handle_eq(src->top, target->top)) {
/* Ignore collision if bullet already spent or if weapon and /* Ignore collision if bullet already spent or if weapon and
@ -377,20 +376,29 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
struct xform xf = entity_get_xform(tracer); struct xform xf = entity_get_xform(tracer);
xf.og = point; xf.og = point;
entity_set_xform(tracer, xf); entity_set_xform(tracer, xf);
tracer->linear_velocity = V2(0, 0); entity_set_linear_velocity(tracer, V2(0, 0));
} }
/* Update target */
struct v2 knockback = v2_mul(v2_norm(vrel), bullet->bullet_knockback);
entity_apply_linear_impulse(target, knockback, point);
/* Create test blood */ /* Create test blood */
/* TODO: Remove this */ /* TODO: Remove this */
{ {
struct xform xf = XFORM_TRS(.t = point); struct xform xf = XFORM_TRS(.t = point);
struct entity *decal = entity_alloc(root); struct entity *decal = entity_alloc(root);
decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase")); decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase"));
decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.5f);
entity_set_xform(decal, xf); entity_set_xform(decal, xf);
f32 angular_velocity_range = 5;
entity_enable_prop(decal, ENTITY_PROP_PHYSICAL_KINEMATIC); entity_enable_prop(decal, ENTITY_PROP_PHYSICAL_KINEMATIC);
decal->linear_velocity = v2_mul(v2_norm(normal), 0.5f); entity_set_linear_velocity(decal, v2_mul(v2_norm(v2_neg(vrel)), 0.5f));
decal->angular_velocity = 1 - (((f32)sys_rand_u32() / (f32)U32_MAX) * 2); entity_set_angular_velocity(decal, angular_velocity_range - (((f32)sys_rand_u32() / (f32)U32_MAX) * (angular_velocity_range * 2)));
decal->linear_damping = 5.0f;
decal->angular_damping = 5.0f;
} }
} }
} }
@ -821,6 +829,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
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_impulse = 0.75f;
bullet->bullet_knockback = 10;
bullet->mass_unscaled = 0.04f; bullet->mass_unscaled = 0.04f;
bullet->inertia_unscaled = 0.00001f; bullet->inertia_unscaled = 0.00001f;
@ -883,7 +892,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
} }
entity_set_xform(joint_ent, XFORM_IDENT); /* Reset joint ent position */ entity_set_xform(joint_ent, XFORM_IDENT); /* Reset joint ent position */
joint_ent->linear_velocity = v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed); entity_set_linear_velocity(joint_ent, v2_mul(v2_clamp_len(ent->control.move, 1), ent->control_force_max_speed));
} }
} }
#endif #endif
@ -973,7 +982,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
new_vel = diff / dt; new_vel = diff / dt;
} }
} }
joint_ent->angular_velocity = new_vel; entity_set_angular_velocity(joint_ent, new_vel);
} }
} }
#endif #endif
@ -1098,7 +1107,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
if (entity_is_valid_and_active(tracer)) { if (entity_is_valid_and_active(tracer)) {
entity_set_xform(tracer, xf); entity_set_xform(tracer, xf);
entity_enable_prop(tracer, ENTITY_PROP_PHYSICAL_KINEMATIC); entity_enable_prop(tracer, ENTITY_PROP_PHYSICAL_KINEMATIC);
tracer->linear_velocity = ent->linear_velocity; entity_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;
tracer->tracer_gradient_end = pos; tracer->tracer_gradient_end = pos;

View File

@ -457,10 +457,10 @@ void phys_warm_start_contacts(struct phys_ctx *ctx)
w1 += v2_wedge(vcp1, impulse) * inv_i1; w1 += v2_wedge(vcp1, impulse) * inv_i1;
} }
e0->linear_velocity = v0; entity_set_linear_velocity(e0, v0);
e0->angular_velocity = w0; entity_set_angular_velocity(e0, w0);
e1->linear_velocity = v1; entity_set_linear_velocity(e1, v1);
e1->angular_velocity = w1; entity_set_angular_velocity(e1, w1);
} }
} }
} }
@ -573,10 +573,10 @@ void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias)
w1 += v2_wedge(vcp1, impulse) * inv_i1; w1 += v2_wedge(vcp1, impulse) * inv_i1;
} }
e0->linear_velocity = v0; entity_set_linear_velocity(e0, v0);
e0->angular_velocity = w0; entity_set_angular_velocity(e0, w0);
e1->linear_velocity = v1; entity_set_linear_velocity(e1, v1);
e1->angular_velocity = w1; entity_set_angular_velocity(e1, w1);
} }
} }
} }
@ -685,8 +685,8 @@ void phys_warm_start_motor_joints(struct phys_ctx *ctx)
struct v2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og); struct v2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
struct v2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og); struct v2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
e0->linear_velocity = v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)); entity_set_linear_velocity(e0, v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)));
e1->linear_velocity = v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)); entity_set_linear_velocity(e1, v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)));
e0->angular_velocity -= (v2_wedge(vcp0, joint->linear_impulse) + joint->angular_impulse) * inv_i0; e0->angular_velocity -= (v2_wedge(vcp0, joint->linear_impulse) + joint->angular_impulse) * inv_i0;
e1->angular_velocity += (v2_wedge(vcp1, joint->linear_impulse) + joint->angular_impulse) * inv_i1; e1->angular_velocity += (v2_wedge(vcp1, joint->linear_impulse) + joint->angular_impulse) * inv_i1;
} }
@ -761,10 +761,10 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
w1 += v2_wedge(vcp1, impulse) * inv_i1; w1 += v2_wedge(vcp1, impulse) * inv_i1;
} }
e0->linear_velocity = v0; entity_set_linear_velocity(e0, v0);
e0->angular_velocity = w0; entity_set_angular_velocity(e0, w0);
e1->linear_velocity = v1; entity_set_linear_velocity(e1, v1);
e1->angular_velocity = w1; entity_set_angular_velocity(e1, w1);
} }
} }
@ -903,7 +903,7 @@ void phys_warm_start_mouse_joints(struct phys_ctx *ctx)
f32 inv_i = joint->inv_i; f32 inv_i = joint->inv_i;
struct xform xf = entity_get_xform(ent); struct xform xf = entity_get_xform(ent);
struct v2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og); struct v2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
ent->linear_velocity = v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)); entity_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
ent->angular_velocity += (v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i; ent->angular_velocity += (v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i;
} }
} }
@ -984,12 +984,83 @@ void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
w += v2_wedge(vcp, impulse) * inv_i; w += v2_wedge(vcp, impulse) * inv_i;
} }
ent->linear_velocity = v; entity_set_linear_velocity(ent, v);
ent->angular_velocity = w; entity_set_angular_velocity(ent, w);
} }
} }
} }
/* ========================== *
* Integration
* ========================== */
INTERNAL struct xform get_derived_xform(struct entity *ent, f32 dt)
{
struct xform xf = entity_get_xform(ent);
struct v2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
f32 step_angular_velocity = ent->angular_velocity * dt;
xf.og = v2_add(xf.og, step_linear_velocity);
xf = xform_basis_rotated_world(xf, step_angular_velocity);
return xf;
}
void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
b32 is_dynamic = entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC);
b32 is_kinematic = entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC);
if (is_dynamic || is_kinematic) {
struct v2 linear_velocity = ent->linear_velocity;
f32 angular_velocity = ent->angular_velocity;
f32 linear_damping_factor = max_f32(1.0f - (ent->linear_damping * dt), 0);
f32 angular_damping_factor = max_f32(1.0f - (ent->angular_damping * dt), 0);
/* Integrate forces */
if (is_dynamic) {
struct xform xf = entity_get_xform(ent);
f32 det_abs = math_fabs(xform_get_determinant(xf));
f32 mass = ent->mass_unscaled * det_abs;
f32 inertia = ent->inertia_unscaled * det_abs;
struct v2 force_accel = v2_mul(v2_div(ent->force, mass), dt);
f32 torque_accel = (ent->torque / inertia) * dt;
linear_velocity = v2_add(linear_velocity, force_accel);
angular_velocity += torque_accel;
}
/* Apply damping */
linear_velocity = v2_mul(linear_velocity, linear_damping_factor);
angular_velocity *= angular_damping_factor;
/* Update entity */
entity_set_linear_velocity(ent, linear_velocity);
entity_set_angular_velocity(ent, angular_velocity);
ent->force = V2(0, 0);
ent->torque = 0;
}
}
}
void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) continue;
entity_set_xform(ent, get_derived_xform(ent, dt));
}
}
/* ========================== * /* ========================== *
* Earliest time of impact * Earliest time of impact
* ========================== */ * ========================== */
@ -1010,16 +1081,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
struct collider_shape e0_collider = e0->local_collider; struct collider_shape e0_collider = e0->local_collider;
struct xform e0_xf_t0 = entity_get_xform(e0); struct xform e0_xf_t0 = entity_get_xform(e0);
struct xform e0_xf_t1 = e0_xf_t0; struct xform e0_xf_t1 = get_derived_xform(e0, step_dt);
{
/* Calculate xform at t=1 */
struct v2 linear_velocity = v2_clamp_len(e0->linear_velocity, GAME_MAX_LINEAR_VELOCITY);
f32 angular_velocity = clamp_f32(e0->angular_velocity, -GAME_MAX_ANGULAR_VELOCITY, GAME_MAX_ANGULAR_VELOCITY);
struct v2 tick_linear_velocity = v2_mul(linear_velocity, step_dt);
f32 tick_angular_velocity = angular_velocity * step_dt;
e0_xf_t1.og = v2_add(e0_xf_t1.og, tick_linear_velocity);
e0_xf_t1 = xform_basis_rotated_world(e0_xf_t1, tick_angular_velocity);
}
/* Start e1 index at e0 index + 1 to prevent redundant checks */ /* Start e1 index at e0 index + 1 to prevent redundant checks */
for (u64 e1_index = e0_index + 1; e1_index < store->reserved; ++e1_index) { for (u64 e1_index = e0_index + 1; e1_index < store->reserved; ++e1_index) {
@ -1036,16 +1098,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
struct collider_shape e1_collider = e1->local_collider; struct collider_shape e1_collider = e1->local_collider;
struct xform e1_xf_t0 = entity_get_xform(e1); struct xform e1_xf_t0 = entity_get_xform(e1);
struct xform e1_xf_t1 = e1_xf_t0; struct xform e1_xf_t1 = get_derived_xform(e1, step_dt);
{
/* Calculate xform at t=1 */
struct v2 linear_velocity = v2_clamp_len(e1->linear_velocity, GAME_MAX_LINEAR_VELOCITY);
f32 angular_velocity = clamp_f32(e1->angular_velocity, -GAME_MAX_ANGULAR_VELOCITY, GAME_MAX_ANGULAR_VELOCITY);
struct v2 tick_linear_velocity = v2_mul(linear_velocity, step_dt);
f32 tick_angular_velocity = angular_velocity * step_dt;
e1_xf_t1.og = v2_add(e1_xf_t1.og, tick_linear_velocity);
e1_xf_t1 = xform_basis_rotated_world(e1_xf_t1, tick_angular_velocity);
}
f32 t = collider_time_of_impact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations); f32 t = collider_time_of_impact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations);
if (t != 0 && t < smallest_t) { if (t != 0 && t < smallest_t) {
@ -1057,61 +1110,6 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
return smallest_t; return smallest_t;
} }
/* ========================== *
* Integration
* ========================== */
void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) continue;
struct xform xf = entity_get_xform(ent);
f32 det_abs = math_fabs(xform_get_determinant(xf));
f32 mass = ent->mass_unscaled * det_abs;
f32 inertia = ent->inertia_unscaled * det_abs;
/* Determine force & torque acceleration */
struct v2 force_accel = v2_mul(v2_div(ent->force, mass), dt);
f32 torque_accel = (ent->torque / inertia) * dt;
/* Integrate & clamp */
ent->linear_velocity = v2_clamp_len(v2_add(ent->linear_velocity, force_accel), GAME_MAX_LINEAR_VELOCITY);
ent->angular_velocity = clamp_f32(ent->angular_velocity + torque_accel, -GAME_MAX_ANGULAR_VELOCITY, GAME_MAX_ANGULAR_VELOCITY);
/* Reset forces */
ent->force = V2(0, 0);
ent->torque = 0;
}
}
void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) continue;
/* Clamp velocities */
ent->linear_velocity = v2_clamp_len(ent->linear_velocity, GAME_MAX_LINEAR_VELOCITY);
ent->angular_velocity = clamp_f32(ent->angular_velocity, -GAME_MAX_ANGULAR_VELOCITY, GAME_MAX_ANGULAR_VELOCITY);
struct v2 tick_linear_velocity = v2_mul(ent->linear_velocity, dt);
f32 tick_angular_velocity = ent->angular_velocity * dt;
struct xform xf = entity_get_xform(ent);
xf.og = v2_add(xf.og, tick_linear_velocity);
xf = xform_basis_rotated_world(xf, tick_angular_velocity);
entity_set_xform(ent, xf);
}
}
/* ========================== * /* ========================== *
* Step * Step
* ========================== */ * ========================== */

View File

@ -177,12 +177,6 @@ void phys_prepare_mouse_joints(struct phys_ctx *ctx);
void phys_warm_start_mouse_joints(struct phys_ctx *ctx); void phys_warm_start_mouse_joints(struct phys_ctx *ctx);
void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt); void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt);
/* ========================== *
* Earliest time of impact
* ========================== */
f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations);
/* ========================== * /* ========================== *
* Integration * Integration
* ========================== */ * ========================== */
@ -190,6 +184,12 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
void phys_integrate_forces(struct phys_ctx *ctx, f32 dt); void phys_integrate_forces(struct phys_ctx *ctx, f32 dt);
void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt); void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt);
/* ========================== *
* Earliest time of impact
* ========================== */
f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations);
/* ========================== * /* ========================== *
* Step * Step
* ========================== */ * ========================== */