From 483a95dfca57d08b13a80c914a68bd488223d79b Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 29 Oct 2024 11:13:15 -0500 Subject: [PATCH] testing linear movement using motor joint --- src/entity.h | 8 +++- src/game.c | 102 ++++++++++++++++++++++++++++++++++++--------------- src/user.c | 4 +- 3 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/entity.h b/src/entity.h index d7e59043..e88dde2a 100644 --- a/src/entity.h +++ b/src/entity.h @@ -221,13 +221,17 @@ struct entity { /* ====================================================================== */ /* Control */ - f32 control_force; /* How much force is applied to achieve desired control movement */ - f32 control_turn_speed; /* Turn speed in turns / second */ + f32 control_force; /* How much force is applied to achieve desired control movement */ + f32 control_force_max_speed; /* Maximum linear velocity achieved by force (m/s) */ + + f32 control_torque; /* How much torque is applied when turning towards desired focus */ + struct { struct v2 move; struct v2 focus; } control; + struct entity_handle move_joint; struct entity_handle aim_joint; /* ====================================================================== */ diff --git a/src/game.c b/src/game.c index 6c2d8f5d..4c3549bc 100644 --- a/src/game.c +++ b/src/game.c @@ -176,28 +176,47 @@ INTERNAL void spawn_test_entities(f32 offset) e->sprite_span_name = STR("idle.two_handed"); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); -#if GAME_PHYSICS_ENABLE_GROUND_FRICTION - //e->control_force = 4500; - //e->control_force = 1200; - e->control_force = 250; -#else - //e->control_force = 5000; - e->control_force = 250; -#endif - //e->control_turn_speed = 10; - e->control_turn_speed = 1; - e->control.focus = V2(0, -1); + + e->linear_ground_friction = 150; + e->angular_ground_friction = 100; + + + e->control_force = 500; + e->control_force_max_speed = 4; + e->control_torque = 5000; entity_enable_prop(e, ENTITY_PROP_PHYSICAL); e->mass_unscaled = 10; - //e->inertia_unscaled = F32_INFINITY; e->inertia_unscaled = 10; - e->linear_ground_friction = 200; - e->angular_ground_friction = 100; entity_enable_prop(e, ENTITY_PROP_TEST); player_ent = e; + + +#if 0 + { + struct entity *joint_ent = entity_alloc(root); + entity_enable_prop(joint_ent, ENTITY_PROP_PHYSICAL); + entity_enable_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT); + entity_enable_prop(joint_ent, ENTITY_PROP_ACTIVE); + + struct motor_joint_def def = ZI; + def.e0 = root->handle; + def.e1 = e->handle; + def.correction_rate = 0; + def.max_force = e->linear_ground_friction; + def.max_torque = e->angular_ground_friction; + joint_ent->motor_joint_data = motor_joint_from_def(def); + } +#endif + + + + + + + } #if GAME_SPAWN_TESTENT @@ -942,8 +961,8 @@ INTERNAL void solve_motor_joints(f32 dt) 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 Cdot = 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(Cdot, linear_bias))); + 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 old_impulse = joint->linear_impulse; joint->linear_impulse = v2_clamp_len(v2_add(joint->linear_impulse, impulse), max_impulse); @@ -1488,6 +1507,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) * Create forces from control move * ========================== */ +#if 0 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; @@ -1498,6 +1518,36 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) entity_apply_force_to_center(ent, force); } } +#else + 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_PLAYER_CONTROLLED)) { + struct entity *joint_ent = entity_from_handle(store, ent->move_joint); + if (!entity_is_valid_and_active(joint_ent)) { + joint_ent = entity_alloc(root); + joint_ent->mass_unscaled = F32_INFINITY; + joint_ent->inertia_unscaled = F32_INFINITY; + entity_enable_prop(joint_ent, ENTITY_PROP_PHYSICAL); + entity_enable_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT); + entity_enable_prop(joint_ent, ENTITY_PROP_ACTIVE); + ent->move_joint = joint_ent->handle; + + struct motor_joint_def def = ZI; + def.e0 = joint_ent->handle; /* Re-using joint entity as e0 */ + def.e1 = ent->handle; + def.correction_rate = 0; + def.max_force = ent->control_force; + def.max_torque = 0; + joint_ent->motor_joint_data = motor_joint_from_def(def); + } + + entity_set_xform(joint_ent, XFORM_IDENT); /* Reset joint ent position */ + joint_ent->linear_velocity = v2_with_len(ent->control.move, ent->control_force_max_speed); + } + } +#endif /* ========================== * * Create forces from control focus (aim) @@ -1516,28 +1566,20 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) struct entity *joint_ent = entity_from_handle(store, ent->aim_joint); if (!entity_is_valid_and_active(joint_ent)) { joint_ent = entity_alloc(root); + joint_ent->mass_unscaled = F32_INFINITY; + joint_ent->inertia_unscaled = F32_INFINITY; entity_enable_prop(joint_ent, ENTITY_PROP_PHYSICAL); entity_enable_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT); entity_enable_prop(joint_ent, ENTITY_PROP_ACTIVE); + ent->aim_joint = joint_ent->handle; struct motor_joint_def def = ZI; def.e0 = joint_ent->handle; /* Re-using joint entity as e0 */ def.e1 = ent->handle; - def.correction_rate = 0.2; + def.correction_rate = 0.1; 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); - ent->aim_joint = joint_ent->handle; - - joint_ent->mass_unscaled = F32_INFINITY; - joint_ent->inertia_unscaled = F32_INFINITY; - } - - { - f32 inertia_scaled = ent->inertia_unscaled * math_fabs(xform_get_determinant(xf)); - joint_ent->motor_joint_data.max_torque = ((1.f / dt) * (PI / 2) * inertia_scaled) * ent->control_turn_speed; } /* Solve for final angle using law of sines */ @@ -1601,6 +1643,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) * Create ground friction force (gravity) * ========================== */ +#if 0 #if GAME_PHYSICS_ENABLE_GROUND_FRICTION #if 0 /* TODO: Do this globally rather than creating entities for constant forces */ @@ -1668,6 +1711,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) } } #endif +#endif #endif /* ========================== * diff --git a/src/user.c b/src/user.c index 136da616..21bf8eec 100644 --- a/src/user.c +++ b/src/user.c @@ -496,10 +496,10 @@ INTERNAL void user_update(void) } e->control_force = math_lerp(e0->control_force, e1->control_force, tick_blend); - e->control_turn_speed = math_lerp(e0->control_turn_speed, e1->control_turn_speed, tick_blend); + e->control_torque = math_lerp(e0->control_torque, e1->control_torque, tick_blend); e->linear_velocity = v2_lerp(e0->linear_velocity, e1->linear_velocity, tick_blend); - e->angular_velocity = math_lerp(e0->angular_velocity, e1->angular_velocity, tick_blend); + e->angular_velocity = math_lerp_angle(e0->angular_velocity, e1->angular_velocity, tick_blend); e->control.move = v2_lerp(e0->control.move, e1->control.move, tick_blend); e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, tick_blend);