fix clip winding swap

This commit is contained in:
jacob 2024-10-30 13:58:11 -05:00
parent c8b48b9537
commit c071e17305
4 changed files with 72 additions and 37 deletions

View File

@ -425,7 +425,14 @@ struct collider_collision_points_result collider_collision_points(struct collide
f32 vap_wedge = v2_wedge(vap, normal);
f32 vpb_wedge = v2_wedge(vpb, normal);
if (vap_wedge * v2_winding(vap, vpb) < (vpb_wedge + wedge_epsilon)) {
if (count0 > 2 && v2_winding(vap, vpb) > 0) {
/* Winding is reversed, swap */
f32 t = vap_wedge;
vap_wedge = vpb_wedge;
vpb_wedge = t;
}
if (vap_wedge > (vpb_wedge + wedge_epsilon)) {
id_a0 = a_i;
id_b0 = p_i;
a0 = a;
@ -453,7 +460,14 @@ struct collider_collision_points_result collider_collision_points(struct collide
f32 vap_wedge = v2_wedge(vap, normal);
f32 vpb_wedge = v2_wedge(vpb, normal);
if (vap_wedge * -v2_winding(vap, vpb) < (vpb_wedge + wedge_epsilon)) {
if (count1 > 2 && v2_winding(vap, vpb) < 0) {
/* Winding is reversed, swap */
f32 t = vap_wedge;
vap_wedge = vpb_wedge;
vpb_wedge = t;
}
if (vap_wedge > (vpb_wedge + wedge_epsilon)) {
id_a1 = a_i;
id_b1 = p_i;
a1 = a;

View File

@ -41,11 +41,13 @@
#define GAME_PHYSICS_ENABLE_COLLISION 1
#define GAME_SPAWN_LOTS 0
#define GAME_SPAWN_TESTENT 0
#define GAME_SPAWN_BOX 1
#define GAME_SPAWN_BOX 0
#define GAME_PLAYER_AIM 1
#define GAME_MAX_LINEAR_VELOCITY 100
#define GAME_MAX_ANGULAR_VELOCITY (TAU * 20)
//#define GAME_MAX_LINEAR_VELOCITY 500
//#define GAME_MAX_ANGULAR_VELOCITY (TAU * 20)
#define GAME_MAX_LINEAR_VELOCITY F32_INFINITY
#define GAME_MAX_ANGULAR_VELOCITY F32_INFINITY
/* How many ticks back in time should the user blend between?
* <Delay ms> = <USER_INTERP_OFFSET_TICK_RATIO> * <Game tick rate>

View File

@ -177,10 +177,21 @@ INTERNAL void spawn_test_entities(f32 offset)
f32 r = 0;
if (!G.extra_spawn) {
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
entity_enable_prop(e, ENTITY_PROP_TEST);
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
e->mass_unscaled = 10;
e->inertia_unscaled = 5;
} else {
entity_enable_prop(e, ENTITY_PROP_TEST);
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
e->mass_unscaled = 10;
e->inertia_unscaled = 5;
#if 0
e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase"));
//size = V2(0.5, 0.5);
e->mass_unscaled = 100;
e->inertia_unscaled = 100;
#endif
}
//e->sprite = sprite_tag_from_path(STR("res/graphics/box_rounded.ase"));
@ -194,32 +205,21 @@ INTERNAL void spawn_test_entities(f32 offset)
entity_set_xform(e, xf);
if (!G.extra_spawn) {
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
}
e->linear_ground_friction = 150;
e->angular_ground_friction = 100;
e->linear_ground_friction = 250;
e->angular_ground_friction = 200;
//e->control_force = 500;
e->control_force = 500;
//e->control_force_max_speed = 4;
e->control_torque = 500;
e->control_torque = 1000;
e->control_force_max_speed = 4;
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
e->mass_unscaled = 10;
e->inertia_unscaled = 10;
entity_enable_prop(e, ENTITY_PROP_TEST);
player_ent = e;
#if 0
#if 1
{
struct entity *joint_ent = entity_alloc(root);
entity_enable_prop(joint_ent, ENTITY_PROP_PHYSICAL);
@ -1203,12 +1203,31 @@ INTERNAL void solve_mouse_joints(f32 dt)
f32 mass_scale = softness.mass_scale;
f32 impulse_scale = softness.impulse_scale;
#if 0
struct v2 vel = v2_add(v, v2_perp_mul(vcp, w));
struct v2 b = v2_mul(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias)), mass_scale);
struct v2 b = v2_mul(xform_basis_mul_v2(xform_invert(joint->linear_mass_xf), v2_add(vel, bias)), mass_scale);
struct v2 old_impulse = joint->linear_impulse;
struct v2 impulse = v2_sub(v2_mul(old_impulse, -impulse_scale), b);
joint->linear_impulse = v2_clamp_len(v2_add(joint->linear_impulse, impulse), max_impulse);
impulse = v2_sub(joint->linear_impulse, old_impulse);
#else
struct v2 vel = v2_add(v, v2_perp_mul(vcp, w));
struct v2 b = xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias));
struct v2 impulse;
impulse.x = -mass_scale * b.x - impulse_scale * joint->linear_impulse.x;
impulse.y = -mass_scale * b.y - impulse_scale * joint->linear_impulse.y;
struct v2 old_impulse = joint->linear_impulse;
joint->linear_impulse.x += impulse.x;
joint->linear_impulse.y += impulse.y;
joint->linear_impulse = v2_clamp_len(joint->linear_impulse, max_impulse);
impulse.x = joint->linear_impulse.x - old_impulse.x;
impulse.y = joint->linear_impulse.y - old_impulse.y;
#endif
v = v2_add(v, v2_mul(impulse, inv_m));
w += v2_wedge(vcp, impulse) * inv_i;
@ -1513,20 +1532,20 @@ 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(cxf, quad_from_rect(slice.rect)));
#if 0
#if 1
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
//if ((true)) {
#if 1
#if 0
ent->local_collider.points[0] = V2(0, 0);
ent->local_collider.count = 1;
ent->local_collider.radius = 0.5;
#elif 0
ent->local_collider.points[0] = V2(0, 0.5);
ent->local_collider.points[1] = V2(0, -0.5);
#elif 1
ent->local_collider.points[0] = v2_with_len(V2(0.08, 0.17), 0.15);
ent->local_collider.points[1] = v2_with_len(V2(-0.07, -0.2), 0.15);
ent->local_collider.count = 2;
ent->local_collider.radius = 0.25;
#elif 0
#if 1
ent->local_collider.radius = 0.075;
#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);

View File

@ -87,7 +87,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
/* Testing */
[SYS_BTN_M1] = USER_BIND_KIND_DEBUG_DRAG,
[SYS_BTN_M2] = USER_BIND_KIND_DEBUG_DRAG,
[SYS_BTN_C] = USER_BIND_KIND_DEBUG_CLEAR,
[SYS_BTN_V] = USER_BIND_KIND_DEBUG_SPAWN,
[SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP,
@ -1098,7 +1098,7 @@ INTERNAL void user_update(void)
/* Draw menkowski */
{
u32 color = ent->res.solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1);
u32 color = data->res.solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1);
f32 thickness = 2;
u32 detail = 512;
(UNUSED)thickness;
@ -1131,7 +1131,7 @@ INTERNAL void user_update(void)
f32 arrow_thickness = 2;
f32 arrow_height = 5;
struct v2 start = xform_mul_v2(G.world_view, V2(0, 0));
struct v2 end = xform_mul_v2(G.world_view, v2_mul(v2_norm(ent->manifold_normal), len));
struct v2 end = xform_mul_v2(G.world_view, v2_mul(v2_norm(data->normal), len));
draw_solid_arrow_line(G.viewport_canvas, start, end, arrow_thickness, arrow_height, color);
}
@ -1141,8 +1141,8 @@ INTERNAL void user_update(void)
u32 color = RGBA_32_F(1, 1, 1, 0.25);
struct v2_array m = {
.points = ent->res.prototype.points,
.count = ent->res.prototype.len
.points = data->res.prototype.points,
.count = data->res.prototype.len
};
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_view, m.points[i]);
draw_solid_poly_line(G.viewport_canvas, m, true, thickness, color);
@ -1157,7 +1157,7 @@ INTERNAL void user_update(void)
u32 color_second = RGBA_32_F(0, 1, 0, 0.75);
u32 color_third = RGBA_32_F(0, 0, 1, 0.75);
struct collider_simplex simplex = ent->res.simplex;
struct collider_simplex simplex = data->res.simplex;
struct v2 simplex_points[] = { simplex.a, simplex.b, simplex.c };
for (u64 i = 0; i < ARRAY_COUNT(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_view, simplex_points[i]);
struct v2_array simplex_array = { .count = simplex.len, .points = simplex_points };
@ -1417,7 +1417,7 @@ INTERNAL void user_update(void)
/* Queue physics drag cmd */
i32 drag_presses = G.bind_states[USER_BIND_KIND_DEBUG_DRAG].num_presses - G.bind_states[USER_BIND_KIND_DEBUG_DRAG].num_releases;
if (G.debug_camera && drag_presses) {
if (drag_presses) {
queue_game_cmd(scratch.arena, &cmd_list, (struct game_cmd) {
.kind = GAME_CMD_KIND_DRAG_OBJECT,
.state = drag_presses > 0 ? GAME_CMD_STATE_START : GAME_CMD_STATE_STOP