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/math.hpp>
#include <psemek/util/profiler.hpp>
#include <psemek/log/log.hpp>
#include <optional>
@ -415,13 +413,18 @@ namespace psemek::phys2d
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 update(float dt);
void apply_gravity(float dt);
void integrate(float dt);
void resolve_collisions();
void gather_collisions();
void resolve_impulses();
void resolve_penetrations();
void log_energy();
float energy();
@ -446,7 +449,9 @@ namespace psemek::phys2d
{
apply_gravity(dt);
integrate(dt);
resolve_collisions();
gather_collisions();
resolve_impulses();
resolve_penetrations();
// 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)
{
@ -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)
{
@ -547,12 +553,13 @@ namespace psemek::phys2d
}
}
}
}
std::size_t const contact_count = contacts_by_velocity.size();
std::size_t const impulse_iterations = contact_count * 2;
std::size_t const penetraion_iterations = contact_count * 2;
void engine::impl::resolve_impulses()
{
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();
@ -711,9 +718,11 @@ namespace psemek::phys2d
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();)
{
auto jt = it++;
@ -726,9 +735,9 @@ namespace psemek::phys2d
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();