From d34d712fa3113818d5a2e0da261553d5ec624e77 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Wed, 16 Dec 2020 11:03:30 +0300 Subject: [PATCH] 2D physics example (wip) --- examples/physics_2d.cpp | 53 +++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/examples/physics_2d.cpp b/examples/physics_2d.cpp index 0cce76cd..ab4216f5 100644 --- a/examples/physics_2d.cpp +++ b/examples/physics_2d.cpp @@ -41,7 +41,7 @@ struct physics_2d_app float physics_lag = 0.f; phys2d::engine::material_handle material; - phys2d::engine::shape_handle ball_shape, large_ball_shape, box_shape, small_box_shape; + phys2d::engine::shape_handle ball_shape, large_ball_shape, box_shape, small_box_shape, wide_box_shape; phys2d::engine::group_handle ball_group, box_group; float const world_width = 5.f; @@ -49,7 +49,7 @@ struct physics_2d_app float const line_width = 0.05f; - float const ball_radius = 0.5f; + float const ball_radius = 0.25f; float const box_width = 0.5f; float const box_height = 0.25f; @@ -80,7 +80,7 @@ struct physics_2d_app float const inf = std::numeric_limits::infinity(); - material = physics.add_material({1.f, 0.5f, 1.f}); + material = physics.add_material({1.f, 0.5f, 0.5f}); ball_shape = physics.add_shape(phys2d::ball{ball_radius}); ball_group = physics.create_group(); @@ -92,6 +92,8 @@ struct physics_2d_app small_box_shape = physics.add_shape(phys2d::box{box_width / 2.f, box_height}); + wide_box_shape = physics.add_shape(phys2d::box{box_width * 8.f, box_height}); + int nx = std::ceil(simulation_box[0].length() / box_width); int ny = std::ceil(simulation_box[1].length() / box_height); @@ -114,7 +116,7 @@ struct physics_2d_app // if (false) { int chess = 1; - for (int y = 0; y < 5; ++y) + for (int y = 0; y < 4; ++y) { if (chess && (y % 2)) { @@ -154,7 +156,7 @@ struct physics_2d_app } auto wall_group = physics.create_group(); - auto wall_material = physics.add_material({inf, 0.5f, 1.f}); + auto wall_material = physics.add_material({inf, 0.5f, 1.5f}); auto wall_0_shape = physics.add_shape(phys2d::half_space{{1.f, 0.f}, simulation_box[0].min}); physics.add_object(wall_group, wall_0_shape, wall_material, {}, {}); @@ -191,6 +193,15 @@ struct physics_2d_app loop.dispatch_at(std::chrono::system_clock::now() + std::chrono::seconds{1}, [this]{ physics.explode(simulation_box.corner(0.5f, -0.2f), 1000.f, 100.f); }); + +// loop.dispatch_at(std::chrono::system_clock::now() + std::chrono::seconds{5}, [this]{ +// stop(); +// }); + } + + ~physics_2d_app() + { + util::profiler::dump(); } void on_resize(int width, int height) override @@ -218,9 +229,10 @@ struct physics_2d_app } else if (mouse) { - physics.add_object(ball_group, ball_shape, material, {*mouse, 0.f}, {{0.f, 0.f}, 0.f}); -// physics.add_object(box_group, box_shape, material, {*mouse, 0.f}, {}); +// physics.add_object(ball_group, ball_shape, material, {*mouse, 0.f}, {{0.f, 0.f}, 0.f}); // physics.add_object(ball_group, large_ball_shape, material, {*mouse, 0.f}, {}); + physics.add_object(box_group, box_shape, material, {*mouse, 0.f}, {}); +// physics.add_object(box_group, wide_box_shape, material, {*mouse, 0.f}, {}); } } @@ -237,7 +249,10 @@ struct physics_2d_app if (mouse) { - physics.explode(*mouse, 1000.f, 100.f); + physics.add_object(ball_group, ball_shape, material, {*mouse, 0.f}, {{0.f, 0.f}, 0.f}); +// physics.add_object(box_group, box_shape, material, {*mouse, 0.f}, {}); +// physics.add_object(box_group, wide_box_shape, material, {*mouse, 0.f}, {}); +// physics.explode(*mouse, 10.f, 100.f); } } @@ -253,6 +268,8 @@ struct physics_2d_app void update() override { + util::profiler prof("update"); + float MOTOR = 15.f; float m = 0.f; @@ -362,16 +379,32 @@ struct physics_2d_app float const frame_dt = frame_clock.restart().count(); physics_lag += frame_dt; - float const physics_dt = 0.002f; + static int frame_count = 0; + + float const physics_dt = 0.001f; + float const max_physics_time = 0.01f; + if (false) while (physics_lag > physics_dt) -// if (physics_lag > physics_dt) { physics_lag -= physics_dt; physics.update(physics_dt); for (int i = 0; i < 8; ++i) apply_constraints(physics_dt, 1.f); + + if (false && frame_clock.count() > max_physics_time) + { + log::warning() << "Can't keep up with physics, running " << physics_lag << "s behind"; + break; + } } + for (int i = 0; i < 16; ++i) + physics.update(physics_dt); + + ++frame_count; + if (frame_count == 300) + stop(); + if (!drag_delta) { selected_ball = std::nullopt;