Handling simultaneous collisions

Started by
1 comment, last by AussyMike 15 years, 4 months ago
I currently have a demo of 16 boxes bouncing against 4 walls also represented as 4 single pixel thin collision boxes. It works fine, but now I want to have the collision boxes bounce off each other I'm trying to figure the best way to go about it. Currently my movement is frame based and basically works like this: while all movement in this frame hasn't finished { find earliest collision if collision happened within remaining frame time { move all boxes up to time of collision handle the box that collided with a wall add time it took to get to the next collision to the total frame time } else { move all boxes to end of frame position break loop condition } } and if you want to see the actual source code:

	/*Logic*/
	float frameTime = 0;
	    
	//While the frame hasn't finished
	while( roundf( frameTime, 5 ) < 1 )
	{
            //Next collision time and collision intervals
            ColEvent nextEvent;
            
            //Check box collision
            for( int c = 0; c < NUM_BOXES; c++ )
            {
                //Against walls
                for( int w = 0; w < NUM_WALLS; w++ )
                {
                    //Test for collision
                    ColIntervals colI = calc_intervals( boxes[ c ], walls[ w ] );
                    float colT = col_time( colI );
                
                    //If time is earlier
                    if( colT < nextEvent.time )
                    {
                        //Replace collision event
                        nextEvent.time = colT;
                        nextEvent.intervals = colI;
                        nextEvent.a = &boxes[ c ];
                        nextEvent.b = &walls[ w ];
                    }
                }
            }
            
            //If collision happens this frame
            if( roundf( nextEvent.time + frameTime, 5 ) < 1 )
            {
                //Move to collision point
                for( int b = 0; b < NUM_BOXES; b++ )
                {
                    boxes.move( nextEvent.time );
                }
                
                <span class="cpp-comment">//Handle collision</span>
                nextEvent.a-&gt;handle_collision( nextEvent.intervals );
                
                <span class="cpp-comment">//Move time forward</span>
                frameTime += nextEvent.time;
            }
            <span class="cpp-keyword">else</span>
            {
                <span class="cpp-comment">//Do movement for remaining frame</span>
                nextEvent.time = <span class="cpp-number">1</span> - frameTime;
                
                <span class="cpp-comment">//Move to end of frame time</span>
                <span class="cpp-keyword">for</span>( <span class="cpp-keyword">int</span> b = <span class="cpp-number">0</span>; b &lt; NUM_BOXES; b++ )
                {
                    boxes.move( nextEvent.time );
                }
                
                <span class="cpp-comment">//Break loop</span>
                frameTime = <span class="cpp-number">2</span>;
            }
        }
    }

</pre></div><!–ENDSCRIPT–>

Handling two objects bouncing against each other is easy, all my boxes are assumed to have the same mass so they just exchange linear velocities to conserve momentum.

But what do I do if all of my boxes hit each other as &#111;ne clump at the same time? How would I handle if half hit each other in &#111;ne clump and the other half in another clump? And how would I handle a clump of boxes colliding at a wall?

Learn to make games with my SDL 2 Tutorials

Advertisement
the trick here is that you need to solve collisions in the *time* order in which they occur.

so, you would do a broad phase pass over all your objects, and generate a sorted list of collisions which *may* occur. the list would be sorted from earliest to latest.

then, you step over that list, *in time order*, from earliest to latest. doing a narrow phase collision test. If a collision actually occurs.
- you throw out any subsequent possible collisions for the objects involved in the collision that actually happened, the path of this object is likely to change.
- you then do another broad phase test using the objects that you just resolved the collision for, inserting collisions back into the sorted possible collision list.

you then repeat this until you either run out of collisions, or you run out of time for your frame :)

most games dont bother with the handling of dependent collisions due to the variable amount of processing required to actually resolve all possible collisions within a frame. this is where "divide and conquer" methods work well, split your space up in order to reduce the number of possible collisions, so retesting doesnt involve all the objects in the entire world.

Matt D




your never as good as they say you were, never as bad as they say you was.

You move 1 box and check for it colliding with all the others, deal with that collision and then move on to the next box. If you want it to be absolutely accurate then when you find a collision you need to move the box back to where they are just in contact and exchange velocities before moving the box the remaining amount. Should you get two simultaneous collisions then you deal with the one that happened first time wise.

If the above is what your code is doing then just ignore it. I'm not familiar with the functions you are using.

Mike.

This topic is closed to new replies.

Advertisement