Collision Detection

Hi,

My entire OpenGL world is built with cubes. Therefore, I decided to use bounding boxes for my collisions. I already have a procedure that returns whether there is a collision between your current position and any of the bounding boxes. It returns either 1 (collision on x), 2 (collision on y), 3 (collision on z) or 0 (no collisions).

My update camera procedure looks like this:


void updateCamera()
{
    glRotatef(xrot,1.0,0.0,0.0);  //rotate our camera on the x-axis (left and right)
    glRotatef(yrot,0.0,1.0,0.0);  //rotate our camera on the y-axis (up and down)


    glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera
}


What I want to know is how I can translate the information provided by my collision procedure to stop the camera flying through things?

Thanks,

James

This can be a black art due to timestep & numerical issues but one typical way is to move the eye to the point of the collision minus some distance whence it traveled. Then take the residual vector and dot product it with the collision normal. Subtract the dot product * normal from the remaining motion vector and add that motion to the collision eye position (you may have to switch a sign or two).

The result will be the eye sliding along the collision surface.

For complete robustness you need some kind of volume collision that is compatible with your typical velocities otherwise you risk sticking at corners or penetrating cracks depending on your implementation.

Hi,

Thanks for the reply. I’m afraid you lost me. Could you give me some example code (c++) or point me to a tutorial?

Anyone?

hello OPENGL users;

I need a help if possible. I am a beginner to use OPENGL and would like to develope collision detection to my application. I know that opengl does not support collision detection, I went over internet but all what I found is hard and not sure which algorithm is better with notice that the objects that I need to detect collision for one of them is not convex shape and other one is a sphere.

can you please, provide me with any helpful links, materials?

Thank you in advance.

@hana, you might want to use an external collision library. I haven’t used one, but google might turn up some results.

@OP
So… your collision function… do you enter a radius of collision?

Anyways, for the camera’s position in 3d space, take the rightmost column of the matrix found by:
glTranslated(xpos,ypos,zpos);
glRotatef(-yrot,0.0,1.0,0.0);
glRotatef(-xrot,1.0,0.0,0.0);
(just the inverse of the view matrix here)

Then, do your collision function, so check if your camera is near a wall. if it’s too close, find the face’s normal, and push the camera out in the direction of the normal, by an amount either found in your calculation of the collision, arbitrarily selected.

sooo take the rightmost vector of the above matrix, do your collision check, push the rightmost vector away from the wall, and then set that vector to be your camera’s position.

[edit]
ALSO you can do what dorbie said, and mess with the velocity,but I prefer not to get fancy xD
The intended velocity, plus the change in movement from the collision code, will approximately (or exactly if you do it right) equal the overall velocity as per described in dorbie’s post (the correct velocity)

Check out Bullet.

Free download, build the examples, and try. Supports OpenGL and is very capable. Some big companies now using it.

Also, for a quick overview of some basic physics/collision detection concepts, take a look at the SIGGRAPH 2010 course slides on this:

In particular, check out the Yoon 3pm, Young 2:30pm, and Coumans 4:15pm presentations if you’re pressed for time. That said, what time you spend up-front getting your head inside the problem domain will save you big later.

Hi,

I kind of understand your solution… would this also work with colliding with the floor and if so, how would I use this to impliment basic gravity.

James

James,
Since I’m new at this as well, this may or may not help. Instead of rotating and translating your world around your camera, you might want to consider leaving the world stationary and moving your camera within your world.

 By using the gluLookAt(eye_x, eye_y, eye_z, lookat_x, lookat_y, lookat_z, up_x, up_y, up_z) command, you can explicitly specify your camera's eye position and if it is about to collide with a box (or be inside a box) you can modify it's position before redrawing the screen.

 I prefer to think of my world in world coordinates and allow objects to move within that frame of reference (including my camera).

void RenderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(Eye_x, Eye_y, Eye_z, At_x, At_y, At_z, 0, 0, 1); // assuming Z-direction is up
glPushMatrix();
Draw_World();
glPopMatrix();
glutSwapBuffers();
}

Regards
Dave