BSP Collision Handling

Started by
2 comments, last by jafe 16 years, 1 month ago
Hello there, I've just implemented some simple collision detection code as described here, http://www.devmaster.net/articles/quake3collision/ . Now I've gone on to develope how to handle specific collisions. I am trying to make the 'slide' effect as popular in many FPS games (ie no instantaneous stop when hitting a wall), my recent attempts have been 'bumpy', and so if anybody has any experience or information which could help, it would be greatly appreciated. -Mike
Advertisement
jafe,

I'm not sure what the best solution is. However, if I was to do this, I would get the angle between the walls face and my look at vector.

So, if you are facing the wall exactly, you will get a 0 angle. If you are facing left completely, you'll have 90 degrees and opposite you will have -90 degrees. Normalized that to a -1 to 1 float by dividing it by 90 degrees. Now take that float and multiply it by the full speed of youre movement. This will allow you to have the right speed while sliding against the wall.

float speed = dot(wallface, lookatdir) / DegToRad(90);

Then, all you have to do is, if you collide with a wall take the perpendicular angle of the wall face to get the vector you will move along and move a unit * the speed we calculated.

It's hard to try and explain, but let me know if you have any questions.

I haven't worked with BSP's at all, so I don't know how this will work in a BSP environment.

jeff.
Say that you want to move along some line, from point p0 to point p1. This line collides between those points with some plane, with some point of collision cp. You then update your position to cp and stop there. In order to instead glide along the plane you must redo the move after having done this, with a new line of movement. This new line will have cp as it's p0 and another point along the plane as it's p1. Then you redo the whole thing again from the top. The problem is finding the endpoint p1 for the new line of movement along the plane, labeled p in the image below.



This point p is easily found by moving along the normal of the plane from the old p1 until we hit the plane. This can be accomplished by first calculating the distance from the plane to the old p1 that is behind the plane. Then move this distance along the direction of the plane's normal, and you have your point p.
You probably want to move slightly further, like some safety distance in front of the plane, instead of exactly on the plane, in order to avoid precision problems in floating point operations, which could potentially lead to getting stuck in the plane or sometimes moving through the plane. In the same way it might also be a good idea to offset the point cp some very small distance along the plane normal so that it's in front of the plane. Something like 0.01 perhaps, depending on the scale of your world of course. It should preferably be small enough to not be noticed by the user but still avoid precision problems.

You might notice that the above algorithm is best done recursively, looping until no collision is found. You might further ahead notice that this can potentially lead to very long recursion when walking right into two planes at the same time depending on the angle between the planes, so some cutoff number of iterations might be a good idea, simply setting the position to cp if the recursion goes too far.
I remember getting infinite loops in such cases when I first started doing this type of collision detection.

Also note the sign of the distance to the point p1 behind the plane. Usually distances to planes are considered negative when behind the plane, so then you must be sure to move in the positive direction along the normal even though the signed distance is negative.
Many thanks for the replies. It helped, I now have the slide effect working to a big extent (some walls where there are more than 3 intersecting planes cause the abrupt stop but I'm not worrying too much about that at the moment)

-Mike

This topic is closed to new replies.

Advertisement