29. OpenGL Bounding Sphere Collision

p>Every good game has some sort of collision detection. Without it you would
not even be able to tell if there was a wall in front of you. So here
I am going to show you how to use bounding spheres.

Bounding spheres are like a sphere that radiates from your chosen point
and radiates to the distance in which you set as the radius of your
sphere.

A bigger sphere has a bigger radius. Therefore, objects can’t come as
close as with a smaller sphere.

Now first, we need to set some variables to be able to hold our points
locations and the size of their radii.

This will hold the distance between our objects
GLfloat d;

This will hold the x,y and z positions for our first point
GLfloat p1x;
GLfloat p1y;
GLfloat p1z;

This will hold the size of the radii for the 2 points
point 1 has a radius of 1, and point 2 has a radius of 0, there point 2
will act just like a point, while point 1 will act like a sphere
const p1radius = 1;
const p2radius = 0;

This will hold the x,y and z poisitions for our second point
GLfloat p2x;
GLfloat p2y;
GLfloat p2z;

Now for the guts of this tutorial, working out the collision
void collision (void) {
Our distance is worked out with this simple little formula.
d = sqrt(((p1x – p2x) * (p1x – p2x)) + ((p1y – p2y) * (p1y – p2y)) + ((p1z – p2z) * (p1z – p2z)));
}

Technically you could write it as:
d = sqrt(((p1x – p2x)^2) + ((p1y – p2y)^2) + ((p1z – p2z)^2));
But it is just a matter of preference.

Now to draw the points.
void pointz (void) {
glPushMatrix();

If the distance between the 2 points, is less than that of there radii
combined, then there is a collision
if (d <= p2radius + p1radius)
{

Set the color of our first point to red
glColor3f(1, 0, 0);
}
else
{

If not, then set it to blue
glColor3f(0, 0, 1);
}

Begin drawing the point
glBegin(GL_POINTS);
Draw it at its x,y and z position
glVertex3f(p1x, p1y, p1z);
glEnd();
glPopMatrix();

glPushMatrix();
Set the color of our first point to green
glColor3f(0, 1, 0);
Begin drawing the point
glBegin(GL_POINTS);
Draw it at its x,y and z position
glVertex3f(p2x, p2y, p2z);
glEnd();
glPopMatrix();
}

Now this is just to show you that it works, we are moving the points around
with the following keys.
void keyboard (unsigned char key, int x, int y) {
if (key==’q’) {
p1z = p1z – 0.1;
}

if (key==’z’) {
p1z = p1z + 0.1;
}

if (key==’w’) {
p1y = p1y + 0.1;
}

if (key==’s’) {
p1y = p1y – 0.1;
}

if (key==’a’) {
p1x = p1x – 0.1;
}

if (key==’d’) {
p1x = p1x + 0.1;
}

if (key==’i’) {
p2y = p2y + 0.1;
}

if (key==’k’) {
p2y = p2y – 0.1;
}

if (key==’j’) {
p2x = p2x – 0.1;
}

if (key==’l’) {
p2x = p2x + 0.1;
}

If you have any problems with this tutorial, please email me at swiftless@gmail.com

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
    #include <GL/gl.h>
#include <GL/glut.h>
#include <math.h>

GLfloat d;

GLfloat p1x;
GLfloat p1y;
GLfloat p1z;

const p1radius = 1;
const p2radius = 0;

GLfloat p2x;
GLfloat p2y;
GLfloat p2z;

void collision (void) {
d = sqrt(((p1x p2x) * (p1x p2x)) + ((p1y p2y) * (p1y p2y))
+ ((p1z p2z) * (p1z p2z)));
}

void pointz (void) {
glPushMatrix();
if (d <= p2radius + p1radius)
{
glColor3f(1, 0, 0);
}
else
{
glColor3f(0, 0, 1);
}
glBegin(GL_POINTS);
glVertex3f(p1x, p1y, p1z);
glEnd();
glPopMatrix();

glPushMatrix();
glColor3f(0, 1, 0);
glBegin(GL_POINTS);
glVertex3f(p2x, p2y, p2z);
glEnd();
glPopMatrix();
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    glLoadIdentity();  
    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glPointSize(5);
    collision();
    pointz();
    glutSwapBuffers();
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
}

void keyboard (unsigned char key, int x, int y) {
if (key==‘q’) {
p1z = p1z  0.1;
}

if (key==‘z’) {
p1z = p1z + 0.1;
}

if (key==‘w’) {
p1y = p1y + 0.1;
}

if (key==‘s’) {
p1y = p1y  0.1;
}

if (key==‘a’) {
p1x = p1x  0.1;
}

if (key==‘d’) {
p1x = p1x + 0.1;
}

if (key==‘i’) {
p2y = p2y + 0.1;
}

if (key==‘k’) {
p2y = p2y  0.1;
}

if (key==‘j’) {
p2x = p2x  0.1;
}

if (key==‘l’) {
p2x = p2x + 0.1;
}

if (key==27) { //27 is the ascii code for the ESC key
    exit (0); //end the program
}
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE); //set up the double 
buffering

    glutInitWindowSize (500, 500);
    glutInitWindowPosition (100, 100);
    glutCreateWindow (“A basic OpenGL Window);
    glutDisplayFunc (display);
    glutIdleFunc (display);
    glutReshapeFunc (reshape);
    glutKeyboardFunc (keyboard);//the call for the keyboard 
function.

    glutMainLoop ();
    return 0;
}

  • March 25, 2010
  • 27