2D physics example (wip)

This commit is contained in:
Nikita Lisitsa 2020-12-16 11:03:30 +03:00
parent 415616534e
commit d34d712fa3

View file

@ -41,7 +41,7 @@ struct physics_2d_app
float physics_lag = 0.f; float physics_lag = 0.f;
phys2d::engine::material_handle material; 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; phys2d::engine::group_handle ball_group, box_group;
float const world_width = 5.f; float const world_width = 5.f;
@ -49,7 +49,7 @@ struct physics_2d_app
float const line_width = 0.05f; 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_width = 0.5f;
float const box_height = 0.25f; float const box_height = 0.25f;
@ -80,7 +80,7 @@ struct physics_2d_app
float const inf = std::numeric_limits<float>::infinity(); float const inf = std::numeric_limits<float>::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_shape = physics.add_shape(phys2d::ball{ball_radius});
ball_group = physics.create_group(); 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}); 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 nx = std::ceil(simulation_box[0].length() / box_width);
int ny = std::ceil(simulation_box[1].length() / box_height); int ny = std::ceil(simulation_box[1].length() / box_height);
@ -114,7 +116,7 @@ struct physics_2d_app
// if (false) // if (false)
{ {
int chess = 1; int chess = 1;
for (int y = 0; y < 5; ++y) for (int y = 0; y < 4; ++y)
{ {
if (chess && (y % 2)) if (chess && (y % 2))
{ {
@ -154,7 +156,7 @@ struct physics_2d_app
} }
auto wall_group = physics.create_group(); 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}); 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, {}, {}); 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]{ 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); 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 void on_resize(int width, int height) override
@ -218,9 +229,10 @@ struct physics_2d_app
} }
else if (mouse) else if (mouse)
{ {
physics.add_object(ball_group, ball_shape, material, {*mouse, 0.f}, {{0.f, 0.f}, 0.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(ball_group, large_ball_shape, material, {*mouse, 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) 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 void update() override
{ {
util::profiler prof("update");
float MOTOR = 15.f; float MOTOR = 15.f;
float m = 0.f; float m = 0.f;
@ -362,16 +379,32 @@ struct physics_2d_app
float const frame_dt = frame_clock.restart().count(); float const frame_dt = frame_clock.restart().count();
physics_lag += frame_dt; 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) while (physics_lag > physics_dt)
// if (physics_lag > physics_dt)
{ {
physics_lag -= physics_dt; physics_lag -= physics_dt;
physics.update(physics_dt); physics.update(physics_dt);
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
apply_constraints(physics_dt, 1.f); 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) if (!drag_delta)
{ {
selected_ball = std::nullopt; selected_ball = std::nullopt;