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;
|
(UNUSED)radius1;
|
||||||
|
|
||||||
/* TODO: Parameterize */
|
/* TODO: Parameterize */
|
||||||
const f32 tolerance = 0.005f;
|
const f32 tolerance = 0.001f;
|
||||||
const f32 min_unique_pt_dist_sq = 0.001f * 0.001f;
|
const f32 min_unique_pt_dist_sq = 0.001f * 0.001f;
|
||||||
|
|
||||||
b32 colliding = false;
|
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);
|
m = menkowski_point(shape0, shape1, xf0, xf1, dir);
|
||||||
/* Check that new point is far enough away from existing point */
|
/* 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) {
|
if (v2_len_sq(v2_sub(m, s.a)) < min_unique_pt_dist_sq) {
|
||||||
|
simplex_is_closest_edge = true;
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
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 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac));
|
||||||
struct v2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
|
struct v2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab));
|
||||||
struct v2 rbc_dir = v2_perp_towards_dir(vbc, 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(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(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 */
|
voronoi_mask |= (v2_dot(rbc_dir, v2_neg(s.b)) > 0) << 2; /* Regions bc, b, and c */
|
||||||
@ -344,7 +345,15 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
}
|
}
|
||||||
proto[pen_pe_index] = m;
|
proto[pen_pe_index] = m;
|
||||||
}
|
}
|
||||||
} else if (simplex_is_closest_edge && s.len > 1) {
|
} 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
|
/* Shapes are not overlapping (origin is outside of simplex). Project
|
||||||
* origin to determine if distance is within tolerance. */
|
* origin to determine if distance is within tolerance. */
|
||||||
ASSERT(s.len == 2);
|
ASSERT(s.len == 2);
|
||||||
@ -358,6 +367,7 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
colliding = true;
|
colliding = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (colliding) {
|
if (colliding) {
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
21
src/game.c
21
src/game.c
@ -166,15 +166,15 @@ INTERNAL void spawn_test_entities(f32 offset)
|
|||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||||
//e->control_force = 4500;
|
//e->control_force = 4500;
|
||||||
e->control_force = 1200;
|
//e->control_force = 1200;
|
||||||
//e->control_force = 250;
|
e->control_force = 250;
|
||||||
e->control_torque = 10;
|
e->control_torque = 10;
|
||||||
e->control.focus = V2(0, -1);
|
e->control.focus = V2(0, -1);
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
||||||
e->mass_unscaled = 100;
|
e->mass_unscaled = 100;
|
||||||
//e->inertia_unscaled = F32_INFINITY;
|
e->inertia_unscaled = F32_INFINITY;
|
||||||
e->inertia_unscaled = 25;
|
//e->inertia_unscaled = 25;
|
||||||
e->linear_ground_friction = 1000;
|
e->linear_ground_friction = 1000;
|
||||||
e->angular_ground_friction = 100;
|
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, 29);
|
||||||
//struct v2 pos = V2(0.5, 24);
|
//struct v2 pos = V2(0.5, 24);
|
||||||
//struct v2 pos = V2(1, -1);
|
//struct v2 pos = V2(1, -1);
|
||||||
struct v2 size = V2(1, 1);
|
//struct v2 size = V2(1, 1);
|
||||||
//struct v2 size = V2(500, 50);
|
struct v2 size = V2(500, 1);
|
||||||
//f32 rot = PI / 4;
|
//f32 rot = PI / 4;
|
||||||
f32 rot = 0;
|
f32 rot = 0;
|
||||||
struct entity *e = entity_alloc(root);
|
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 vcp1 = v2_sub(p1, e1_xf.og);
|
||||||
|
|
||||||
struct v2 impulse = v2_add(v2_mul(normal, contact->normal_impulse), v2_mul(tangent, contact->tangent_impulse));
|
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));
|
v0 = v2_sub(v0, v2_mul(impulse, contact->inv_m0));
|
||||||
v1 = v2_add(v1, v2_mul(impulse, contact->inv_m1));
|
v1 = v2_add(v1, v2_mul(impulse, contact->inv_m1));
|
||||||
@ -611,9 +611,10 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
|||||||
f32 mass_scale = 1.0f;
|
f32 mass_scale = 1.0f;
|
||||||
f32 impulse_scale = 0.0f;
|
f32 impulse_scale = 0.0f;
|
||||||
|
|
||||||
|
if (apply_bias) {
|
||||||
if (separation > 0.0f) {
|
if (separation > 0.0f) {
|
||||||
velocity_bias = separation / dt;
|
velocity_bias = separation / dt;
|
||||||
} else if (apply_bias) {
|
} else {
|
||||||
/* Soft constraint */
|
/* Soft constraint */
|
||||||
|
|
||||||
f32 contact_damping_ratio = 10.0f;
|
f32 contact_damping_ratio = 10.0f;
|
||||||
@ -627,6 +628,7 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
|||||||
mass_scale = softness.mass_scale;
|
mass_scale = softness.mass_scale;
|
||||||
impulse_scale = softness.impulse_scale;
|
impulse_scale = softness.impulse_scale;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
||||||
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
||||||
@ -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);
|
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 = 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 (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
#if 0
|
#if 0
|
||||||
@ -1357,7 +1358,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
* Create ground friction force (gravity)
|
* Create ground friction force (gravity)
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
/* TODO: Do this globally rather than creating entities for constant forces */
|
/* TODO: Do this globally rather than creating entities for constant forces */
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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;
|
G.window = window;
|
||||||
sys_window_register_event_callback(G.window, &window_event_callback);
|
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"));
|
G.user_thread = sys_thread_alloc(&user_thread_entry_point, NULL, STR("[P1] User thread"));
|
||||||
app_register_exit_callback(&user_shutdown);
|
app_register_exit_callback(&user_shutdown);
|
||||||
|
|
||||||
@ -994,9 +996,9 @@ INTERNAL void user_update(void)
|
|||||||
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
||||||
struct collider_shape collider = ent->local_collider;
|
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);
|
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 = 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, 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);
|
draw_solid_collider_line(G.viewport_canvas, G.world_view, collider, xf, thickness, color, detail);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user