halve warm start impulse to reduce jitter
This commit is contained in:
parent
bc19bd816d
commit
9b4cfa345d
@ -87,6 +87,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
|
||||
/* TODO: Parameterize */
|
||||
const f32 tolerance = 0.005f; /* How close can shapes be before collision is considered */
|
||||
//const f32 tolerance = 0.05f; /* How close can shapes be before collision is considered */
|
||||
const f32 min_unique_pt_dist_sq = 0.0001f * 0.0001f;
|
||||
const u32 max_epa_iterations = 64; /* To prevent extremely large prototypes when origin is in exact center of rounded feature */
|
||||
|
||||
@ -247,6 +248,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
* ========================== */
|
||||
|
||||
const f32 epa_epsilon_sq = 0.001f * 0.001f;
|
||||
//const f32 epa_epsilon_sq = F32_INFINITY;
|
||||
|
||||
proto = arena_dry_push(scratch.arena, struct v2);
|
||||
proto_count = 0;
|
||||
@ -409,7 +411,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
struct v2 vap = v2_sub(p, a);
|
||||
struct v2 vpb = v2_sub(b, p);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* Swap a & b depending on winding order */
|
||||
if (v2_wedge(vap, vpb) < 0) {
|
||||
u32 tmp_u32 = a_i;
|
||||
@ -452,7 +454,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
struct v2 vap = v2_sub(p, a);
|
||||
struct v2 vpb = v2_sub(b, p);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* Swap a & b depending on winding order */
|
||||
if (v2_wedge(vap, vpb) > 0) {
|
||||
u32 tmp_u32 = a_i;
|
||||
@ -482,6 +484,22 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (radius0 > 0.0) {
|
||||
struct v2 scale = xform_get_scale(xf0);
|
||||
struct v2 normal_radius = v2_mul_v2(v2_mul(normal, radius0), scale);
|
||||
a0 = v2_add(a0, normal_radius);
|
||||
b0 = v2_add(b0, normal_radius);
|
||||
}
|
||||
|
||||
if (radius1 > 0.0) {
|
||||
struct v2 scale = xform_get_scale(xf1);
|
||||
struct v2 normal_radius = v2_mul_v2(v2_mul(normal, radius1), scale);
|
||||
a1 = v2_sub(a1, normal_radius);
|
||||
b1 = v2_sub(b1, normal_radius);
|
||||
}
|
||||
#endif
|
||||
|
||||
f32 a0t = 0;
|
||||
f32 a1t = 0;
|
||||
f32 b0t = 0;
|
||||
@ -697,7 +715,6 @@ b32 collider_collision_boolean(struct collider_shape *shape0, struct collider_sh
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
struct collider_collision_points_result collider_collision_points(struct collider_shape *shape0, struct collider_shape *shape1, struct xform xf0, struct xform xf1)
|
||||
{
|
||||
|
||||
@ -81,6 +81,9 @@ struct contact {
|
||||
f32 inv_i1;
|
||||
|
||||
b32 persisted;
|
||||
|
||||
/* Debugging */
|
||||
struct v2 dbg_pt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
46
src/game.c
46
src/game.c
@ -222,8 +222,8 @@ INTERNAL void spawn_test_entities(f32 offset)
|
||||
|
||||
//entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||
//e->control_force = 4500;
|
||||
//e->control_force = 1200;
|
||||
e->control_force = 250;
|
||||
e->control_force = 1200;
|
||||
//e->control_force = 250;
|
||||
e->control_torque = 10;
|
||||
e->control.focus = V2(0, -1);
|
||||
|
||||
@ -488,6 +488,11 @@ INTERNAL void create_contact_manifolds(void)
|
||||
contact->point_local_e1 = xform_invert_mul_v2(e1_xf, point);
|
||||
contact->starting_separation = sep;
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
{
|
||||
contact->dbg_pt = point;
|
||||
}
|
||||
|
||||
{
|
||||
f32 scale0 = math_fabs(xform_get_determinant(e0_xf));
|
||||
f32 scale1 = math_fabs(xform_get_determinant(e1_xf));
|
||||
@ -580,7 +585,7 @@ INTERNAL void warm_start_contacts(void)
|
||||
struct v2 vcp1 = v2_sub(p1, e1_xf.og);
|
||||
|
||||
struct v2 impulse = v2_add(v2_mul(normal, contact->normal_impulse), v2_mul(tangent, contact->tangent_impulse));
|
||||
//impulse = v2_mul(impulse, 0.5f);
|
||||
impulse = v2_mul(impulse, 0.5f);
|
||||
|
||||
v0 = v2_sub(v0, v2_mul(impulse, contact->inv_m0));
|
||||
v1 = v2_add(v1, v2_mul(impulse, contact->inv_m1));
|
||||
@ -668,23 +673,22 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
||||
f32 mass_scale = 1.0f;
|
||||
f32 impulse_scale = 0.0f;
|
||||
|
||||
if (apply_bias) {
|
||||
if (separation > 0.0f) {
|
||||
velocity_bias = separation / dt;
|
||||
} else {
|
||||
/* Soft constraint */
|
||||
/* Only apply speculative if applying bias */
|
||||
if (separation > 0.0f) {
|
||||
velocity_bias = separation / dt;
|
||||
} else if (apply_bias) {
|
||||
/* Soft constraint */
|
||||
|
||||
f32 contact_damping_ratio = 10.0f;
|
||||
f32 contact_hertz = (GAME_FPS * GAME_PHYSICS_SUBSTEPS) / 8.f;
|
||||
f32 contact_damping_ratio = 10.0f;
|
||||
f32 contact_hertz = (GAME_FPS * GAME_PHYSICS_SUBSTEPS) / 8.f;
|
||||
|
||||
struct soft_result softness = make_soft(contact_hertz, contact_damping_ratio, dt);
|
||||
struct soft_result softness = make_soft(contact_hertz, contact_damping_ratio, dt);
|
||||
|
||||
f32 contact_pushout_velocity = 3.0f;
|
||||
velocity_bias = max_f32(softness.bias_rate * separation, -contact_pushout_velocity);
|
||||
f32 contact_pushout_velocity = 3.0f;
|
||||
velocity_bias = max_f32(softness.bias_rate * separation, -contact_pushout_velocity);
|
||||
|
||||
mass_scale = softness.mass_scale;
|
||||
impulse_scale = softness.impulse_scale;
|
||||
}
|
||||
mass_scale = softness.mass_scale;
|
||||
impulse_scale = softness.impulse_scale;
|
||||
}
|
||||
|
||||
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
||||
@ -1027,12 +1031,18 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
ent->local_collider.count = 2;
|
||||
ent->local_collider.radius = 0.25;
|
||||
#elif 1
|
||||
#if 0
|
||||
/* "Bad" winding order */
|
||||
ent->local_collider.points[0] = V2(-0.5, 0.5);
|
||||
ent->local_collider.points[1] = V2(0.5, 0.5);
|
||||
//ent->local_collider.points[1] = V2(0, 0.5);
|
||||
ent->local_collider.points[2] = V2(0, -0.5);
|
||||
#else
|
||||
ent->local_collider.points[0] = V2(0, -0.5);
|
||||
ent->local_collider.points[1] = V2(0.5, 0.5);
|
||||
ent->local_collider.points[2] = V2(-0.5, 0.5);
|
||||
#endif
|
||||
ent->local_collider.count = 3;
|
||||
//ent->local_collider.radius = 0.25;
|
||||
ent->local_collider.radius = 0.25;
|
||||
//ent->local_collider.radius = math_fabs(math_sin(G.tick.time) / 3);
|
||||
#else
|
||||
ent->local_collider.radius = 0.25;
|
||||
|
||||
32
src/user.c
32
src/user.c
@ -1012,6 +1012,8 @@ INTERNAL void user_update(void)
|
||||
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
(UNUSED)e0_xf;
|
||||
(UNUSED)e1_xf;
|
||||
|
||||
struct collider_shape e0_collider = e0->local_collider;
|
||||
struct collider_shape e1_collider = e1->local_collider;
|
||||
@ -1109,9 +1111,13 @@ INTERNAL void user_update(void)
|
||||
f32 radius = 5;
|
||||
for (u32 i = 0; i < ent->num_contacts; ++i) {
|
||||
struct contact contact = ent->contacts[i];
|
||||
#if 0
|
||||
struct v2 p0 = xform_mul_v2(e0_xf, contact.point_local_e0);
|
||||
struct v2 p1 = xform_mul_v2(e1_xf, contact.point_local_e1);
|
||||
struct v2 point = v2_add(p0, v2_mul(v2_sub(p1, p0), 0.5f));
|
||||
#else
|
||||
struct v2 point = contact.dbg_pt;
|
||||
#endif
|
||||
/* Draw point */
|
||||
{
|
||||
//u32 color = contact.persisted ? RGBA_32_F(1, 1, 0, 0.50) : RGBA_32_F(1, 0, 0, 0.50);
|
||||
@ -1130,7 +1136,7 @@ INTERNAL void user_update(void)
|
||||
struct v2 end = xform_mul_v2(G.world_view, v2_add(point, v2_mul(v2_norm(ent->manifold_normal), len)));
|
||||
draw_solid_arrow_line(G.viewport_canvas, start, end, arrow_thickness, arrow_height, color);
|
||||
}
|
||||
#if 1
|
||||
#if 0
|
||||
/* Draw info text */
|
||||
{
|
||||
struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);
|
||||
@ -1172,20 +1178,22 @@ INTERNAL void user_update(void)
|
||||
{
|
||||
f32 thickness = 2;
|
||||
f32 radius = 4;
|
||||
u32 color = RGBA_32_F(1, 0, 1, 0.5);
|
||||
u32 color_line = RGBA_32_F(1, 0, 1, 0.5);
|
||||
u32 color_a = RGBA_32_F(1, 0, 0, 0.5);
|
||||
u32 color_b = RGBA_32_F(0, 1, 0, 0.5);
|
||||
{
|
||||
struct v2 start = xform_mul_v2(G.world_view, ent->res.a0);
|
||||
struct v2 end = xform_mul_v2(G.world_view, ent->res.b0);
|
||||
draw_solid_line(G.viewport_canvas, start, end, thickness, color);
|
||||
draw_solid_circle(G.viewport_canvas, start, radius, color, 10);
|
||||
draw_solid_circle(G.viewport_canvas, end, radius, color, 10);
|
||||
struct v2 a = xform_mul_v2(G.world_view, ent->res.a0);
|
||||
struct v2 b = xform_mul_v2(G.world_view, ent->res.b0);
|
||||
draw_solid_line(G.viewport_canvas, a, b, thickness, color_line);
|
||||
draw_solid_circle(G.viewport_canvas, a, radius, color_a, 10);
|
||||
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
||||
}
|
||||
{
|
||||
struct v2 start = xform_mul_v2(G.world_view, ent->res.a1);
|
||||
struct v2 end = xform_mul_v2(G.world_view, ent->res.b1);
|
||||
draw_solid_line(G.viewport_canvas, start, end, thickness, color);
|
||||
draw_solid_circle(G.viewport_canvas, start, radius, color, 10);
|
||||
draw_solid_circle(G.viewport_canvas, end, radius, color, 10);
|
||||
struct v2 a = xform_mul_v2(G.world_view, ent->res.a1);
|
||||
struct v2 b = xform_mul_v2(G.world_view, ent->res.b1);
|
||||
draw_solid_line(G.viewport_canvas, a, b, thickness, color_line);
|
||||
draw_solid_circle(G.viewport_canvas, a, radius, color_a, 10);
|
||||
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user