ignore speculative bias during relaxation for stabililty
This commit is contained in:
parent
ac042a3306
commit
33b32e849c
@ -85,7 +85,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
(UNUSED)radius1;
|
||||
|
||||
/* TODO: Parameterize */
|
||||
const f32 tolerance = 0.005f;
|
||||
const f32 tolerance = 0.001f;
|
||||
const f32 min_unique_pt_dist_sq = 0.001f * 0.001f;
|
||||
|
||||
b32 colliding = false;
|
||||
@ -130,6 +130,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
m = menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||
/* Check that new point is far enough away from existing point */
|
||||
if (v2_len_sq(v2_sub(m, s.a)) < min_unique_pt_dist_sq) {
|
||||
simplex_is_closest_edge = true;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
@ -172,7 +173,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
struct v2 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac));
|
||||
struct v2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
|
||||
struct v2 rbc_dir = v2_perp_towards_dir(vbc, vab);
|
||||
#if 0
|
||||
#if 1
|
||||
voronoi_mask |= (v2_dot(rab_dir, v2_neg(s.a)) > 0) << 0; /* Regions ab, a, and b*/
|
||||
voronoi_mask |= (v2_dot(rac_dir, v2_neg(s.a)) > 0) << 1; /* Regions ac, a, and c */
|
||||
voronoi_mask |= (v2_dot(rbc_dir, v2_neg(s.b)) > 0) << 2; /* Regions bc, b, and c */
|
||||
@ -344,18 +345,27 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
||||
}
|
||||
proto[pen_pe_index] = m;
|
||||
}
|
||||
} else if (simplex_is_closest_edge && s.len > 1) {
|
||||
/* Shapes are not overlapping (origin is outside of simplex). Project
|
||||
* origin to determine if distance is within tolerance. */
|
||||
ASSERT(s.len == 2);
|
||||
struct v2 vab = v2_sub(s.b, s.a);
|
||||
struct v2 vao = v2_neg(s.a);
|
||||
f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
||||
struct v2 p = v2_add(s.a, v2_mul(vab, ratio));
|
||||
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
||||
res.path = 2;
|
||||
normal = v2_norm(dir);
|
||||
colliding = true;
|
||||
} else if (simplex_is_closest_edge) {
|
||||
if (s.len == 1) {
|
||||
struct v2 p = v2_neg(s.a);
|
||||
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
||||
res.path = 2;
|
||||
normal = v2_norm(dir);
|
||||
colliding = true;
|
||||
}
|
||||
} else {
|
||||
/* Shapes are not overlapping (origin is outside of simplex). Project
|
||||
* origin to determine if distance is within tolerance. */
|
||||
ASSERT(s.len == 2);
|
||||
struct v2 vab = v2_sub(s.b, s.a);
|
||||
struct v2 vao = v2_neg(s.a);
|
||||
f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
||||
struct v2 p = v2_add(s.a, v2_mul(vab, ratio));
|
||||
if (v2_len_sq(p) <= (tolerance * tolerance)) {
|
||||
res.path = 2;
|
||||
normal = v2_norm(dir);
|
||||
colliding = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
41
src/game.c
41
src/game.c
@ -166,15 +166,15 @@ 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);
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
||||
e->mass_unscaled = 100;
|
||||
//e->inertia_unscaled = F32_INFINITY;
|
||||
e->inertia_unscaled = 25;
|
||||
e->inertia_unscaled = F32_INFINITY;
|
||||
//e->inertia_unscaled = 25;
|
||||
e->linear_ground_friction = 1000;
|
||||
e->angular_ground_friction = 100;
|
||||
|
||||
@ -212,8 +212,8 @@ INTERNAL void spawn_test_entities(f32 offset)
|
||||
//struct v2 pos = V2(0.5, 29);
|
||||
//struct v2 pos = V2(0.5, 24);
|
||||
//struct v2 pos = V2(1, -1);
|
||||
struct v2 size = V2(1, 1);
|
||||
//struct v2 size = V2(500, 50);
|
||||
//struct v2 size = V2(1, 1);
|
||||
struct v2 size = V2(500, 1);
|
||||
//f32 rot = PI / 4;
|
||||
f32 rot = 0;
|
||||
struct entity *e = entity_alloc(root);
|
||||
@ -523,7 +523,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));
|
||||
@ -611,21 +611,23 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
||||
f32 mass_scale = 1.0f;
|
||||
f32 impulse_scale = 0.0f;
|
||||
|
||||
if (separation > 0.0f) {
|
||||
velocity_bias = separation / dt;
|
||||
} else if (apply_bias) {
|
||||
/* Soft constraint */
|
||||
if (apply_bias) {
|
||||
if (separation > 0.0f) {
|
||||
velocity_bias = separation / dt;
|
||||
} else {
|
||||
/* 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));
|
||||
@ -954,7 +956,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
{
|
||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), ent->animation_frame);
|
||||
ent->local_collider = collider_from_quad(xform_mul_quad(ent->sprite_local_xform, quad_from_rect(slice.rect)));
|
||||
ent->local_collider.radius = 0.1;
|
||||
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
#if 0
|
||||
@ -1357,7 +1358,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
* Create ground friction force (gravity)
|
||||
* ========================== */
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
/* TODO: Do this globally rather than creating entities for constant forces */
|
||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||
struct entity *ent = &store->entities[entity_index];
|
||||
|
||||
@ -146,6 +146,8 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
|
||||
G.window = window;
|
||||
sys_window_register_event_callback(G.window, &window_event_callback);
|
||||
|
||||
G.debug_draw = true;
|
||||
|
||||
G.user_thread = sys_thread_alloc(&user_thread_entry_point, NULL, STR("[P1] User thread"));
|
||||
app_register_exit_callback(&user_shutdown);
|
||||
|
||||
@ -994,9 +996,9 @@ INTERNAL void user_update(void)
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
||||
struct collider_shape collider = ent->local_collider;
|
||||
u32 color = ent->colliding ? RGBA_32_F(1, 1, 1, 0.5) : RGBA_32_F(1, 1, 0, 0.25);
|
||||
f32 thickness = 1;
|
||||
f32 thickness = 2;
|
||||
//u32 detail = 32;
|
||||
u32 detail = 256;
|
||||
u32 detail = 512;
|
||||
//draw_solid_collider_line(G.viewport_canvas, collider, xform_mul(G.world_view, xf), thickness, color, detail);
|
||||
draw_solid_collider_line(G.viewport_canvas, G.world_view, collider, xf, thickness, color, detail);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user