accumulated impulse testing

This commit is contained in:
jacob 2024-09-17 14:58:40 -05:00
parent b717a38b13
commit be2f15d1a8
3 changed files with 44 additions and 15 deletions

View File

@ -61,12 +61,14 @@ struct entity_store {
struct entity_contact_point { struct entity_contact_point {
struct v2 local; struct v2 local;
}; };
struct entity_contact_pair { struct entity_contact_pair {
struct entity_contact_point p0, p1; struct entity_contact_point p0, p1;
struct v2 pen;
}; };

View File

@ -911,6 +911,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct string contact_key; struct string contact_key;
{ {
/* FIXME: Contact should be same regardless of entity order */
u64 contact_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&e0->handle)); u64 contact_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&e0->handle));
contact_hash = hash_fnv64(contact_hash, BUFFER_FROM_STRUCT(&e1->handle)); contact_hash = hash_fnv64(contact_hash, BUFFER_FROM_STRUCT(&e1->handle));
contact_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&contact_hash)); contact_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&contact_hash));
@ -943,6 +944,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct v2 new_p0_local = xform_invert_mul_v2(e0_xf, new_p0_world); struct v2 new_p0_local = xform_invert_mul_v2(e0_xf, new_p0_world);
struct v2 new_p1_local = xform_invert_mul_v2(e1_xf, new_p1_world); struct v2 new_p1_local = xform_invert_mul_v2(e1_xf, new_p1_world);
struct v2 pen = v2_sub(new_p1_world, new_p0_world);
i32 replace_index = -1; i32 replace_index = -1;
for (u32 j = 0; j < contact->num_contact_pairs; ++j) { for (u32 j = 0; j < contact->num_contact_pairs; ++j) {
struct entity_contact_pair old_pair = contact->contact_pairs[j]; struct entity_contact_pair old_pair = contact->contact_pairs[j];
@ -955,12 +958,13 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
if (p0_dist_sq < min_new_contact_point_dist_sq || p1_dist_sq < min_new_contact_point_dist_sq) { if (p0_dist_sq < min_new_contact_point_dist_sq || p1_dist_sq < min_new_contact_point_dist_sq) {
replace_index = j; replace_index = j;
//should_insert = false;
break; break;
} }
} }
if (should_insert) { if (should_insert) {
u32 index; u32 index;
if (replace_index > 0) { if (replace_index >= 0) {
index = replace_index; index = replace_index;
contact->next_pair_index = index + 1; contact->next_pair_index = index + 1;
if (contact->next_pair_index >= ARRAY_COUNT(contact->contact_pairs)) { if (contact->next_pair_index >= ARRAY_COUNT(contact->contact_pairs)) {
@ -980,12 +984,9 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
} }
} }
contact->contact_pairs[index] = (struct entity_contact_pair) { contact->contact_pairs[index] = (struct entity_contact_pair) {
.p0 = { .p0 = { .local = new_p0_local },
.local = new_p0_local .p1 = { .local = new_p1_local },
}, .pen = pen
.p1 = {
.local = new_p1_local
}
}; };
} }
} }
@ -1012,7 +1013,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct entity *e0 = entity_from_handle(store, contact->contact_e0); struct entity *e0 = entity_from_handle(store, contact->contact_e0);
struct entity *e1 = entity_from_handle(store, contact->contact_e1); struct entity *e1 = entity_from_handle(store, contact->contact_e1);
if (e0->valid && e1->valid && contact->num_contact_pairs > 0) { if (contact->num_contact_pairs > 0 && e0->valid && e1->valid) {
struct xform e0_xf = entity_get_xform(e0); struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1); struct xform e1_xf = entity_get_xform(e1);
@ -1027,17 +1028,26 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
f32 inv_i0 = 1.f / i0; f32 inv_i0 = 1.f / i0;
f32 inv_i1 = 1.f / i1; f32 inv_i1 = 1.f / i1;
struct v2 e0_accumulated_linear_impulse = { 0 };
f32 e0_accumulated_angular_impulse = 0;
struct v2 e1_accumulated_linear_impulse = { 0 };
f32 e1_accumulated_angular_impulse = 0;
//f32 e1_accumulated_impulse = 0;
for (u32 pair_index = 0; pair_index < contact->num_contact_pairs; ++pair_index) { for (u32 pair_index = 0; pair_index < contact->num_contact_pairs; ++pair_index) {
struct entity_contact_pair pair = contact->contact_pairs[pair_index]; struct entity_contact_pair pair = contact->contact_pairs[pair_index];
struct v2 p0 = xform_mul_v2(e0_xf, pair.p0.local); struct v2 p0 = xform_mul_v2(e0_xf, pair.p0.local);
struct v2 p1 = xform_mul_v2(e1_xf, pair.p1.local); struct v2 p1 = xform_mul_v2(e1_xf, pair.p1.local);
struct v2 pen = v2_sub(p1, p0); struct v2 pen = pair.pen;
struct v2 pen_norm = v2_norm(pen); struct v2 pen_norm = v2_norm(pen);
#if 1 #if 0
f32 bias_factor = 0.2; f32 bias_factor = 0.2;
//f32 bias_slop = 0.1;
f32 bias_slop = 0.001; f32 bias_slop = 0.001;
//f32 bias_slop = 0.00;
f32 bias = (bias_factor / dt) * max((v2_len(pen) - bias_slop), 0); f32 bias = (bias_factor / dt) * max((v2_len(pen) - bias_slop), 0);
#else #else
@ -1072,9 +1082,28 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
e0->test_collided = true; e0->test_collided = true;
} }
entity_apply_linear_impulse(e0, imp, p0); e0_accumulated_linear_impulse = v2_add(e0_accumulated_linear_impulse, imp);
entity_apply_linear_impulse(e1, v2_neg(imp), p1); e1_accumulated_linear_impulse = v2_add(e1_accumulated_linear_impulse, v2_neg(imp));
e0_accumulated_angular_impulse += v2_wedge(vcp0, imp);
e1_accumulated_angular_impulse += v2_wedge(vcp1, v2_neg(imp));
//entity_apply_linear_impulse(e0, imp, p0);
//entity_apply_linear_impulse(e1, v2_neg(imp), p1);
} }
//entity_apply_linear_impulse(e0, imp, p0);
//entity_apply_linear_impulse(e1, v2_neg(imp), p1);
/* FIXME: Clamp */
entity_apply_linear_impulse_to_center(e0, e0_accumulated_linear_impulse);
entity_apply_angular_impulse(e0, e0_accumulated_angular_impulse);
entity_apply_linear_impulse_to_center(e1, e1_accumulated_linear_impulse);
entity_apply_angular_impulse(e1, e1_accumulated_angular_impulse);
} else { } else {
entity_enable_prop(contact, ENTITY_PROP_RELEASE); entity_enable_prop(contact, ENTITY_PROP_RELEASE);
} }

View File

@ -1003,9 +1003,7 @@ INLINE struct v2 xform_basis_invert_mul_v2(struct xform xf, struct v2 v)
INLINE struct v2 xform_invert_mul_v2(struct xform xf, struct v2 v) INLINE struct v2 xform_invert_mul_v2(struct xform xf, struct v2 v)
{ {
struct xform inv = xform_invert(xf); struct xform inv = xform_invert(xf);
struct v2 res = xform_basis_mul_v2(inv, v); return xform_mul_v2(inv, v);
res = v2_add(res, inv.og);
return res;
} }
INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad) INLINE struct quad xform_mul_quad(struct xform xf, struct quad quad)