Some collision handling fun
I am looking for the most elegant solution to a specific problem that I am having.
Before saying anything else: I am using OpenGL with SDL.
Let me first explain how I am currently handling collision detection in my game project:
The game map is a 3-dimensional map composed of cells. Each cell is literally a block that is 1x1x1 in its dimensions - making it quite easy to handle. Each face of a cell can be defined as having a wall or not having a wall. If a specific face has a wall, then it is assigned a texture and rendered. Otherwise it is not.
Now, let's say the camera is sitting in cell X. We already know that we only have to check for collisions for other objects also in cell X or the walls defined in cell X (the faces of the cell).
For now we will assume that there are no objects at all in cell X, and so we are only checking collisions on the walls in cell X.
Please take a look at exhibit A.
Exhibit A shows us the camera facing the wall about to collide into it. The blue lines represent where I have set the "clipping planes" for collision detection. Instead of detecting collision right at the point of the wall, I detect collision just a little bit in front of the wall. This helps to avoid some unwanted artifacts of actually hitting the wall (and thus the camera seeing through the wall).
Now, to do the actual collision detection, I simplified the problem into a clipping algorithm (hence why I used the term clipping planes above). In essence that is all collision detection is. Please observe exhibit B.
In exhibit B we see a starting point and an ending point after a movement has been made. The collision detection algorithm forms a line and calls the Sutherland-Hodgman polygon clipping algorithm in order to clip the endpoint of the movement into an allowed movement space. Therefore the player is able to move to the wall without ever going beyond the wall.
So far all is well and good. What I have explained so far works...and it works well. Now we arrive at the problem. I want to implement gravity into the engine. Please observe exhibit C.
Part of the problem with implementing gravity is that I must more concretely define where the player is in terms of the y-axis. Up until this point the location of the player has been the location of the camera. This causes no problems.
Now when I implement gravity, gravity wants to push the player down onto the ground...so technically the player position should be on the ground. However, if the position of the player actually is on the ground (i.e. sitting on the collision detecting plane), then a collision is constantly occurring, and therefore the algorithm will always throw out any move that the player tries to make, and the player will not be able to move.
See the problem?
So basically...if player movement gets clipped because the entire movement vector is sitting right on a "clipping" plane, I still want the player to be able to move on axes other than the one that that clipping plane is defining. Get the drift?
Based on what I have explained here, can anyone suggest an elegant solution?