AABB Multiple Collision Response

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

AABB Multiple Collision Response

Post 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!
Last edited by dandymcgee on Sun Jun 13, 2010 6:47 pm, edited 2 times in total.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
eatcomics
ES Beta Backer
ES Beta Backer
Posts: 2528
Joined: Sat Mar 08, 2008 7:52 pm
Location: Illinois

Re: AABB Multiple Collision Response

Post 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
Image
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: AABB Multiple Collision Response

Post 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
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: AABB Multiple Collision Response

Post 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.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: AABB Multiple Collision Response

Post 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.
User avatar
eatcomics
ES Beta Backer
ES Beta Backer
Posts: 2528
Joined: Sat Mar 08, 2008 7:52 pm
Location: Illinois

Re: AABB Multiple Collision Response

Post by eatcomics »

text highlighting w00t!
Image
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: AABB Multiple Collision Response

Post 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?
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
Ginto8
ES Beta Backer
ES Beta Backer
Posts: 1064
Joined: Tue Jan 06, 2009 4:12 pm
Programming Language of Choice: C/C++, Java

Re: AABB Multiple Collision Response

Post 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;
}
Quit procrastinating and make something awesome.
Ducky wrote:Give a man some wood, he'll be warm for the night. Put him on fire and he'll be warm for the rest of his life.
Post Reply