set aim joint correction rate dynamically based on dt
This commit is contained in:
parent
aaaa7deb81
commit
eea9c978c9
@ -33,6 +33,7 @@
|
|||||||
#define SPACE_CELL_BUCKETS_SQRT (256)
|
#define SPACE_CELL_BUCKETS_SQRT (256)
|
||||||
#define SPACE_CELL_SIZE 1.0f
|
#define SPACE_CELL_SIZE 1.0f
|
||||||
|
|
||||||
|
|
||||||
#define GAME_FPS 50.0
|
#define GAME_FPS 50.0
|
||||||
#define GAME_TIMESCALE 1
|
#define GAME_TIMESCALE 1
|
||||||
|
|
||||||
|
|||||||
@ -229,7 +229,6 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Enemy */
|
/* Enemy */
|
||||||
#if 1
|
|
||||||
{
|
{
|
||||||
struct entity *e = entity_alloc(root);
|
struct entity *e = entity_alloc(root);
|
||||||
|
|
||||||
@ -249,7 +248,6 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
e->linear_ground_friction = 250;
|
e->linear_ground_friction = 250;
|
||||||
e->angular_ground_friction = 200;
|
e->angular_ground_friction = 200;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Big box */
|
/* Big box */
|
||||||
@ -984,12 +982,15 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
struct phys_motor_joint_def def = ZI;
|
struct phys_motor_joint_def def = ZI;
|
||||||
def.e0 = joint_ent->handle; /* Re-using joint entity as e0 */
|
def.e0 = joint_ent->handle; /* Re-using joint entity as e0 */
|
||||||
def.e1 = ent->handle;
|
def.e1 = ent->handle;
|
||||||
def.correction_rate = 0.1f;
|
|
||||||
def.max_force = 0;
|
def.max_force = 0;
|
||||||
def.max_torque = ent->control_torque;
|
def.max_torque = ent->control_torque;
|
||||||
joint_ent->motor_joint_data = motor_joint_from_def(def);
|
joint_ent->motor_joint_data = motor_joint_from_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set correction rate dynamically since motor velocity is only set for one frame */
|
||||||
|
joint_ent->motor_joint_data.correction_rate = 10 * dt;
|
||||||
|
|
||||||
|
|
||||||
/* Solve for final angle using law of sines */
|
/* Solve for final angle using law of sines */
|
||||||
f32 new_angle;
|
f32 new_angle;
|
||||||
{
|
{
|
||||||
@ -1039,6 +1040,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
struct xform joint_xf = entity_get_xform(joint_ent);
|
struct xform joint_xf = entity_get_xform(joint_ent);
|
||||||
f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf));
|
f32 diff = math_unwind_angle(new_angle - xform_get_rotation(joint_xf));
|
||||||
if (math_fabs(diff) > angle_error_allowed) {
|
if (math_fabs(diff) > angle_error_allowed) {
|
||||||
|
/* Instantly snap joint ent to new angle */
|
||||||
new_vel = diff / dt;
|
new_vel = diff / dt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,6 +50,5 @@ void mixer_set_listener(struct v2 pos, struct v2 dir);
|
|||||||
|
|
||||||
/* Mixing */
|
/* Mixing */
|
||||||
struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_request_count);
|
struct mixed_pcm_f32 mixer_update(struct arena *arena, u64 frame_request_count);
|
||||||
void mixer_advance(u64 frames_written_count);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
31
src/phys.c
31
src/phys.c
@ -717,23 +717,23 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
|
|||||||
f32 w0 = e0->angular_velocity;
|
f32 w0 = e0->angular_velocity;
|
||||||
f32 w1 = e1->angular_velocity;
|
f32 w1 = e1->angular_velocity;
|
||||||
|
|
||||||
f32 correction_rate = joint->correction_rate / dt;
|
f32 correction_rate = joint->correction_rate;
|
||||||
|
f32 inv_dt = 1.f / dt;
|
||||||
|
|
||||||
/* Angular constraint */
|
/* Angular constraint */
|
||||||
{
|
{
|
||||||
f32 max_impulse = joint->max_torque * dt;
|
f32 max_impulse = joint->max_torque * dt;
|
||||||
|
|
||||||
f32 angular_separation = math_unwind_angle(xform_get_rotation(e1_xf) - xform_get_rotation(e0_xf));
|
f32 angular_separation = math_unwind_angle(xform_get_rotation(e1_xf) - xform_get_rotation(e0_xf));
|
||||||
f32 angular_bias = angular_separation * correction_rate;
|
|
||||||
|
|
||||||
f32 impulse = -joint->angular_mass * (w1 - w0 + angular_bias);
|
f32 angular_bias = angular_separation * correction_rate * inv_dt;
|
||||||
|
|
||||||
f32 old_impulse = joint->angular_impulse;
|
f32 old_impulse = joint->angular_impulse;
|
||||||
joint->angular_impulse = clamp_f32(joint->angular_impulse + impulse, -max_impulse, max_impulse);
|
f32 new_impulse = clamp_f32(old_impulse + (-joint->angular_mass * (w1 - w0 + angular_bias)), -max_impulse, max_impulse);
|
||||||
impulse = joint->angular_impulse - old_impulse;
|
joint->angular_impulse = new_impulse;
|
||||||
|
|
||||||
w0 -= impulse * inv_i0;
|
f32 delta = new_impulse - old_impulse;
|
||||||
w1 += impulse * inv_i1;
|
w0 -= delta * inv_i0;
|
||||||
|
w1 += delta * inv_i1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linear constraint */
|
/* Linear constraint */
|
||||||
@ -744,19 +744,20 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
|
|||||||
f32 max_impulse = joint->max_force * dt;
|
f32 max_impulse = joint->max_force * dt;
|
||||||
|
|
||||||
struct v2 linear_separation = v2_sub(v2_add(e1_xf.og, vcp1), v2_add(e0_xf.og, vcp0));
|
struct v2 linear_separation = v2_sub(v2_add(e1_xf.og, vcp1), v2_add(e0_xf.og, vcp0));
|
||||||
struct v2 linear_bias = v2_mul(linear_separation, correction_rate);
|
struct v2 linear_bias = v2_mul(linear_separation, correction_rate * inv_dt);
|
||||||
|
|
||||||
struct v2 vrel = v2_sub(v2_add(v1, v2_perp_mul(vcp1, w1)), v2_add(v0, v2_perp_mul(vcp0, w0)));
|
struct v2 vrel = v2_sub(v2_add(v1, v2_perp_mul(vcp1, w1)), v2_add(v0, v2_perp_mul(vcp0, w0)));
|
||||||
struct v2 impulse = v2_neg(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vrel, linear_bias)));
|
struct v2 impulse = v2_neg(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vrel, linear_bias)));
|
||||||
|
|
||||||
struct v2 old_impulse = joint->linear_impulse;
|
struct v2 old_impulse = joint->linear_impulse;
|
||||||
joint->linear_impulse = v2_clamp_len(v2_add(joint->linear_impulse, impulse), max_impulse);
|
struct v2 new_impulse = v2_clamp_len(v2_add(old_impulse, impulse), max_impulse);
|
||||||
impulse = v2_sub(joint->linear_impulse, old_impulse);
|
joint->linear_impulse = new_impulse;
|
||||||
|
|
||||||
v0 = v2_sub(v0, v2_mul(impulse, inv_m0));
|
struct v2 delta = v2_sub(new_impulse, old_impulse);
|
||||||
v1 = v2_add(v1, v2_mul(impulse, inv_m1));
|
v0 = v2_sub(v0, v2_mul(delta, inv_m0));
|
||||||
w0 -= v2_wedge(vcp0, impulse) * inv_i0;
|
v1 = v2_add(v1, v2_mul(delta, inv_m1));
|
||||||
w1 += v2_wedge(vcp1, impulse) * inv_i1;
|
w0 -= v2_wedge(vcp0, delta) * inv_i0;
|
||||||
|
w1 += v2_wedge(vcp1, delta) * inv_i1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_set_linear_velocity(e0, v0);
|
entity_set_linear_velocity(e0, v0);
|
||||||
|
|||||||
@ -936,7 +936,7 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
|
b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
|
||||||
b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA);
|
b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA);
|
||||||
skip_debug_draw_transform = true;
|
//skip_debug_draw_transform = true;
|
||||||
|
|
||||||
struct xform sprite_xform = xf;
|
struct xform sprite_xform = xf;
|
||||||
|
|
||||||
@ -1005,8 +1005,8 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* Draw xform */
|
/* Draw xform */
|
||||||
if (!skip_debug_draw_transform) {
|
if (!skip_debug_draw_transform) {
|
||||||
u32 color_x = RGBA_32_F(1, 0, 0, 0.3);
|
u32 color_x = RGBA_32_F(1, 0, 0, 0.5);
|
||||||
u32 color_y = RGBA_32_F(0, 1, 0, 0.3);
|
u32 color_y = RGBA_32_F(0, 1, 0, 0.5);
|
||||||
debug_draw_xform(xf, color_x, color_y);
|
debug_draw_xform(xf, color_x, color_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user