testing linear movement using motor joint
This commit is contained in:
parent
c6b2a8c283
commit
483a95dfca
@ -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;
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
102
src/game.c
102
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
|
||||
|
||||
/* ========================== *
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user