Physics engine 2d: refaactor collisions to 3 functions

This commit is contained in:
Nikita Lisitsa 2020-12-04 13:24:13 +03:00
parent eff7be5653
commit b6a68b8e1a

View file

@ -8,8 +8,6 @@
#include <psemek/geom/rotation.hpp> #include <psemek/geom/rotation.hpp>
#include <psemek/geom/math.hpp> #include <psemek/geom/math.hpp>
#include <psemek/util/profiler.hpp>
#include <psemek/log/log.hpp> #include <psemek/log/log.hpp>
#include <optional> #include <optional>
@ -415,13 +413,18 @@ namespace psemek::phys2d
std::optional<geom::vector<float, 2>> gravity; std::optional<geom::vector<float, 2>> gravity;
std::set<contact, velocity_comparator> contacts_by_velocity;
std::set<contact, penetration_comparator> contacts_by_penetration;
void explode(geom::point<float, 2> const & center, float strength, float attenuation); void explode(geom::point<float, 2> const & center, float strength, float attenuation);
void update(float dt); void update(float dt);
void apply_gravity(float dt); void apply_gravity(float dt);
void integrate(float dt); void integrate(float dt);
void resolve_collisions(); void gather_collisions();
void resolve_impulses();
void resolve_penetrations();
void log_energy(); void log_energy();
float energy(); float energy();
@ -446,7 +449,9 @@ namespace psemek::phys2d
{ {
apply_gravity(dt); apply_gravity(dt);
integrate(dt); integrate(dt);
resolve_collisions(); gather_collisions();
resolve_impulses();
resolve_penetrations();
// log_energy(); // log_energy();
} }
@ -478,7 +483,7 @@ namespace psemek::phys2d
} }
} }
void engine::impl::resolve_collisions() void engine::impl::gather_collisions()
{ {
for (std::size_t gi = 0; gi < groups.size(); ++gi) for (std::size_t gi = 0; gi < groups.size(); ++gi)
{ {
@ -491,7 +496,8 @@ namespace psemek::phys2d
} }
} }
std::set<contact, velocity_comparator> contacts_by_velocity; contacts_by_velocity.clear();
contacts_by_penetration.clear();
for (std::size_t gi = 0; gi < groups.size(); ++gi) for (std::size_t gi = 0; gi < groups.size(); ++gi)
{ {
@ -547,12 +553,13 @@ namespace psemek::phys2d
} }
} }
} }
}
std::size_t const contact_count = contacts_by_velocity.size(); void engine::impl::resolve_impulses()
std::size_t const impulse_iterations = contact_count * 2; {
std::size_t const penetraion_iterations = contact_count * 2; std::size_t const iterations = contacts_by_velocity.size() * 2;
for (std::size_t iteration = 0; iteration < impulse_iterations; ++iteration) for (std::size_t iteration = 0; iteration < iterations; ++iteration)
{ {
contact const & c = *contacts_by_velocity.begin(); contact const & c = *contacts_by_velocity.begin();
@ -711,9 +718,11 @@ namespace psemek::phys2d
groups[ccc.gj].contacts_by_velocity[ccc.j][ctj] = new_it; groups[ccc.gj].contacts_by_velocity[ccc.j][ctj] = new_it;
} }
} }
}
std::set<contact, penetration_comparator> contacts_by_penetration;
void engine::impl::resolve_penetrations()
{
for (auto it = contacts_by_velocity.begin(); it != contacts_by_velocity.end();) for (auto it = contacts_by_velocity.begin(); it != contacts_by_velocity.end();)
{ {
auto jt = it++; auto jt = it++;
@ -726,9 +735,9 @@ namespace psemek::phys2d
groups[c.gj].contacts_by_penetration[c.j].push_back(new_it); groups[c.gj].contacts_by_penetration[c.j].push_back(new_it);
} }
assert(contacts_by_penetration.size() == contact_count); std::size_t const iterations = contacts_by_penetration.size() * 2;
for (std::size_t iteration = 0; iteration < penetraion_iterations; ++iteration) for (std::size_t iteration = 0; iteration < iterations; ++iteration)
{ {
contact const & c = *contacts_by_penetration.begin(); contact const & c = *contacts_by_penetration.begin();