formatting

This commit is contained in:
jacob 2024-09-09 10:56:54 -05:00
parent 14163d2a09
commit 5c03288c53
3 changed files with 18 additions and 411 deletions

View File

@ -123,12 +123,12 @@ INTERNAL void spawn_test_entities(void)
struct entity *player_ent; struct entity *player_ent;
{ {
//struct v2 pos = V2(-1, -1); //struct v2 pos = V2(-1, -1);
//struct v2 pos = V2(1.1230469346046448864129274625156, -1); /* Touching right side of box */ struct v2 pos = V2(1.1230469346046448864129274625156, -1); /* Touching right side of box */
//struct v2 pos = V2(1.1230469346046448864129274625156 - 0.0001, -1); /* Touching right side of box */ //struct v2 pos = V2(1.1230469346046448864129274625156 - 0.0001, -1); /* Touching right side of box */
struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */ //struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */
struct v2 size = V2(1, 1); struct v2 size = V2(1, 1);
f32 r = PI / 4; //f32 r = PI / 4;
//f32 r = 0; f32 r = 0;
f32 skew = 0; f32 skew = 0;
struct entity *e = entity_alloc(root); struct entity *e = entity_alloc(root);
@ -144,6 +144,7 @@ INTERNAL void spawn_test_entities(void)
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
e->control_move_force = 4500; e->control_move_force = 4500;
//e->control_move_force = 500000;
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);
@ -673,111 +674,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
* Collision * Collision
* ========================== */ * ========================== */
#if 0
for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) {
struct entity *e0 = &store->entities[e0_index];
if (!(e0->valid && entity_has_prop(e0, ENTITY_PROP_ACTIVE))) continue;
if (!entity_has_prop(e0, ENTITY_PROP_PHYSICAL)) continue;
if (!entity_has_prop(e0, ENTITY_PROP_PLAYER_CONTROLLED)) continue;
struct xform e0_xf = entity_get_xform(e0);
struct quad e0_quad;
struct v2_array e0_poly;
{
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, e0->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), e0->animation_frame);
e0_quad = xform_mul_quad(e0->sprite_local_xform, quad_from_rect(slice.rect));
e0_quad = xform_mul_quad(e0_xf, e0_quad);
e0_poly = (struct v2_array) {
.count = ARRAY_COUNT(e0_quad.e),
.points = e0_quad.e
};
}
b32 colliding = false;
struct v2 point0 = V2(0, 0);
struct v2 point1 = V2(0, 0);
struct entity *colliding_with = entity_nil();
struct gjk_simplex simplex = { 0 };
struct v2 pendir = { 0 };
b32 velocity_intersects = false;
for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) {
struct entity *e1 = &store->entities[e1_index];
if (e1 == e0) continue;
if (!(e1->valid && entity_has_prop(e1, ENTITY_PROP_ACTIVE))) continue;
if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue;
struct xform e1_xf = entity_get_xform(e1);
struct quad e1_quad;
struct v2_array e1_poly;
{
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, e1->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), e1->animation_frame);
e1_quad = xform_mul_quad(e1->sprite_local_xform, quad_from_rect(slice.rect));
e1_quad = xform_mul_quad(e1_xf, e1_quad);
e1_poly = (struct v2_array) {
.count = ARRAY_COUNT(e1_quad.e),
.points = e1_quad.e
};
}
#if 1
struct v2 e0_velocity = v2_sub(e0_xf.og, e0->verlet_xform.og);
struct v2 e1_velocity = v2_sub(e1_xf.og, e1->verlet_xform.og);
pendir = v2_sub(e0_velocity, e1_velocity);
//pendir = v2_norm(pendir);
#else
pendir = V2(0, 0);
//pendir = V2(-0.25, -1);
//pendir = v2_mul(v2_norm(V2(-0.25, -1)), 0.2);
//pendir = V2(0, 99999);
//pendir = V2(-99999999999, -99999999999);
//pendir = V2(-0.0000794729349, -1.00000);
//pendir = V2(-0.0001794729349, -1.00000);
//pendir = V2(-0.1794729349, -1.00000);
#endif
struct gjk_extended_result res = gjk_extended(e0_poly, e1_poly, pendir);
colliding = res.colliding;
point0 = res.p0;
point1 = res.p1;
colliding_with = e1;
simplex = res.simplex;
velocity_intersects = res.velocity_intersects;
if (colliding) {
#if 0
struct v2 pen = v2_sub(point1, point0);
/* Pen movement test */ #if 0
f32 epsilon = 0.000100; pen = v2_add(pen, v2_mul(v2_norm(pen), epsilon));
#endif
struct xform xf = e0_xf;
xf.og = v2_add(xf.og, pen);
entity_set_xform(e0, xf);
e0->verlet_xform.og = v2_add(e0->verlet_xform.og, pen);
//e0->verlet_xform.og = xf.og;
#endif
}
}
e0->colliding = colliding;
e0->colliding_with = colliding_with->handle;
e0->point = point0;
e0->simplex = simplex;
e0->pendir = pendir;
e0->velocity_intersects = velocity_intersects;
if (colliding_with->valid) {
colliding_with->colliding = colliding;
colliding_with->colliding_with = e0->handle;
colliding_with->point = point1;
}
}
#else
for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) { for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) {
struct entity *e0 = &store->entities[e0_index]; struct entity *e0 = &store->entities[e0_index];
if (!(e0->valid && entity_has_prop(e0, ENTITY_PROP_ACTIVE))) continue; if (!(e0->valid && entity_has_prop(e0, ENTITY_PROP_ACTIVE))) continue;
@ -839,11 +735,13 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
velocity = v2_sub(xf1.og, xf0.og); velocity = v2_sub(xf1.og, xf0.og);
//velocity = V2(0.014992147684, -0.000010356307); //velocity = V2(0.014992147684, -0.000010356307);
//velocity = V2(0.005, 0); //velocity = V2(0.005, 0);
//velocity = V2(0.005, 0.005); //velocity = V2(-500, -500);
//velocity = V2(-1, -1); //velocity = V2(-1, -1);
//velocity = v2_neg(velocity); //velocity = v2_neg(velocity);
//velocity = v2_neg(velocity);
//xf0.og = v2_sub(xf1.og, velocity); //xf0.og = v2_sub(xf1.og, velocity);
xf1.og = v2_add(xf0.og, velocity); xf1.og = v2_add(xf0.og, velocity);
} }
@ -907,7 +805,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
} }
#endif #endif
} }
#endif
/* ========================== * /* ========================== *
* Player aim * Player aim

301
src/gjk.c
View File

@ -397,7 +397,7 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
struct gjk_extended_result res = { 0 }; struct gjk_extended_result res = { 0 };
/* TODO: Verify epsilon */ /* TODO: Verify epsilon */
f32 epsilon = 0.00001; f32 epsilon = 0.00000001;
struct gjk_simplex s = { struct gjk_simplex s = {
.len = 3, .len = 3,
.a = V2(F32_NAN, F32_NAN), .a = V2(F32_NAN, F32_NAN),
@ -537,289 +537,6 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
} }
} }
#if 0
if (colliding) {
use_penetration_dir = !v2_eq(velocity, V2(0, 0));
if (!use_penetration_dir) {
/* ========================== *
* Expand simplex towards closest edge to origin inside menkowski (EPA)
* ========================== */
struct gjk_menkowski_point *proto = arena_dry_push(scratch.arena, struct gjk_menkowski_point);
u32 proto_count = 0;
{
ASSERT(s.len == 3);
struct gjk_menkowski_point *tmp = arena_push_array(scratch.arena, struct gjk_menkowski_point, 3);
tmp[0] = s.a;
tmp[1] = s.b;
tmp[2] = s.c;
proto_count = 3;
}
while (true) {
DBGSTEP;
f32 pen_len_sq = F32_INFINITY;
/* Find dir from origin to closest edge */
/* FIXME: Winding order of ps & pe index */
u32 pen_ps_index = 0;
u32 pen_pe_index = 0;
for (u32 i = 0; i < proto_count; ++i) {
u32 ps_index = i;
u32 pe_index = (i < proto_count - 1) ? (i + 1) : 0;
struct v2 ps = proto[ps_index].p;
struct v2 pe = proto[pe_index].p;
struct v2 vse = v2_sub(pe, ps);
struct v2 vso = v2_neg(ps);
f32 d1 = v2_dot(vso, vse);
f32 d2 = v2_dot(vse, vse);
struct v2 vsd = v2_mul(vse, (d1 / d2));
struct v2 pd = v2_add(ps, vsd);
f32 pd_len_sq = v2_len_sq(pd);
if (pd_len_sq < pen_len_sq) {
pen_ps_index = ps_index;
pen_pe_index = pe_index;
pen_len_sq = pd_len_sq;
dir = pd;
}
}
/* TODO: Move to break (debugging) */
s.a = proto[pen_ps_index];
s.b = proto[pen_pe_index];
s.len = 2;
/* Find new point in dir */
m = menkowski_point_extended_test(shape0, shape1, dir, xf0, xf1);
/* Check unique */
/* TODO: Better */
{
b32 unique = true;
for (u32 i = 0; i < proto_count; ++i) {
struct v2 edge_start = proto[i].p;
struct v2 edge_end = i < proto_count - 1 ? proto[i + 1].p : proto[0].p;
if (math_fabs(v2_wedge(v2_sub(edge_end, edge_start), v2_sub(m.p, edge_start))) < epsilon) {
unique = false;
break;
}
}
if (!unique) {
break;
}
}
/* Insert point into prototype */
/* FIXME: Preserve winding order */
arena_push(scratch.arena, struct v2);
++proto_count;
for (u32 i = proto_count - 1; i > pen_pe_index; --i) {
u32 shift_from = (i > 0) ? i - 1 : proto_count - 1;
u32 shift_to = i;
proto[shift_to] = proto[shift_from];
}
proto[pen_pe_index] = m;
}
} else {
/* ========================== *
* Move simplex towards penetration dir
* ========================== */
while (true) {
/* Second point is support point towards velocity */
if (s.len == 1) {
DBGSTEP;
dir = v2_sub(v2_mul(velocity, v2_dot(velocity, s.a.p) / v2_dot(velocity, velocity)), s.a.p);
m = menkowski_point_extended_test(shape0, shape1, dir, xf0, xf1);
if (v2_eq(m.p, s.a.p)) {
break;
}
if (math_fabs(v2_wedge(v2_sub(s.b.p, s.a.p), v2_neg(s.a.p))) < epsilon) {
/* ab lies on origin */
break;
}
s.b = s.a;
s.a = m;
s.len = 2;
/* Third point is support point in direction of line normal towards `a` projected onto velocity */
dir = v2_perp_towards_dir(v2_sub(s.b.p, s.a.p), velocity);
}
if (s.len == 2) {
DBGSTEP;
m = menkowski_point_extended_test(shape0, shape1, dir, xf0, xf1);
if (math_fabs(v2_wedge(v2_sub(s.b.p, s.a.p), v2_sub(m.p, s.a.p))) < epsilon) {
/* New point is already on the current line */
break;
}
s.c = s.b;
s.b = s.a;
s.a = m;
s.len = 3;
DBGSTEP;
if (math_fabs(v2_wedge(v2_sub(s.b.p, s.a.p), v2_neg(s.a.p))) < epsilon) {
/* ab lies on origin */
s.len = 2;
break;
} else if (math_fabs(v2_wedge(v2_sub(s.c.p, s.a.p), v2_neg(s.a.p))) < epsilon) {
/* ac lies on origin */
s.b = s.c;
s.len = 2;
break;
}
}
#if 0
DBGSTEP;
//struct v2 vab = v2_sub(s.b.p, s.a.p);
f32 a_dot = v2_dot(velocity, s.a.p);
f32 a_wedge = v2_wedge(velocity, s.a.p);
f32 b_dot = v2_dot(velocity, s.b.p);
f32 b_wedge = v2_wedge(velocity, s.b.p);
f32 c_dot = v2_dot(velocity, s.c.p);
f32 c_wedge = v2_wedge(velocity, s.c.p);
i32 code = 0; /* 0 = ab, 1 = ac, 2 = bc */
f32 highest_intercept = -F32_INFINITY;
if (math_fsign(a_wedge) != math_fsign(b_wedge)) {
highest_intercept = ((b_dot - a_dot) / (b_wedge - a_wedge)) * (-a_wedge) + a_dot;
}
if (math_fsign(a_wedge) != math_fsign(c_wedge)) {
f32 intercept = ((c_dot - a_dot) / (c_wedge - a_wedge)) * (-a_wedge) + a_dot;
if (intercept > highest_intercept) {
code = 1;
highest_intercept = intercept;
}
}
if (math_fsign(b_wedge) != math_fsign(c_wedge)) {
f32 intercept = ((c_dot - b_dot) / (c_wedge - b_wedge)) * (-b_wedge) + b_dot;
if (intercept > highest_intercept) {
code = 2;
highest_intercept = intercept;
}
}
switch (code) {
case 0:
{ /* ab is furthest, remove c */
dir = v2_perp_towards_dir(v2_sub(s.b.p, s.a.p), velocity);
s.len = 2;
} break;
case 1:
{ /* ac is furthest, remove b */
dir = v2_perp_towards_dir(v2_sub(s.c.p, s.a.p), velocity);
s.b = s.c;
s.len = 2;
} break;
case 2:
{ /* bc is furthest, remove a */
dir = v2_perp_towards_dir(v2_sub(s.c.p, s.b.p), velocity);
s.a = s.b;
s.b = s.c;
s.len = 2;
} break;
}
#else
DBGSTEP;
struct v2 vab = v2_sub(s.b.p, s.a.p);
struct v2 vac = v2_sub(s.c.p, s.a.p);
struct v2 vbc = v2_sub(s.c.p, s.b.p);
/* TODO: De-duplicate operations */
i32 code = 0; /* 0 = ab, 1 = ac, 2 = bc */
f32 furthest = -F32_INFINITY;
{
struct v2 vao = v2_neg(s.a.p);
f32 w = 1 / v2_wedge(vab, velocity);
f32 t1 = v2_wedge(vao, velocity) * w;
f32 t2 = v2_wedge(vao, vab) * w;
(UNUSED)t1;
(UNUSED)t2;
//b32 intersects = 0 <= t1 && 0 <= t2 && t2 <= 1;
b32 intersects = true;
if (intersects && t1 > furthest) {
code = 0;
furthest = t2;
}
}
{
struct v2 vao = v2_neg(s.a.p);
f32 w = 1 / v2_wedge(vac, velocity);
f32 t1 = v2_wedge(vao, velocity) * w;
f32 t2 = v2_wedge(vao, vac) * w;
(UNUSED)t1;
(UNUSED)t2;
//b32 intersects = 0 <= t1 && 0 <= t2 && t2 <= 1;
b32 intersects = true;
if (intersects && t1 > furthest) {
code = 1;
furthest = t2;
}
}
{
struct v2 vbo = v2_neg(s.b.p);
f32 w = 1 / v2_wedge(vbc, velocity);
f32 t1 = v2_wedge(vbo, velocity) * w;
f32 t2 = v2_wedge(vbo, vbc) * w;
(UNUSED)t1;
(UNUSED)t2;
//b32 intersects = 0 <= t1 && 0 <= t2 && t2 <= 1;
b32 intersects = true;
if (intersects && t1 > furthest) {
code = 2;
furthest = t2;
}
}
switch (code) {
case 0:
{ /* ab is furthest, remove c */
dir = v2_perp_towards_dir(vab, velocity);
s.len = 2;
} break;
case 1:
{ /* ac is furthest, remove b */
dir = v2_perp_towards_dir(vac, velocity);
s.b = s.c;
s.len = 2;
} break;
case 2:
{ /* bc is furthest, remove a */
dir = v2_perp_towards_dir(vbc, velocity);
s.a = s.b;
s.b = s.c;
s.len = 2;
} break;
}
#endif
}
}
}
#else
if (colliding) { if (colliding) {
/* ========================== * /* ========================== *
* Epa * Epa
@ -970,7 +687,7 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
w = 1 / w; w = 1 / w;
t1 = v2_wedge(vso, velocity) * w; t1 = v2_wedge(vso, velocity) * w;
t2 = v2_wedge(vso, vse) * w; t2 = v2_wedge(vso, vse) * w;
intersects = 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1; intersects = -epsilon < t1 && t1 < 1 + epsilon && -epsilon < t2 && t2 < 1 + epsilon;
} }
struct v2 next_dir = dir; struct v2 next_dir = dir;
@ -981,17 +698,10 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
next_dir = v2_perp_towards_dir(vse, velocity); next_dir = v2_perp_towards_dir(vse, velocity);
} else { } else {
/* Score is inverse projection len */ /* Score is inverse projection len */
//f32 len = v2_len(v2_sub(velocity, ps));
struct v2 vsv = v2_sub(velocity, ps); struct v2 vsv = v2_sub(velocity, ps);
struct v2 vsd = v2_mul(vse, v2_dot(vse, vsv) / v2_dot(vse, vse));
f32 r = v2_dot(vse, vsv) / v2_dot(vse, vse);
struct v2 vsd = v2_mul(vse, r);
f32 len = v2_len(v2_sub(vsd, vsv)); f32 len = v2_len(v2_sub(vsd, vsv));
score = 1.0 - len; score = 1.0 - len;
next_dir = v2_perp_towards_dir(vse, ps); next_dir = v2_perp_towards_dir(vse, ps);
} }
@ -999,10 +709,7 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
pen_ps_index = ps_index; pen_ps_index = ps_index;
pen_pe_index = pe_index; pen_pe_index = pe_index;
highest_score = score; highest_score = score;
(UNUSED)next_dir;
dir = next_dir; dir = next_dir;
//dir = velocity;
} }
} }
#endif #endif
@ -1070,8 +777,6 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
} }
} }
} }
#endif

View File

@ -1201,8 +1201,13 @@ INTERNAL void user_update(void)
{ {
/* Queue player move cmd */ /* Queue player move cmd */
const f32 walk_ratio = 0.25f; f32 move_speed = 1.0f;
f32 move_speed = G.bind_states[USER_BIND_KIND_WALK].is_held ? walk_ratio : 1.0f; if (G.bind_states[USER_BIND_KIND_WALK].is_held) {
//const f32 walk_ratio = 0.25f;
const f32 walk_ratio = 0.01f;
move_speed *= walk_ratio;
}
struct v2 input_move_dir = { 0 }; struct v2 input_move_dir = { 0 };
{ {
for (enum user_bind_kind bind = 0; bind < (i32)ARRAY_COUNT(G.bind_states); ++bind) { for (enum user_bind_kind bind = 0; bind < (i32)ARRAY_COUNT(G.bind_states); ++bind) {