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;
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<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_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,15 +379,31 @@ 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)
{