Page 1 of 1

AABB Multiple Collision Response

Posted: Sun Jun 13, 2010 4:25 pm
by dandymcgee
I'm trying to figure out how to deal with collisions between multiple objects. I'm using Falco's AABB collision function which returns both a boolean value and the normal of intersection.

Right now I have three different types of objects: Player (Any character), Dynamic (pushable), and Solid (does not move)

The following response causes the second object to be pushed by the first (player kicks a can out of his way)

Code: Select all

objects[j]->Center( objects[j]->Center() + normal );
 
This response causes the first object to be stopped by the second (player walks into a wall)

Code: Select all

objects[i]->Center( objects[i]->Center() - normal );
 
The problem is handing collisions between the different types of objects.

This is what I'm playing with at the moment:

Code: Select all

for( int i = 0; i < numberOfObjects; i++ ){
    for( int j = 0; j < numberOfObjects; j++ ){
        if( AABBCollisionCheck(objects[i], object[j], normal) ){
            //PLAYER pushes DYNAMIC
            if( objects[i]->Type() == PLAYER_OBJECT && objects[j]->Type() == DYNAMIC_OBJECT ){
                objects[j]->Center( objects[j]->Center() + normal );
            //PLAYER is stopped by SOLID
            }else if(objects[i]->Type() == PLAYER_OBJECT && objects[j]->Type() == SOLID_OBJECT ){
                objects[i]->Center( objects[i]->Center() - normal );
            //DYNAMIC is pushed by PLAYER
            }else if( objects[i]->Type() == DYNAMIC_OBJECT && objects[j]->Type() == PLAYER_OBJECT ){
                objects[i]->Center( objects[i]->Center() - normal );
            //SOLID is unaffected by PLAYER
            }else if( objects[i]->Type() == SOLID_OBJECT && objects[j]->Type() == PLAYER_OBJECT ){
                objects[j]->Center( objects[j]->Center() + normal );
            }else{
                objects[i]->Center( objects[i]->Center() - normal );
                objects[j]->Center( objects[j]->Center() + normal );
            }
        }
    }
}
 
The major mishap occurs when the player is pushing a dynamic object that then collides with solid object. This forces the player through the dynamic object (see illustration below)
Image

The first way I tried to solve this was to set the dynamic object's type to solid while it was colliding with a solid, but I couldn't figure out how or when to change it back to dynamic (so it would become "stuck" as if it were a solid itself).

How would you handle collisions between objects with different properties?

Thanks for reading!

Re: AABB Multiple Collision Response

Posted: Sun Jun 13, 2010 4:33 pm
by eatcomics
sounds like you need a way of determining which side is colliding with the solid, and which side the player is pushing it... or you could just do a test on wether pushing the object would make it go farther into the solid object (if that makes sense) and then if it does make it go in further just keep it still instead of pushing, but otherwise push it

Re: AABB Multiple Collision Response

Posted: Sun Jun 13, 2010 6:17 pm
by XianForce
Before you actually resolve the player - dynamic collision, check if the dynamic has a collision with a solid in the same direction, if so, then reverse the effects and push back the player

Re: AABB Multiple Collision Response

Posted: Sun Jun 13, 2010 6:43 pm
by dandymcgee
XianForce wrote:Before you actually resolve the player - dynamic collision, check if the dynamic has a collision with a solid in the same direction, if so, then reverse the effects and push back the player
So you're saying I should have separate object collections for each type? Right now there's no way to make sure dynamic / static is checked before player / dynamic since the objects are sorted by their (somewhat arbitrary) IDs.

Re: AABB Multiple Collision Response

Posted: Sun Jun 13, 2010 8:32 pm
by Falco Girgis
The problem is that a player and a wall are essentially "infinite mass" bodies in this game/simulation. The rigid bodies (mass aggregate technically, lolz) are unable to move either the player or wall, no matter how much force is exerted (depth of penetration).

I would propose a flag on the dynamic bodies that is set whenever the dynamic body has been moved or "resolved" as a result of colliding with a static body. By using this flag, the dynamic body can push back on the player.

If a player and dynamic body collide without the flag set, the player moves the body.

If a player and a dynamic body collide WITH the flag set, the player is moved backwards by the collision normal.

This flag needs to be cumulative so that when you have player against dynamic body against dynamic body against the wall, it will aggregate back to the player.

Re: AABB Multiple Collision Response

Posted: Sun Jun 13, 2010 11:53 pm
by eatcomics
text highlighting w00t!

Re: AABB Multiple Collision Response

Posted: Mon Jun 14, 2010 1:46 pm
by dandymcgee
GyroVorbis wrote:This flag needs to be cumulative so that when you have player against dynamic body against dynamic body against the wall, it will aggregate back to the player.
This is what I'm having trouble figuring out how to do. You've mentioned each object having a list of all of the other objects it's colliding with, is that the best way to aggregate the force back through to the player?

Re: AABB Multiple Collision Response

Posted: Mon Jun 14, 2010 5:29 pm
by Ginto8
dandymcgee wrote:
GyroVorbis wrote:This flag needs to be cumulative so that when you have player against dynamic body against dynamic body against the wall, it will aggregate back to the player.
This is what I'm having trouble figuring out how to do. You've mentioned each object having a list of all of the other objects it's colliding with, is that the best way to aggregate the force back through to the player?

Code: Select all

object->handleCollision();
if(object->movedByStatic) {
    // stuff handling the movedByStatic case goes here
    this->movedByStatic = true;
}