fix epa collision not detecting when diagonals touch
This commit is contained in:
parent
1f0c8964d0
commit
dbdd653ae8
@ -116,7 +116,6 @@ struct entity {
|
||||
b32 solved;
|
||||
|
||||
b32 test_torque_applied;
|
||||
b32 test_collided;
|
||||
|
||||
|
||||
|
||||
|
||||
131
src/game.c
131
src/game.c
@ -129,10 +129,10 @@ INTERNAL void spawn_test_entities(void)
|
||||
//struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */
|
||||
//struct v2 size = V2(1, 1);
|
||||
struct v2 size = V2(0.5, 0.5);
|
||||
//f32 r = PI / 4;
|
||||
f32 r = PI / 4;
|
||||
//f32 r = PI / 3;
|
||||
//f32 r = PI / 2;
|
||||
f32 r = 0;
|
||||
//f32 r = 0;
|
||||
f32 skew = 0;
|
||||
|
||||
struct entity *e = entity_alloc(root);
|
||||
@ -155,8 +155,8 @@ INTERNAL void spawn_test_entities(void)
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
||||
e->mass_unscaled = 100;
|
||||
e->inertia_unscaled = 1;
|
||||
//e->inertia_unscaled = F32_INFINITY;
|
||||
//e->inertia_unscaled = 1;
|
||||
e->inertia_unscaled = F32_INFINITY;
|
||||
e->linear_ground_friction = 1000;
|
||||
e->angular_ground_friction = 100;
|
||||
|
||||
@ -250,6 +250,8 @@ INTERNAL void create_contact_manifolds(void)
|
||||
static u64 manifold_iteration = 0;
|
||||
++manifold_iteration;
|
||||
|
||||
/* FIXME: I think it's technically possible for manifold entities to swap between iterations */
|
||||
|
||||
struct entity_store *store = G.tick.entity_store;
|
||||
struct sprite_scope *sprite_frame_scope = G.sprite_frame_scope;
|
||||
struct entity *root = G.root;
|
||||
@ -301,10 +303,15 @@ INTERNAL void create_contact_manifolds(void)
|
||||
manifold_hash = hash_fnv64(manifold_hash, BUFFER_FROM_STRUCT(&h1));
|
||||
manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash));
|
||||
}
|
||||
struct entity *manifold = fixed_dict_get(&dict, manifold_key);
|
||||
|
||||
struct entity *manifold = entity_nil();
|
||||
struct entity_handle *entry = fixed_dict_get(&dict, manifold_key);
|
||||
if (entry) {
|
||||
manifold = entity_from_handle(store, *entry);
|
||||
}
|
||||
|
||||
/* Ensure manifold hasn't already been computed this iteration */
|
||||
if (manifold) {
|
||||
if (manifold->valid) {
|
||||
if (manifold->last_manifold_iteration == manifold_iteration) {
|
||||
/* Already iterated this manifold from The other entity's perspective, skip */
|
||||
continue;
|
||||
@ -336,8 +343,16 @@ INTERNAL void create_contact_manifolds(void)
|
||||
#endif
|
||||
|
||||
struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly);
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
if (manifold->valid) {
|
||||
manifold->prototype = res.prototype;
|
||||
manifold->simplex = res.simplex;
|
||||
manifold->solved = res.solved;
|
||||
}
|
||||
|
||||
if (res.num_pairs > 0) {
|
||||
if (!manifold) {
|
||||
if (!manifold->valid) {
|
||||
manifold = entity_alloc(root);
|
||||
manifold->manifold_e0 = e0->handle;
|
||||
manifold->manifold_e1 = e1->handle;
|
||||
@ -345,15 +360,22 @@ INTERNAL void create_contact_manifolds(void)
|
||||
manifold->manifold_normal = v2_norm(v2_sub(res.pairs[0].p1, res.pairs[0].p0));
|
||||
entity_enable_prop(manifold, ENTITY_PROP_MANIFOLD);
|
||||
activate_now(manifold);
|
||||
fixed_dict_set(&dict_arena, &dict, manifold_key, manifold);
|
||||
|
||||
if (entry) {
|
||||
*entry = manifold->handle;
|
||||
} else {
|
||||
entry = arena_push(&dict_arena, struct entity_handle);
|
||||
*entry = manifold->handle;
|
||||
fixed_dict_set(&dict_arena, &dict, manifold_key, entry);
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
{
|
||||
manifold->prototype = res.prototype;
|
||||
manifold->simplex = res.simplex;
|
||||
|
||||
|
||||
manifold->solved = res.solved;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update contact depths, and remove contacts that are no longer penetrating or have drifted too far from original position */
|
||||
struct v2 old_normal = manifold->manifold_normal;
|
||||
@ -420,12 +442,14 @@ INTERNAL void create_contact_manifolds(void)
|
||||
c = &overflow[overflow_count++];
|
||||
}
|
||||
|
||||
f32 depth = v2_len(v2_sub(p1_world, p0_world));
|
||||
|
||||
MEMZERO_STRUCT(c);
|
||||
c->p0_local = xform_invert_mul_v2(e0_xf, p0_world);
|
||||
c->p0_initial_world = p0_world;
|
||||
c->p1_local = xform_invert_mul_v2(e1_xf, p1_world);
|
||||
c->p1_initial_world = p1_world;
|
||||
c->depth = v2_len(v2_sub(p1_world, p0_world));
|
||||
c->depth = depth;
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,10 +532,19 @@ INTERNAL void create_contact_manifolds(void)
|
||||
|
||||
|
||||
|
||||
} else if (manifold) {
|
||||
/* No longer colliding, delete contact */
|
||||
} else if (manifold->valid) {
|
||||
/* No longer colliding, delete manifold */
|
||||
#if 0
|
||||
manifold->num_contacts = 0;
|
||||
fixed_dict_set(&dict_arena, &dict, manifold_key, NULL);
|
||||
//fixed_dict_set(&dict_arena, &dict, manifold_key, NULL);
|
||||
//entity_enable_prop(manifold, ENTITY_PROP_RELEASE);
|
||||
#else
|
||||
if (res.solved) {
|
||||
manifold->prototype.len = 0;
|
||||
manifold->simplex.len = 0;
|
||||
}
|
||||
manifold->num_contacts = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -534,13 +567,8 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
||||
|
||||
u32 num_contacts = manifold->num_contacts;
|
||||
f32 inv_num_contacts = 1.f / num_contacts;
|
||||
|
||||
if (num_contacts > 0 && e0->valid && e1->valid) {
|
||||
/* TODO: Remove this (testing) */
|
||||
if (!e0->test_collided) {
|
||||
e0->test_collided = true;
|
||||
}
|
||||
|
||||
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
|
||||
@ -555,7 +583,6 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
||||
f32 inv_i0 = 1.f / i0;
|
||||
f32 inv_i1 = 1.f / i1;
|
||||
|
||||
|
||||
struct queued_impulse {
|
||||
struct v2 p0, p1;
|
||||
f32 impulse;
|
||||
@ -602,14 +629,17 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
||||
/* (to be applied along n) */
|
||||
f32 j = (vn + bias) / k;
|
||||
j *= inv_num_contacts; /* TODO: Is this the correct place to do this? */
|
||||
(UNUSED)inv_num_contacts;
|
||||
|
||||
f32 old_impulse = contact->accumulated_impulse;
|
||||
contact->accumulated_impulse = max_f32(contact->accumulated_impulse + j, 0);
|
||||
f32 old_accumulated_impulse = contact->accumulated_impulse;
|
||||
f32 new_accumulated_impulse = max_f32(contact->accumulated_impulse + j, 0);
|
||||
f32 delta_impulse = new_accumulated_impulse - old_accumulated_impulse;
|
||||
contact->accumulated_impulse = new_accumulated_impulse;
|
||||
|
||||
queued_impulses[contact_index] = (struct queued_impulse) {
|
||||
.p0 = p0,
|
||||
.p1 = p1,
|
||||
.impulse = contact->accumulated_impulse - old_impulse
|
||||
.impulse = delta_impulse
|
||||
};
|
||||
}
|
||||
|
||||
@ -619,8 +649,6 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
|
||||
entity_apply_linear_impulse(e0, impulse, qi.p0);
|
||||
entity_apply_linear_impulse(e1, v2_neg(impulse), qi.p1);
|
||||
}
|
||||
} else {
|
||||
entity_enable_prop(manifold, ENTITY_PROP_RELEASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1306,48 +1334,31 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
ent->torque = 0;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Physics
|
||||
* ========================== */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
u32 substeps = 4;
|
||||
f32 substep_dt = dt / substeps;
|
||||
for (u32 i = 0; i < substeps; ++i) {
|
||||
|
||||
#if 0
|
||||
/* ========================== *
|
||||
* Create contact manifolds
|
||||
* ========================== */
|
||||
|
||||
create_contact_manifolds();
|
||||
|
||||
/* ========================== *
|
||||
* Collision resolution
|
||||
* ========================== */
|
||||
|
||||
solve_collisions(dt);
|
||||
|
||||
/* ========================== *
|
||||
* Integrate positions from velocity
|
||||
* ========================== */
|
||||
|
||||
integrate_positions(dt);
|
||||
solve_collisions(substep_dt, true);
|
||||
integrate_positions(substep_dt);
|
||||
solve_collisions(substep_dt, false);
|
||||
#else
|
||||
u32 iterations = 4;
|
||||
for (u32 i = 0; i < iterations; ++i) {
|
||||
f32 timestep = dt / iterations;
|
||||
(UNUSED)create_contact_manifolds;
|
||||
(UNUSED)solve_collisions;
|
||||
(UNUSED)integrate_positions;
|
||||
|
||||
#if 1
|
||||
create_contact_manifolds();
|
||||
solve_collisions(timestep, true);
|
||||
integrate_positions(timestep);
|
||||
solve_collisions(timestep, false);
|
||||
#else
|
||||
create_contact_manifolds();
|
||||
solve_collisions(timestep, false);
|
||||
integrate_positions(timestep);
|
||||
solve_collisions(substep_dt, true);
|
||||
integrate_positions(substep_dt);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Initialize bullet kinematics from sources
|
||||
|
||||
14
src/gjk.c
14
src/gjk.c
@ -196,14 +196,17 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
s.len = 1;
|
||||
|
||||
/* Second point is support point towards origin */
|
||||
DBGSTEP;
|
||||
dir = v2_neg(s.a.p);
|
||||
m = menkowski_point_extended(shape0, shape1, dir);
|
||||
if (v2_dot(dir, m.p) > 0) {
|
||||
DBGSTEP;
|
||||
s.b = s.a;
|
||||
s.a = m;
|
||||
s.len = 2;
|
||||
while (true) {
|
||||
/* Third point is support point in direction of line normal towards origin */
|
||||
DBGSTEP;
|
||||
dir = v2_perp_towards_dir(v2_sub(s.b.p, s.a.p), v2_neg(s.a.p));
|
||||
m = menkowski_point_extended(shape0, shape1, dir);
|
||||
if (v2_dot(dir, m.p) < 0) {
|
||||
@ -220,6 +223,7 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
struct v2 vac = v2_sub(s.c.p, s.a.p);
|
||||
struct v2 a_to_origin = v2_neg(s.a.p);
|
||||
|
||||
DBGSTEP;
|
||||
dir = v2_perp_towards_dir(vab, v2_neg(vac)); /* Normal of ab pointing away from c */
|
||||
if (v2_dot(dir, a_to_origin) > 0) {
|
||||
/* Point is in region ab, remove c from simplex */
|
||||
@ -283,7 +287,6 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
pen_ps_index = ps_index;
|
||||
pen_pe_index = pe_index;
|
||||
pen_len_sq = pd_len_sq;
|
||||
dir = pd;
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,11 +296,18 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
||||
s.len = 2;
|
||||
|
||||
/* Find new point in dir */
|
||||
DBGSTEP;
|
||||
{
|
||||
/* Next point is in direction of line normal pointing outwards from shape */
|
||||
struct v2 n = proto[(pen_pe_index < proto_count - 1) ? (pen_pe_index + 1) : 0].p; /* Next point along prototype after edge */
|
||||
struct v2 van = v2_sub(n, s.a.p);
|
||||
struct v2 vab = v2_sub(s.b.p, s.a.p);
|
||||
dir = v2_perp_towards_dir(vab, v2_neg(van));
|
||||
}
|
||||
m = menkowski_point_extended(shape0, shape1, dir);
|
||||
|
||||
/* Check unique */
|
||||
/* TODO: Better */
|
||||
DBGSTEP;
|
||||
{
|
||||
b32 unique = true;
|
||||
for (u32 i = 0; i < proto_count; ++i) {
|
||||
|
||||
@ -1938,6 +1938,7 @@ INTERNAL void win32_precise_sleep_timer(f64 seconds, HANDLE timer)
|
||||
/* TODO: Maybe increase tolerance for higher precision but more power usage */
|
||||
//const double tolerance = 0.001200 * scheduler_period_ms;
|
||||
const double tolerance = 0.000520 * scheduler_period_ms;
|
||||
//const double tolerance = 1 * scheduler_period_ms;
|
||||
|
||||
INT64 max_ticks = (INT64)scheduler_period_ms * 9500;
|
||||
while (true) {
|
||||
|
||||
103
src/user.c
103
src/user.c
@ -494,9 +494,8 @@ INTERNAL void user_update(void)
|
||||
entity_set_xform(e, xform_lerp(e0_xf, e1_xf, tick_blend));
|
||||
}
|
||||
|
||||
e->verlet_xform = xform_lerp(e0->verlet_xform, e1->verlet_xform, tick_blend);
|
||||
|
||||
e->control_move_force = math_lerp(e0->control_move_force, e1->control_move_force, tick_blend);
|
||||
e->control_force = math_lerp(e0->control_force, e1->control_force, tick_blend);
|
||||
e->control_torque = math_lerp(e0->control_torque, e1->control_torque, tick_blend);
|
||||
|
||||
e->linear_velocity = v2_lerp(e0->linear_velocity, e1->linear_velocity, tick_blend);
|
||||
e->angular_velocity = math_lerp(e0->angular_velocity, e1->angular_velocity, tick_blend);
|
||||
@ -988,62 +987,38 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw contact */
|
||||
#if 1
|
||||
/* Draw collision */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_MANIFOLD)) {
|
||||
f32 radius = 5;
|
||||
struct entity *e0 = entity_from_handle(store, ent->manifold_e0);
|
||||
struct entity *e1 = entity_from_handle(store, ent->manifold_e1);
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
(UNUSED)e0_xf;
|
||||
(UNUSED)e1_xf;
|
||||
for (u32 i = 0; i < ent->num_contacts; ++i) {
|
||||
struct contact contact = ent->contacts[i];
|
||||
{
|
||||
u32 color = entity_has_prop(e0, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.50) : RGBA_32_F(0, 1, 1, 0.50);
|
||||
struct v2 point = xform_mul_v2(e0_xf, contact.p0_local);
|
||||
//struct v2 point = contact.p0_initial_world;
|
||||
point = xform_mul_v2(G.world_view, point);
|
||||
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
||||
}
|
||||
{
|
||||
u32 color = entity_has_prop(e1, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.50) : RGBA_32_F(0, 1, 1, 0.50);
|
||||
struct v2 point = xform_mul_v2(e1_xf, contact.p1_local);
|
||||
//struct v2 point = contact.p1_initial_world;
|
||||
point = xform_mul_v2(G.world_view, point);
|
||||
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Draw collision */
|
||||
if (ent->is_top) {
|
||||
struct entity *e1 = entity_from_handle(store, ent->colliding_with);
|
||||
(UNUSED)e1;
|
||||
(UNUSED)colliding;
|
||||
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
|
||||
/* Create shapes */
|
||||
struct quad ent_quad;
|
||||
struct v2_array ent_poly;
|
||||
struct quad e0_quad;
|
||||
struct v2_array e0_poly;
|
||||
struct quad e1_quad;
|
||||
struct v2_array e1_poly;
|
||||
{
|
||||
{
|
||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), ent->animation_frame);
|
||||
ent_quad = xform_mul_quad(ent->sprite_local_xform, quad_from_rect(slice.rect));
|
||||
ent_quad = xform_mul_quad(xf, ent_quad);
|
||||
ent_poly = (struct v2_array) {
|
||||
.count = ARRAY_COUNT(ent_quad.e),
|
||||
.points = ent_quad.e
|
||||
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
|
||||
};
|
||||
}
|
||||
{
|
||||
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(entity_get_xform(e1), e1_quad);
|
||||
e1_quad = xform_mul_quad(e1_xf, e1_quad);
|
||||
e1_poly = (struct v2_array) {
|
||||
.count = ARRAY_COUNT(e1_quad.e),
|
||||
.points = e1_quad.e
|
||||
@ -1051,23 +1026,25 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Draw collision shapes */
|
||||
{
|
||||
f32 thickness = 2;
|
||||
u32 color = RGBA_32_F(1, 0, 0, 0.25);
|
||||
struct quad quad = xform_mul_quad(G.world_view, ent_quad);
|
||||
struct quad quad = xform_mul_quad(G.world_view, e0_quad);
|
||||
draw_solid_quad_line(G.viewport_canvas, quad, thickness, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw menkowski */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
{
|
||||
|
||||
u32 color = ent->solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1);
|
||||
f32 thickness = 2;
|
||||
(UNUSED)thickness;
|
||||
|
||||
struct v2_array m = menkowski(temp.arena, ent_poly, e1_poly);
|
||||
//struct v2_array m = menkowski(temp.arena, ent_poly, e1_poly, v2_sub(ent->xf1.og, ent->xf0.og));
|
||||
struct v2_array m = menkowski(temp.arena, e0_poly, e1_poly);
|
||||
//struct v2_array m = menkowski(temp.arena, e0_poly, e1_poly, v2_sub(ent->xf1.og, ent->xf0.og));
|
||||
|
||||
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);
|
||||
@ -1075,11 +1052,11 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
|
||||
/* Draw cloud */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
{
|
||||
u32 color = RGBA_32_F(1, 1, 1, 1);
|
||||
f32 radius = 2;
|
||||
|
||||
struct v2_array m = cloud(temp.arena, ent_poly, e1_poly);
|
||||
struct v2_array m = cloud(temp.arena, e0_poly, e1_poly);
|
||||
|
||||
for (u64 i = 0; i < m.count; ++i) {
|
||||
struct v2 p = xform_mul_v2(G.world_view, m.points[i]);;
|
||||
@ -1088,7 +1065,8 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
|
||||
/* Draw pendir */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
#if 0
|
||||
{
|
||||
f32 thickness = 2;
|
||||
u32 color = COLOR_YELLOW;
|
||||
|
||||
@ -1097,9 +1075,10 @@ INTERNAL void user_update(void)
|
||||
|
||||
draw_solid_arrow_ray(G.viewport_canvas, start, ray, thickness, thickness * 4, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw prototype */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
{
|
||||
f32 thickness = 2;
|
||||
u32 color = RGBA_32_F(1, 1, 1, 0.25);
|
||||
|
||||
@ -1112,7 +1091,7 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
|
||||
/* Draw simplex */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
{
|
||||
f32 thickness = 2;
|
||||
u32 line_color = colliding ? COLOR_WHITE: COLOR_YELLOW;
|
||||
u32 color_first = RGBA_32_F(1, 0, 0, 0.75);
|
||||
@ -1141,21 +1120,28 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw points */
|
||||
/* Draw contacts */
|
||||
{
|
||||
f32 radius = 5;
|
||||
u32 color = entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.75) : RGBA_32_F(0, 1, 1, 0.75);
|
||||
for (u32 i = 0; i < ent->num_contacts; ++i) {
|
||||
struct contact contact = ent->contacts[i];
|
||||
{
|
||||
struct v2 point = xform_mul_v2(G.world_view, ent->point0);
|
||||
u32 color = entity_has_prop(e0, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.50) : RGBA_32_F(0, 1, 1, 0.50);
|
||||
struct v2 point = xform_mul_v2(e0_xf, contact.p0_local);
|
||||
//struct v2 point = contact.p0_initial_world;
|
||||
point = xform_mul_v2(G.world_view, point);
|
||||
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
||||
}
|
||||
if (!v2_is_zero(ent->point1)) {
|
||||
//u32 color = entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 1, 0, 0.75) : RGBA_32_F(1, 0, 1, 0.75);
|
||||
struct v2 point = xform_mul_v2(G.world_view, ent->point1);
|
||||
{
|
||||
u32 color = entity_has_prop(e1, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.50) : RGBA_32_F(0, 1, 1, 0.50);
|
||||
struct v2 point = xform_mul_v2(e1_xf, contact.p1_local);
|
||||
//struct v2 point = contact.p1_initial_world;
|
||||
point = xform_mul_v2(G.world_view, point);
|
||||
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Draw hierarchy */
|
||||
@ -1302,6 +1288,9 @@ INTERNAL void user_update(void)
|
||||
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("world time: %F"), FMT_FLOAT((f64)G.world.time)));
|
||||
pos.y += spacing;
|
||||
|
||||
//draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("time - world time: %F"), FMT_FLOAT((f64)G.time - (f64)G.world.time)));
|
||||
//pos.y += spacing;
|
||||
|
||||
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("entities: %F/%F"), FMT_UINT(G.world.entity_store->allocated), FMT_UINT(G.world.entity_store->reserved)));
|
||||
pos.y += spacing;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user