diff --git a/src/collision.c b/src/collision.c index e630302..4ebb7c9 100644 --- a/src/collision.c +++ b/src/collision.c @@ -1,6 +1,7 @@ #include "collision.h" #include "debug.h" #include "player.h" +#include "vmath.h" // ===================================================== // Shape overlap test using the separating axis theorem @@ -78,6 +79,7 @@ int _internal_collision_get_overlap(PhysicsEntity self, PhysicsEntity other, Col } if(sqr_mag == 0) { + out->separation_force = InfinityVector; return 0; } } @@ -121,13 +123,13 @@ int collision_check(PhysicsEntity a, PhysicsEntity b, Collision* out_a, Collisio int collision_a_overlaps = _internal_collision_get_overlap(a, b, &collision_a); int collision_b_overlaps = _internal_collision_get_overlap(b, a, &collision_b); - if(!collision_a_overlaps && !collision_b_overlaps) + if(!collision_a_overlaps || !collision_b_overlaps) return 0; - else if(!collision_a_overlaps && collision_b_overlaps) - collision_a = _internal_collision_invert(collision_b, b); - else if(!collision_b_overlaps && collision_a_overlaps) - collision_b = _internal_collision_invert(collision_a, a); + if(vsqrmagnitudef(collision_a.separation_force) < vsqrmagnitudef(collision_b.separation_force)) + collision_b = _internal_collision_invert(collision_a, a); + else + collision_a = _internal_collision_invert(collision_b, b); *out_a = collision_a; *out_b = collision_b; diff --git a/src/player.c b/src/player.c index 7938a99..1a61e8d 100644 --- a/src/player.c +++ b/src/player.c @@ -41,7 +41,7 @@ void player_start(Player* self) { float ex_w = 0.1f; float h = .75f; float r = 0.05f; - float rr = (r/3)*2; + float rr = r; self->shape = shape_new((Vector[]){ {r-ex_w, 0.f}, {-ex_w, -rr}, diff --git a/src/rigidbody.c b/src/rigidbody.c index 63a2315..35e77ae 100644 --- a/src/rigidbody.c +++ b/src/rigidbody.c @@ -69,9 +69,12 @@ static inline void _internal_rigidbody_collect_contacts(RigidBody* self) { for(size_t i = 0; i < self->contacts.len; ++i) { Contact* contact = list_at(&self->contacts, i); + if(contact->expiry <= 0) { - list_erase(&self->contacts, i); - i--; + if(vdotf(vnormalizedf(self->linear_velocity), contact->hit.normal) >= -0.01f || contact->expiry <= -1) { + list_erase(&self->contacts, i); + i--; + } } --(contact->expiry); } @@ -95,9 +98,13 @@ void _internal_debug_draw_collision_edge(Vector left, Vector right, Vector norma static inline Vector _internal_calculate_contact_force(Contact* contact) { Collision hit = contact->hit; - const float warming = fminf(1.f, contact->warming); + + if(vsqrmagnitudef(hit.separation_force) < powf(0.01f, 2)) + return ZeroVector; + + const float warming = 100.f * fminf(1.f, contact->warming); const float d = 1.0f; - const float k = 1.0f * warming; + const float k = 0.0f * warming; const float b = 1.0f; const Vector damping = vmulff(hit.normal, k * d); @@ -149,11 +156,7 @@ void rigidbody_solve_contacts(RigidBody* self) { void rigidbody_apply_physics(RigidBody* self) { Vector position = transformable_get_position(self->transformable); Vector velocity = vmulff(self->linear_velocity, delta_time()); - - if(vsqrmagnitudef(velocity) > powf(0.00000f, 2)) { - transformable_set_position(self->transformable, vaddf(position, velocity)); - } - + transformable_set_position(self->transformable, vaddf(position, velocity)); self->linear_force = ZeroVector; }