// between them and replace if collision time smaller
if (FindBallCol(Pos2, BallTime, RestTime, BallColNr1, BallColNr2)) {
if (sounds) PlaySound("Explode.wav", NULL, SND_FILENAME|SND_ASYNC);
if ( (lamda == 10000) || (lamda > BallTime) ) {
RestTime = RestTime - BallTime;
TVector pb1, pb2, xaxis, U1x, U1y, U2x, U2y, V1x, V1y, V2x, V2y;
double a,b;
...
code omitted for space reasons
the code is described in the Physically Based Modeling section under sphere to sphere collision
...
// Update explosion array and insert explosion
for (j = 0; j < 20; j++) {
if (ExplosionArray[j]._Alpha <= 0) {
ExplosionArray[j]._Alpha = 1;
ExplosionArray[j]._Position = ArrayPos[BallColNr1];
ExplosionArray[j]._Scale = 1;
break;
}
}
continue;
}
}
// End of tests
// If collision occured move simulation for the correct timestep
// and compute response for the colliding ball
if (lamda !=10000) {
RestTime -= lamda;
for (j = 0; j < NrOfBalls; j++) ArrayPos[j] = OldPos[j] + ArrayVel[j] * lamda;
rt2 = ArrayVel[BallNr].mag();
ArrayVel[BallNr].unit();
ArrayVel[BallNr] = TVector::unit( (normal * (2 * normal.dot(-ArrayVel[BallNr]))) + ArrayVel[BallNr] );
ArrayVel[BallNr] = ArrayVel[BallNr] * rt2;
// Update explosion array and insert explosion
for (j = 0; j < 20; j++) {
if (ExplosionArray[j]._Alpha <= 0) {
ExplosionArray[j]._Alpha = 1;
ExplosionArray[j]._Position = point;
ExplosionArray[j]._Scale = 1;
break;
}
}
} else RestTime=0;
} //end of while loop
The main global variables of importance are:
Represent the direction and position of the camera. The camera is moved using the LookAt function. As you will probably notice, if not in hook mode (which I will explain later), the whole scene rotates around, the degree of ratation is handles with camera_rotation. | TVector dir; TVector pos(0,-50,1000); float camera_rotation=0; |
Represent the acceleration applied to the moving balls. Acts as gravity in the application. | TVector accel(0,-0.05,0); |
Arrays which hold the New and old ball positions and the velocity vector of each ball. The number of balls is hard coded to 10. | TVector ArrayVel[10]; TVector ArrayPos[10]; TVector OldPos[10]; int NrOfBalls=3; |
The time step we use. | double Time=0.6; |
If 1 the camera view changes and a (the ball with index 0 in the array) ball is followed. For making the camera following the ball we used its position and velocity vector to position the camera exactly behind the ball and make it look along the velocity vector of the ball. | int hook_toball1=0; |
Self explanatory structures for holding data about explosions, planes and cylinders. | struct Plane struct Cylinder struct Explosion |
The explosions are stored in a array, of fixed length. | Explosion ExplosionArray[20]; |
The main functions of interest are:
Perform Intersection tests with primitives | int TestIntersionPlane(…); int TestIntersionCylinder(…); |
Loads Textures from bmp files | void LoadGLTextures(); |
Has the rendering code. Just renders every time the balls, walls, columns and explosions | void DrawGLScene(); |
Performs the main simulation logic | void idle(); |
Sets Up OpenGL state | void InitGL(); |
Find if any balls collide again each other in current time step | int FindBallCol(…); |
For more information look at the source code. I tried to comment it as good as possible. Once the collision detection and response logic is understood, the source should become very clear. For any more info don't hesitate to contact me.
As was stated at the beginning the subject of collision detection is a very difficult and versatile subject to be covered only by one tutorial. Although we have come a long way, learned a lot of new stuff and can now create some nifty and impressive things as the demo shows, there is still a long way in front of you. Now that you have the basics all the other sources on Collision Detection and Physically Based Modeling out there should become easier to understand. With this I send you on your way and wish you happy collisions!!!