fix collision issue between capsule rounded edge & corners, and with reverse-winding shapes
This commit is contained in:
parent
33df739cc6
commit
2260b1bc36
@ -425,18 +425,32 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
|
|
||||||
f32 vap_wedge = v2_wedge(vap, normal);
|
f32 vap_wedge = v2_wedge(vap, normal);
|
||||||
f32 vpb_wedge = v2_wedge(vpb, normal);
|
f32 vpb_wedge = v2_wedge(vpb, normal);
|
||||||
if (count0 > 2 && v2_winding(vap, vpb) > 0) {
|
b32 reversed = count0 > 1 && v2_winding(vap, vpb) < 0;
|
||||||
/* Winding is reversed, swap */
|
if (reversed) {
|
||||||
|
/* Winding is reversed, swap vap & vpb wedge */
|
||||||
f32 t = vap_wedge;
|
f32 t = vap_wedge;
|
||||||
vap_wedge = vpb_wedge;
|
vap_wedge = vpb_wedge;
|
||||||
vpb_wedge = t;
|
vpb_wedge = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vap_wedge > (vpb_wedge + wedge_epsilon)) {
|
if (vap_wedge < (vpb_wedge + wedge_epsilon)) {
|
||||||
|
if (reversed) {
|
||||||
|
id_a0 = p_i;
|
||||||
|
id_b0 = a_i;
|
||||||
|
a0 = p;
|
||||||
|
b0 = a;
|
||||||
|
} else {
|
||||||
id_a0 = a_i;
|
id_a0 = a_i;
|
||||||
id_b0 = p_i;
|
id_b0 = p_i;
|
||||||
a0 = a;
|
a0 = a;
|
||||||
b0 = p;
|
b0 = p;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (reversed) {
|
||||||
|
id_a0 = b_i;
|
||||||
|
id_b0 = p_i;
|
||||||
|
a0 = b;
|
||||||
|
b0 = p;
|
||||||
} else {
|
} else {
|
||||||
id_a0 = p_i;
|
id_a0 = p_i;
|
||||||
id_b0 = b_i;
|
id_b0 = b_i;
|
||||||
@ -444,12 +458,13 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
b0 = b;
|
b0 = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
struct v2 neg_normal = v2_neg(normal);
|
struct v2 neg_normal = v2_neg(normal);
|
||||||
|
|
||||||
u32 p_i = collider_support_point_index(shape1, xf1, neg_normal);
|
u32 p_i = collider_support_point_index(shape1, xf1, neg_normal);
|
||||||
u32 a_i = ((p_i + 1) < count1) ? (p_i + 1) : 0;
|
u32 a_i = (p_i > 0) ? (p_i - 1) : (count1 - 1);
|
||||||
u32 b_i = (p_i > 0) ? (p_i - 1) : (count1 - 1);
|
u32 b_i = ((p_i + 1) < count1) ? (p_i + 1) : 0;
|
||||||
|
|
||||||
struct v2 p = xform_mul_v2(xf1, points1[p_i]);
|
struct v2 p = xform_mul_v2(xf1, points1[p_i]);
|
||||||
struct v2 a = xform_mul_v2(xf1, points1[a_i]);
|
struct v2 a = xform_mul_v2(xf1, points1[a_i]);
|
||||||
@ -460,23 +475,38 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
|
|
||||||
f32 vap_wedge = v2_wedge(vap, normal);
|
f32 vap_wedge = v2_wedge(vap, normal);
|
||||||
f32 vpb_wedge = v2_wedge(vpb, normal);
|
f32 vpb_wedge = v2_wedge(vpb, normal);
|
||||||
if (count1 > 2 && v2_winding(vap, vpb) < 0) {
|
b32 reversed = count1 > 1 && v2_winding(vap, vpb) < 0;
|
||||||
/* Winding is reversed, swap */
|
if (reversed) {
|
||||||
|
/* Winding is reversed, swapvap & vpb wedge*/
|
||||||
f32 t = vap_wedge;
|
f32 t = vap_wedge;
|
||||||
vap_wedge = vpb_wedge;
|
vap_wedge = vpb_wedge;
|
||||||
vpb_wedge = t;
|
vpb_wedge = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vap_wedge > (vpb_wedge + wedge_epsilon)) {
|
if (vap_wedge > (vpb_wedge + wedge_epsilon)) {
|
||||||
|
if (reversed) {
|
||||||
id_a1 = a_i;
|
id_a1 = a_i;
|
||||||
id_b1 = p_i;
|
id_b1 = p_i;
|
||||||
a1 = a;
|
a1 = a;
|
||||||
b1 = p;
|
b1 = p;
|
||||||
} else {
|
} else {
|
||||||
|
id_a1 = p_i;
|
||||||
|
id_b1 = a_i;
|
||||||
|
a1 = p;
|
||||||
|
b1 = a;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (reversed) {
|
||||||
id_a1 = p_i;
|
id_a1 = p_i;
|
||||||
id_b1 = b_i;
|
id_b1 = b_i;
|
||||||
a1 = p;
|
a1 = p;
|
||||||
b1 = b;
|
b1 = b;
|
||||||
|
} else {
|
||||||
|
id_a1 = b_i;
|
||||||
|
id_b1 = p_i;
|
||||||
|
a1 = b;
|
||||||
|
b1 = p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
35
src/game.c
35
src/game.c
@ -399,6 +399,29 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
e->angular_ground_friction = 200;
|
e->angular_ground_friction = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Box */
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
struct entity *e = entity_alloc(root);
|
||||||
|
|
||||||
|
struct v2 pos = V2(1, -0.5);
|
||||||
|
f32 r = 0;
|
||||||
|
struct v2 size = V2(0.5, 0.25);
|
||||||
|
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||||
|
entity_set_xform(e, xf);
|
||||||
|
|
||||||
|
e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase"));
|
||||||
|
e->sprite_collider_slice = STR("shape");
|
||||||
|
|
||||||
|
entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC);
|
||||||
|
e->mass_unscaled = 10;
|
||||||
|
e->inertia_unscaled = 10;
|
||||||
|
e->linear_ground_friction = 250;
|
||||||
|
e->angular_ground_friction = 5;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Player weapon */
|
/* Player weapon */
|
||||||
if (player_ent->valid) {
|
if (player_ent->valid) {
|
||||||
struct entity *e = entity_alloc(player_ent);
|
struct entity *e = entity_alloc(player_ent);
|
||||||
@ -1654,13 +1677,13 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
#elif 1
|
#elif 1
|
||||||
#if 0
|
#if 0
|
||||||
/* "Bad" winding order */
|
/* "Bad" winding order */
|
||||||
ent->local_collider.points[0] = V2(-0.5, 0.5);
|
ent->local_collider.points[0] = V2(-0.15, 0.15);
|
||||||
ent->local_collider.points[1] = V2(0.5, 0.5);
|
ent->local_collider.points[1] = V2(0.15, 0.15);
|
||||||
ent->local_collider.points[2] = V2(0, -0.5);
|
ent->local_collider.points[2] = V2(0, -0.15);
|
||||||
#else
|
#else
|
||||||
ent->local_collider.points[0] = V2(0, -0.5);
|
ent->local_collider.points[0] = V2(0, -0.15);
|
||||||
ent->local_collider.points[1] = V2(0.5, 0.5);
|
ent->local_collider.points[1] = V2(0.15, 0.15);
|
||||||
ent->local_collider.points[2] = V2(-0.5, 0.5);
|
ent->local_collider.points[2] = V2(-0.15, 0.15);
|
||||||
#endif
|
#endif
|
||||||
ent->local_collider.count = 3;
|
ent->local_collider.count = 3;
|
||||||
ent->local_collider.radius = 0.25;
|
ent->local_collider.radius = 0.25;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user