working on capsule collision bug
This commit is contained in:
parent
85234c8dac
commit
a1b8f752c9
@ -4,10 +4,12 @@
|
|||||||
#include "scratch.h"
|
#include "scratch.h"
|
||||||
|
|
||||||
/* How close can non-overlapping shapes be before collision is considered */
|
/* How close can non-overlapping shapes be before collision is considered */
|
||||||
#define COLLISION_TOLERANCE 0.005f
|
//#define COLLISION_TOLERANCE 0.005f
|
||||||
|
#define COLLISION_TOLERANCE 0.0005f
|
||||||
|
|
||||||
/* NOTE: Should always be less than tolerance, since colliding = true if origin is within this distance. */
|
/* NOTE: Should always be less than tolerance, since colliding = true if origin is within this distance. */
|
||||||
#define MIN_UNIQUE_PT_DIST_SQ (0.001f * 0.001f)
|
//#define MIN_UNIQUE_PT_DIST_SQ (0.001f * 0.001f)
|
||||||
|
#define MIN_UNIQUE_PT_DIST_SQ (0.0001f * 0.0001f)
|
||||||
|
|
||||||
/* To prevent extremely large prototypes when origin is in exact center of rounded feature */
|
/* To prevent extremely large prototypes when origin is in exact center of rounded feature */
|
||||||
#define MAX_EPA_ITERATIONS 64
|
#define MAX_EPA_ITERATIONS 64
|
||||||
@ -366,7 +368,7 @@ INTERNAL struct epa_result epa_get_normal_from_gjk(struct collider_shape *shape0
|
|||||||
{
|
{
|
||||||
/* NOTE: Changing this value affects how stable normals are for circular colliders */
|
/* NOTE: Changing this value affects how stable normals are for circular colliders */
|
||||||
//const f32 validity_epsilon = min_unique_pt_dist_sq; /* Arbitrary */
|
//const f32 validity_epsilon = min_unique_pt_dist_sq; /* Arbitrary */
|
||||||
const f32 validity_epsilon = 0.0000000001f; /* Arbitrary */
|
const f32 validity_epsilon = 0.00000000001f; /* Arbitrary */
|
||||||
|
|
||||||
struct v2 vam = v2_sub(m.p, closest_a.p);
|
struct v2 vam = v2_sub(m.p, closest_a.p);
|
||||||
struct v2 vbm = v2_sub(closest_b.p, closest_a.p);
|
struct v2 vbm = v2_sub(closest_b.p, closest_a.p);
|
||||||
@ -511,7 +513,8 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
|
|
||||||
DBGSTEP;
|
DBGSTEP;
|
||||||
{
|
{
|
||||||
const f32 wedge_epsilon = 0.05f;
|
const f32 wedge_epsilon = 0.001f;
|
||||||
|
//const f32 wedge_epsilon = 0.05f;
|
||||||
//const f32 wedge_epsilon = 0.1f;
|
//const f32 wedge_epsilon = 0.1f;
|
||||||
|
|
||||||
/* shape0 a -> b winding = clockwise */
|
/* shape0 a -> b winding = clockwise */
|
||||||
@ -655,8 +658,13 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
f32 vab0_wedge_normal = v2_wedge(vab0, normal);
|
f32 vab0_wedge_normal = v2_wedge(vab0, normal);
|
||||||
f32 vab1_wedge_normal = v2_wedge(vab1, normal);
|
f32 vab1_wedge_normal = v2_wedge(vab1, normal);
|
||||||
|
|
||||||
|
#if 0
|
||||||
b32 collapse0 = math_fabs(vab0_wedge_normal) < wedge_epsilon;
|
b32 collapse0 = math_fabs(vab0_wedge_normal) < wedge_epsilon;
|
||||||
b32 collapse1 = math_fabs(vab1_wedge_normal) < wedge_epsilon;
|
b32 collapse1 = math_fabs(vab1_wedge_normal) < wedge_epsilon;
|
||||||
|
#else
|
||||||
|
b32 collapse0 = false;
|
||||||
|
b32 collapse1 = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (collapse0) {
|
if (collapse0) {
|
||||||
if (v2_dot(b0, normal) >= v2_dot(a0, normal)) {
|
if (v2_dot(b0, normal) >= v2_dot(a0, normal)) {
|
||||||
@ -741,17 +749,15 @@ struct collider_collision_points_result collider_collision_points(struct collide
|
|||||||
point->point = contact_b;
|
point->point = contact_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
/* TODO: Remove this */
|
||||||
res.a0 = a0_clipped;
|
res.a0_clipped = a0_clipped;
|
||||||
res.a1 = a1_clipped;
|
res.a1_clipped = a1_clipped;
|
||||||
res.b0 = b0_clipped;
|
res.b0_clipped = b0_clipped;
|
||||||
res.b1 = b1_clipped;
|
res.b1_clipped = b1_clipped;
|
||||||
#else
|
|
||||||
res.a0 = a0;
|
res.a0 = a0;
|
||||||
res.a1 = a1;
|
res.a1 = a1;
|
||||||
res.b0 = b0;
|
res.b0 = b0;
|
||||||
res.b1 = b1;
|
res.b1 = b1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,10 @@ struct collider_collision_points_result {
|
|||||||
b32 solved;
|
b32 solved;
|
||||||
struct collider_menkowski_simplex simplex;
|
struct collider_menkowski_simplex simplex;
|
||||||
struct collider_prototype prototype;
|
struct collider_prototype prototype;
|
||||||
struct v2 a0, b0, a1, b1; /* Clipping faces */
|
|
||||||
|
/* Clipping faces */
|
||||||
|
struct v2 a0, b0, a1, b1;
|
||||||
|
struct v2 a0_clipped, b0_clipped, a1_clipped, b1_clipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct collider_closest_points_result {
|
struct collider_closest_points_result {
|
||||||
|
|||||||
@ -37,8 +37,7 @@
|
|||||||
#define GAME_PHYSICS_ENABLE_RELAXATION 1
|
#define GAME_PHYSICS_ENABLE_RELAXATION 1
|
||||||
#define GAME_PHYSICS_ENABLE_TOI 1
|
#define GAME_PHYSICS_ENABLE_TOI 1
|
||||||
|
|
||||||
#define USER_DRAW_MENKOWSKI 0
|
#define GAME_PHYSICS_ENABLE_COLLISION 0
|
||||||
#define GAME_PHYSICS_ENABLE_COLLISION 1
|
|
||||||
#define GAME_SPAWN_TESTENT 0
|
#define GAME_SPAWN_TESTENT 0
|
||||||
#define GAME_PLAYER_AIM 1
|
#define GAME_PLAYER_AIM 1
|
||||||
|
|
||||||
@ -55,7 +54,8 @@
|
|||||||
#define USER_INTERP_ENABLED 1
|
#define USER_INTERP_ENABLED 1
|
||||||
|
|
||||||
#define COLLIDER_DEBUG RTC
|
#define COLLIDER_DEBUG RTC
|
||||||
#define COLLIDER_DEBUG_DETAILED 0
|
#define COLLIDER_DEBUG_DETAILED 1
|
||||||
|
#define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 1
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Settings
|
* Settings
|
||||||
|
|||||||
35
src/game.c
35
src/game.c
@ -192,11 +192,15 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->local_collider.points[0] = v2_with_len(V2(0.08f, 0.17f), 0.15f);
|
||||||
|
e->local_collider.points[1] = v2_with_len(V2(-0.07f, -0.2f), 0.15f);
|
||||||
|
e->local_collider.count = 2;
|
||||||
|
e->local_collider.radius = 0.075f;
|
||||||
|
|
||||||
//e->sprite = sprite_tag_from_path(STR("res/graphics/box_rounded.ase"));
|
//e->sprite = sprite_tag_from_path(STR("res/graphics/box_rounded.ase"));
|
||||||
//e->sprite_span_name = STR("idle.unarmed");
|
//e->sprite_span_name = STR("idle.unarmed");
|
||||||
//e->sprite_span_name = STR("idle.one_handed");
|
//e->sprite_span_name = STR("idle.one_handed");
|
||||||
e->sprite_span_name = STR("idle.two_handed");
|
e->sprite_span_name = STR("idle.two_handed");
|
||||||
e->sprite_collider_slice = STR("shape");
|
|
||||||
|
|
||||||
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||||
//xf.bx.y = -1.f;
|
//xf.bx.y = -1.f;
|
||||||
@ -218,6 +222,7 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Enemy */
|
/* Enemy */
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
struct entity *e = entity_alloc(root);
|
struct entity *e = entity_alloc(root);
|
||||||
|
|
||||||
@ -236,11 +241,13 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
e->linear_ground_friction = 250;
|
e->linear_ground_friction = 250;
|
||||||
e->angular_ground_friction = 200;
|
e->angular_ground_friction = 200;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Box */
|
/* Box */
|
||||||
#if 0
|
#if 1
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
struct entity *e = entity_alloc(root);
|
struct entity *e = entity_alloc(root);
|
||||||
|
|
||||||
struct v2 pos = V2(1, -0.5);
|
struct v2 pos = V2(1, -0.5);
|
||||||
@ -257,6 +264,23 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
e->inertia_unscaled = 10;
|
e->inertia_unscaled = 10;
|
||||||
e->linear_ground_friction = 250;
|
e->linear_ground_friction = 250;
|
||||||
e->angular_ground_friction = 5;
|
e->angular_ground_friction = 5;
|
||||||
|
#else
|
||||||
|
struct entity *e = entity_alloc(root);
|
||||||
|
|
||||||
|
struct v2 pos = V2(1, -0.5);
|
||||||
|
f32 r = PI / 4;
|
||||||
|
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/bullet.ase"));
|
||||||
|
e->sprite_collider_slice = STR("shape");
|
||||||
|
|
||||||
|
entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC);
|
||||||
|
e->mass_unscaled = 0.5;
|
||||||
|
e->inertia_unscaled = 1000;
|
||||||
|
e->linear_ground_friction = 0.001;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -615,7 +639,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, ent->sprite_collider_slice, ent->animation_frame);
|
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, ent->sprite_collider_slice, ent->animation_frame);
|
||||||
ent->local_collider = collider_from_quad(xform_mul_quad(cxf, quad_from_rect(slice.rect)));
|
ent->local_collider = collider_from_quad(xform_mul_quad(cxf, quad_from_rect(slice.rect)));
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||||
//if ((true)) {
|
//if ((true)) {
|
||||||
#if 0
|
#if 0
|
||||||
@ -839,9 +863,14 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
bullet->mass_unscaled = 0.04f;
|
bullet->mass_unscaled = 0.04f;
|
||||||
bullet->inertia_unscaled = 0.00001f;
|
bullet->inertia_unscaled = 0.00001f;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Point collider */
|
/* Point collider */
|
||||||
bullet->local_collider.points[0] = V2(0, 0);
|
bullet->local_collider.points[0] = V2(0, 0);
|
||||||
bullet->local_collider.count = 1;
|
bullet->local_collider.count = 1;
|
||||||
|
#else
|
||||||
|
bullet->sprite = sprite_tag_from_path(STR("res/graphics/bullet.ase"));
|
||||||
|
bullet->sprite_collider_slice = STR("shape");
|
||||||
|
#endif
|
||||||
|
|
||||||
entity_enable_prop(bullet, ENTITY_PROP_BULLET);
|
entity_enable_prop(bullet, ENTITY_PROP_BULLET);
|
||||||
entity_enable_prop(bullet, ENTITY_PROP_SENSOR);
|
entity_enable_prop(bullet, ENTITY_PROP_SENSOR);
|
||||||
|
|||||||
@ -245,15 +245,6 @@ struct phys_collision_data_array phys_create_contacts(struct arena *arena, struc
|
|||||||
|
|
||||||
struct phys_collision_debug *dbg = &dbg_ent->collision_debug_data;
|
struct phys_collision_debug *dbg = &dbg_ent->collision_debug_data;
|
||||||
|
|
||||||
if (dbg->res.num_points == 0) {
|
|
||||||
if (collider_res.num_points > 0) {
|
|
||||||
++e0->colliding;
|
|
||||||
++e1->colliding;
|
|
||||||
}
|
|
||||||
} else if (collider_res.num_points == 0) {
|
|
||||||
--e0->colliding;
|
|
||||||
--e1->colliding;
|
|
||||||
}
|
|
||||||
dbg->e0 = e0->handle;
|
dbg->e0 = e0->handle;
|
||||||
dbg->e1 = e1->handle;
|
dbg->e1 = e1->handle;
|
||||||
dbg->res = collider_res;
|
dbg->res = collider_res;
|
||||||
|
|||||||
32
src/user.c
32
src/user.c
@ -877,7 +877,7 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
|
b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
|
||||||
b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA);
|
b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA);
|
||||||
//b32 skip_debug_draw_transform = true;
|
skip_debug_draw_transform = true;
|
||||||
|
|
||||||
struct xform sprite_xform = xf;
|
struct xform sprite_xform = xf;
|
||||||
|
|
||||||
@ -1007,7 +1007,7 @@ INTERNAL void user_update(void)
|
|||||||
/* Draw collider */
|
/* Draw collider */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) {
|
||||||
struct collider_shape collider = ent->local_collider;
|
struct collider_shape collider = ent->local_collider;
|
||||||
u32 color = RGBA_32_F(1, 0, 1, 0.25);
|
u32 color = RGBA_32_F(1, 1, 0, 0.25);
|
||||||
f32 thickness = 2;
|
f32 thickness = 2;
|
||||||
{
|
{
|
||||||
/* Draw collider using support points */
|
/* Draw collider using support points */
|
||||||
@ -1141,15 +1141,24 @@ INTERNAL void user_update(void)
|
|||||||
{
|
{
|
||||||
f32 thickness = 2;
|
f32 thickness = 2;
|
||||||
f32 radius = 4;
|
f32 radius = 4;
|
||||||
u32 color_line = RGBA_32_F(1, 0, 1, 0.5);
|
u32 color_line = RGBA_32_F(1, 0, 1, 0.25);
|
||||||
u32 color_a = RGBA_32_F(1, 0, 0, 0.5);
|
u32 color_a = RGBA_32_F(1, 0, 0, 0.25);
|
||||||
u32 color_b = RGBA_32_F(0, 1, 0, 0.5);
|
u32 color_b = RGBA_32_F(0, 1, 0, 0.25);
|
||||||
|
u32 color_line_clipped = RGBA_32_F(1, 0, 1, 1);
|
||||||
|
u32 color_a_clipped = RGBA_32_F(1, 0, 0, 1);
|
||||||
|
u32 color_b_clipped = RGBA_32_F(0, 1, 0, 1);
|
||||||
{
|
{
|
||||||
struct v2 a = xform_mul_v2(G.world_view, collider_res.a0);
|
struct v2 a = xform_mul_v2(G.world_view, collider_res.a0);
|
||||||
struct v2 b = xform_mul_v2(G.world_view, collider_res.b0);
|
struct v2 b = xform_mul_v2(G.world_view, collider_res.b0);
|
||||||
draw_solid_line(G.viewport_canvas, a, b, thickness, color_line);
|
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, a, radius, color_a, 10);
|
||||||
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
||||||
|
|
||||||
|
struct v2 a_clipped = xform_mul_v2(G.world_view, collider_res.a0_clipped);
|
||||||
|
struct v2 b_clipped = xform_mul_v2(G.world_view, collider_res.b0_clipped);
|
||||||
|
draw_solid_line(G.viewport_canvas, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||||
|
draw_solid_circle(G.viewport_canvas, a_clipped, radius, color_a_clipped, 10);
|
||||||
|
draw_solid_circle(G.viewport_canvas, b_clipped, radius, color_b_clipped, 10);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct v2 a = xform_mul_v2(G.world_view, collider_res.a1);
|
struct v2 a = xform_mul_v2(G.world_view, collider_res.a1);
|
||||||
@ -1157,10 +1166,16 @@ INTERNAL void user_update(void)
|
|||||||
draw_solid_line(G.viewport_canvas, a, b, thickness, color_line);
|
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, a, radius, color_a, 10);
|
||||||
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
||||||
|
|
||||||
|
struct v2 a_clipped = xform_mul_v2(G.world_view, collider_res.a1_clipped);
|
||||||
|
struct v2 b_clipped = xform_mul_v2(G.world_view, collider_res.b1_clipped);
|
||||||
|
draw_solid_line(G.viewport_canvas, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||||
|
draw_solid_circle(G.viewport_canvas, a_clipped, radius, color_a_clipped, 10);
|
||||||
|
draw_solid_circle(G.viewport_canvas, b_clipped, radius, color_b_clipped, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USER_DRAW_MENKOWSKI
|
#if COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI
|
||||||
struct xform e0_xf = data->xf0;
|
struct xform e0_xf = data->xf0;
|
||||||
struct xform e1_xf = data->xf1;
|
struct xform e1_xf = data->xf1;
|
||||||
|
|
||||||
@ -1263,7 +1278,7 @@ INTERNAL void user_update(void)
|
|||||||
u32 color_second = RGBA_32_F(0, 1, 0, 0.75);
|
u32 color_second = RGBA_32_F(0, 1, 0, 0.75);
|
||||||
u32 color_third = RGBA_32_F(0, 0, 1, 0.75);
|
u32 color_third = RGBA_32_F(0, 0, 1, 0.75);
|
||||||
|
|
||||||
struct collider_simplex simplex = collider_res.simplex;
|
struct collider_menkowski_simplex simplex = collider_res.simplex;
|
||||||
struct v2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p };
|
struct v2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p };
|
||||||
for (u64 i = 0; i < ARRAY_COUNT(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_view, simplex_points[i]);
|
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 };
|
struct v2_array simplex_array = { .count = simplex.len, .points = simplex_points };
|
||||||
@ -1407,7 +1422,8 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* Queue player fire cmd */
|
/* Queue player fire cmd */
|
||||||
i32 fire_presses = G.bind_states[USER_BIND_KIND_FIRE].num_presses - G.bind_states[USER_BIND_KIND_FIRE].num_releases;
|
i32 fire_presses = G.bind_states[USER_BIND_KIND_FIRE].num_presses - G.bind_states[USER_BIND_KIND_FIRE].num_releases;
|
||||||
if (!G.debug_camera && fire_presses) {
|
//if (!G.debug_camera && fire_presses) {
|
||||||
|
if (fire_presses) {
|
||||||
queue_game_cmd(scratch.arena, &cmd_list, (struct game_cmd) {
|
queue_game_cmd(scratch.arena, &cmd_list, (struct game_cmd) {
|
||||||
.kind = GAME_CMD_KIND_PLAYER_FIRE,
|
.kind = GAME_CMD_KIND_PLAYER_FIRE,
|
||||||
.state = fire_presses > 0 ? GAME_CMD_STATE_START : GAME_CMD_STATE_STOP
|
.state = fire_presses > 0 ? GAME_CMD_STATE_START : GAME_CMD_STATE_STOP
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user