testing linear movement using motor joint

This commit is contained in:
jacob 2024-10-29 11:13:15 -05:00
parent c6b2a8c283
commit 483a95dfca
3 changed files with 81 additions and 33 deletions

View File

@ -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;
/* ====================================================================== */

View File

@ -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
/* ========================== *

View File

@ -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);