From 9ce882cbb6bb7628d7c9883c43491a75c10625d7 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 21 Nov 2022 13:02:03 +0200 Subject: [PATCH] Simulate friction in collisions --- .../bassteroids/source/gamecontroller.cpp | 2 +- examples/bassteroids/source/physics.cpp | 27 ++++++++++++++----- examples/bassteroids/source/physics.h | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/examples/bassteroids/source/gamecontroller.cpp b/examples/bassteroids/source/gamecontroller.cpp index d39b343..b564033 100644 --- a/examples/bassteroids/source/gamecontroller.cpp +++ b/examples/bassteroids/source/gamecontroller.cpp @@ -8,7 +8,7 @@ using namespace Msp; GameController::GameController(Game::Stage &s): System(s), - asteroid_setup{ .physical={ .body={ .mass=200 }, .collider={ .type=ColliderType::CIRCLE, .radius=3.0f } }, + asteroid_setup{ .physical={ .body={ .mass=200, .moment_of_inertia=2160 }, .collider={ .type=ColliderType::CIRCLE, .radius=3.0f } }, .mesh={ .object_name="Asteroid 1.object" }} { } diff --git a/examples/bassteroids/source/physics.cpp b/examples/bassteroids/source/physics.cpp index 0fb4326..2453fd9 100644 --- a/examples/bassteroids/source/physics.cpp +++ b/examples/bassteroids/source/physics.cpp @@ -70,12 +70,15 @@ void Physics::copy_in(SimulatedEntity &entity) entity.rotation = Geometry::atan2(2*(r.a*r.d+r.b*r.c), 1-2*(r.c*r.c+r.d*r.d)); if constexpr(is_fixture) + { entity.inverse_mass = 0.0f; + entity.inverse_momi = 0.0f; + } else { Game::Handle body = entity.entity->get_body(); entity.inverse_mass = 1.0f/body->get_mass(); - entity.moment_of_inertia = body->get_moment_of_inertia(); + entity.inverse_momi = 1.0f/body->get_moment_of_inertia(); entity.external_force = body->get_force(); entity.external_torque = body->get_torque(); entity.velocity = body->get_velocity(); @@ -105,11 +108,11 @@ void Physics::step(float dt_secs) { SimulatedEntity &entity = entities[i]; - LinAl::Vector new_velocity = entity.velocity+entity.external_force*dt_secs*entity.inverse_mass; + LinAl::Vector new_velocity = entity.velocity+entity.external_force*(dt_secs*entity.inverse_mass); entity.position += (entity.velocity+new_velocity)*(dt_secs/2); entity.velocity = new_velocity; - Geometry::Angle new_angular_velocity = entity.angular_velocity+Geometry::Angle::from_radians(entity.external_torque*(dt_secs/entity.moment_of_inertia)); + Geometry::Angle new_angular_velocity = entity.angular_velocity+Geometry::Angle::from_radians(entity.external_torque*dt_secs*entity.inverse_momi); entity.rotation = wrap_positive(entity.rotation+(entity.angular_velocity+new_angular_velocity)*(dt_secs/2)); entity.angular_velocity = new_angular_velocity; } @@ -178,12 +181,22 @@ void Physics::apply_impulses() { SimulatedEntity &entity1 = entities[c.body1]; SimulatedEntity &entity2 = entities[c.body2]; - LinAl::Vector v_rel = entity2.velocity-entity1.velocity; + LinAl::Vector r1 = c.point-entity1.position; + LinAl::Vector r2 = c.point-entity2.position; + LinAl::Vector v_p1 = entity1.velocity+LinAl::Vector(-r1.y, r1.x)*entity1.angular_velocity.radians(); + LinAl::Vector v_p2 = entity2.velocity+LinAl::Vector(-r2.y, r2.x)*entity2.angular_velocity.radians(); + LinAl::Vector v_rel = v_p2-v_p1; + LinAl::Vector tangent = normalize(v_rel-c.normal*inner_product(v_rel, c.normal)); float restitution = 1.0f; + float friction_coeff = 0.1f; float inv_mass_sum = entity1.inverse_mass+entity2.inverse_mass; - float impulse = (1+restitution)*inner_product(v_rel, c.normal)/inv_mass_sum; - entity1.velocity += c.normal*(impulse*entity1.inverse_mass); - entity2.velocity -= c.normal*(impulse*entity2.inverse_mass); + float reaction = (1+restitution)*inner_product(v_rel, c.normal)/inv_mass_sum; + float friction = reaction*friction_coeff; + LinAl::Vector impulse = c.normal*reaction+tangent*friction; + entity1.velocity += impulse*entity1.inverse_mass; + entity2.velocity -= impulse*entity2.inverse_momi; + entity1.angular_velocity += Geometry::Angle::from_radians(entity1.inverse_momi*(r1.x*impulse.y-r1.y*impulse.x)); + entity2.angular_velocity -= Geometry::Angle::from_radians(entity2.inverse_momi*(r2.x*impulse.y-r2.y*impulse.x)); } } diff --git a/examples/bassteroids/source/physics.h b/examples/bassteroids/source/physics.h index 078d2e6..096e228 100644 --- a/examples/bassteroids/source/physics.h +++ b/examples/bassteroids/source/physics.h @@ -17,7 +17,7 @@ private: { Msp::Game::Handle entity; float inverse_mass = 1.0f; - float moment_of_inertia = 1.0f; + float inverse_momi = 1.0f; Msp::LinAl::Vector external_force; float external_torque = 0.0f; -- 2.43.0