Collision Detection & Proper Uneven Terrain Handling

Hi all,

I have been looking into collision handling and a way to have a character move on a ‘random’ uneven terrain while making this appear as natural as possible.

What I want to do:
1)Have a ‘randomly’ created terrain either based on an arbitrary image I will use as a heightfield map or on a polygonal model I will create in some software like Maya (its the one I am currently learning)
2)have a character with some animations for walking, running (perhaps additional ones for walking on terrains with high angle e.t.c)
3)Using collision detection between the character and the terrain i was thinking of placing the character on top of the terrain (for that region) whenever I get a collision with the terrain.
4)Whenever such a colission occurs the characters will not only be moved on top of that part of the terrain but using the normal of that polygon(s) I want to rotate the character accordingly to make the whole thing appear a bit more realistic.

My questions are:
1)Is there a way to know at which part of the polygonal mesh of an object, has a collision occurred? In this case in which polygon of the terrain the character is walking on?
2)If the above is not possible then I can get the 2D coords (lets say x,y for the plane and z for height even though its different in panda) of the character and approximately know when the collision occured. However I somehow need to find the coords of the terrain polygon where this happened so that I can calculate the normal and rotate the character acoordingly. Any thoughts on how to do this?

3)Are my above questions and logic totally stupid? Is there some better and easier way to do all this? I looked into how PandaSteer handles this kind of thing and the characters there are always partially buried in the terrain (part of their feet at least) so the effect looks like walking on level ground while magically climbing. While this may be fine for a far away view, for a 3rd person perspective its not nice.

I have no idea where to turn for this1 Any suggestions/opinions/link/code or any material is totally welcome and appreciated. Once and If I get something functional I will post the code for future reference.

Thanks in advance,

I just thought that an even better solution would be to have multiple animations for different angles instead of rotating the character. This way it would be even more realistic. However the angle is still need so the above questions still stand…Any help?

I should point out that 4, rotating the character according to the surface normal, will make it look even less realistic. Have you ever tried walking on a slope? A human being tends to stay upright, so that he doesn’t fall over (remember that gravity still points downward, not into the terrain :p)

These are very good questions, but you might be overthinking the problem a bit. The collision system will give you the (x,y) point of the intersection, as well as the surface normal at that point. So you won’t need to do any lookups into the terrain to determine the normal.

The CollisionHandlerFloor can elevate your character to the appropriate height automatically, but it won’t rotate him. You’ll probably want to have your own task to handle that. You can do this with the headsUp() method, which can rotate a node to face a particular direction (e.g. the direction he’s already facing), while also rotating his up axis to be in line with the specified vector (your surface normal).

For simplicity, you might want to avoid using the CollisionHandlerFloor and simply handle both functions in your own Python task, using (for instance) a CollisionHandlerQueue.


Thank you rdb and David for your lightning fast responses.

First of all rdb you are right, rotating will probably ugly it even more. So I think I am going to use the angle to change the animation to one with curved back and more bending on the knees etc. Have to look it up more carefully. Still I want to know the angle to specify which animation to use (2-3 perhaps depending on angle)

David, I did not know what you say can be done. Can you point me to some example or snippet where this is shown?

Thank you both very much

Just search for CollisionHandleQueue in the forums and in the manual and examples. Each entry in the queue is a CollisionEntry, and this has methods like getSurfacePoint() and getSurfaceNormal() to return the point of collision and the surface normal at that point.


Guy, take a look at my new thread, I have the same doubt and I had some progress, maybe you’ll like it.

This thread