I already have SAT implemented for collision detection and MTV computation and it works totally fine when my character collides with only one object.

But it's possible that there is a collision with multiple objects at once. How do I handle such cases? How do I evaluate chracter translation using all computed MTVs?

Pseudocode of how my code currently looks like:

// Contains objects collision with which was detected during broadphase
list<collider> overlappingObjects;
// Collider for the character for which I'm trying to solve the collision
collider characterCollider;

response res;
vec3 translation;
for(collider in overlappingObjects){
   // test if they actally collide and put collision information in `res` if they do
   if(testCollision(characterCollider, collider, res)){
       translation += res.mtv;

// Moving character out of the collided objects

This code works incorrectly if overlappingObjects contains more than 1 object.

What is the correct solution for such problem?

  • \$\begingroup\$ In my exploration of SAT, I did a 3-pass system: a broad pass to find potential collisions, a narrow pass to find the true collisions, and a resolution pass to actually resolve and move each object. This let me do exactly the sort of stuff you are talking about in-between the narrow pass and the resolution because I had a full list of collisions for each object. \$\endgroup\$ – LAMonday Jan 9 '18 at 17:18
  • \$\begingroup\$ @LAMonday well, I do have the list of collision for each object. But I don’t understand how exactly I have to use collision information from each of them to move my character out of the colliding object. \$\endgroup\$ – Daniil Dubrovsky Jan 9 '18 at 17:33
  • \$\begingroup\$ Turned out that translating by the sum of minimal translation vectors often leads to moving character into other objects. For example, trying to resolve collision in the corner results in jittering movement and doesn’t work as expected. \$\endgroup\$ – Daniil Dubrovsky Jan 9 '18 at 17:35
  • \$\begingroup\$ Ah, I misunderstood slightly. Instead of using a sum of the minimal translation vectors (MTV's), I kept a single (let's call it resolveVector) and for each of the MTV's, I would extend the resolveVector to be the Math.max(resolveVector.x, MTV.x). I didn't come up with a good solution to if a body was being pushed in opposite directions, though -- so for my engine, I just had that kill the body/player (aka, it was crushed). \$\endgroup\$ – LAMonday Jan 10 '18 at 14:31
  • \$\begingroup\$ I have some old code sitting on github. It's definitely been a while since I've touched this stuff, but it may provide some insight to what I'm talking about here \$\endgroup\$ – LAMonday Jan 10 '18 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.