First let me tell you a bit about how I do collisions, then I’ll get to the problem…
a quick look at http://home.earthlink.net/~ioquan will give you an idea of the context in which I am doing this.
My frame updates go something like this:
-
Get Input.
-
For each object that can move, calculate a velocity vector. The velocity vector is determined by various factors, including gravity, thrust, and previous velocity. The final vector is then scaled by time. Also calculate a rotation velocity and scale it by time.
-
Now do collisions. For each moving object, test it against each other object. If the bounding spheres of the two objects collide, then do one of two things. If the object that it collided with is a model, correct the collision against the model’s bounding box (this works fine). If the object it collided with is terrain, then do a quad tree search. The quad tree does a few checks, then returns a small list of polygons with which to do more accurate tests. Now that I have a list of polygons, I take the “foot” of the moving object (a single point near the feet) plus the velocity vector. That gives me a line segment to test against each poly. If the poly is a floor, there is one kind of correction, if it’s a wall, there is another kind.
Note about collision correction: the purpose of the collision correction functions (Facet3D::RayCollide(pos,vel) and SmartBox::RayCollide(pos,vel)) is to change the velocity vector so that the collision doesnt happen. This is where most info on the web leaves off. They simply tell you how to determine if a collision happens, then assume you just want to STOP the player. In actuality, you need to slide the player.
The floor tests work fine. I simply solve for the y coordinate using the point the player is trying to move to and the plane equation of the polygon with which it collides. This results in the player being able to walk around the terrain, being raised with the floors.
The wall tests are the problem. If I just want to stop the player, that’s easy, I just find the intersection point, and change the velocity to (intersect - oldposition). Just stopping the player is not right though. I have tried many different methods of sliding the player. I have succeeded in sliding the player, but there are problems. Certain sliding methods result in the player bouncing erratically when he is colliding with both a wall and a floor. By tweaking some settings, I can reduce the bouncing in some places, but then it seems to appear in other places. I can also make it so the y coordinate of the final position to move to is the same as the intersection point; that reduces the bouncing greatly, but also means the player cant slide down a steep wall.
So ultimately what I want to know is, what is the right way to slide a player along a wall, and how can you eliminate the nasty bouncing side effects?
If anyone has done these types of collisions(like quake, doom, and just about any 3d game with floors and walls) , and can offer any insight, it would be much appreciated. Or if you have a URL that discusses this topic, that would be very helpful too.
[This message has been edited by ioquan (edited 05-31-2002).]