Terrain Collision in Rigid Body System

Started by
5 comments, last by Raeldor 18 years, 1 month ago
Hi All, I am trying to implement collision response in a way that all objects and terrain can be handled the same. This seems more difficult than I initially thought. When the player starts moving, I add an impulse to create the horizontal velocity, then each frame I add the downward force of gravity. This means each frame the player comes into contact with the terrain. I then get the terrain normal at the intersection point and use the reflection of the velocity around this as the new velocity. I have tried this and my character bounces around the screen like a deflating balloon. If I set the restitution to zero, then the character pretty much doesn't move at all since the collision is almost immediate. Is there a way of handling this so that the terrain collision can be handled generally, or will terrain always be a special case and need 'special processing'. Thanks!
Advertisement
Object-Terrain collisions and Object-Object collisions should be able to be handled in the same way. As far as I can tell it sounds like your problem is that the only thing you do in the event of a collision is mirror the velocity. Do the different things that you set restitution to result in the character either bouncing around it it's too high, or sinking through the ground if it's too low?
You will probably need to do more than just mirror velocities after a collision. The method I use is to find how deep the object has penetrated into the terrain and projecting the character that distance along the collision normal.
That should allow you to set restitution low enough for objects to rest on the terrain.

Another thing you could do is split the velocity into two components after the collision, velocity in the Normal direction and velocity in the Tangental direction. Have a Co-efficient of restitution applied to the normal velocity to reduce it and prevent the bouncing.
Then, apply a friction co-efficient to the tangental component of the velocity. This can be different to the restitution co-efficient.
This means that you could set restitution to 0 to prevent the bouncing, without affecting the objects horizontal movement and freezing it to a stop.

http://www.harveycartel.org/metanet/tutorials/tutorialA.html
has a section on this that talks about splitting the velocity to deal with bounciness and slipperness seperately.
Quote:Original post by CIJolly
Object-Terrain collisions and Object-Object collisions should be able to be handled in the same way. As far as I can tell it sounds like your problem is that the only thing you do in the event of a collision is mirror the velocity. Do the different things that you set restitution to result in the character either bouncing around it it's too high, or sinking through the ground if it's too low?
You will probably need to do more than just mirror velocities after a collision. The method I use is to find how deep the object has penetrated into the terrain and projecting the character that distance along the collision normal.
That should allow you to set restitution low enough for objects to rest on the terrain.

Another thing you could do is split the velocity into two components after the collision, velocity in the Normal direction and velocity in the Tangental direction. Have a Co-efficient of restitution applied to the normal velocity to reduce it and prevent the bouncing.
Then, apply a friction co-efficient to the tangental component of the velocity. This can be different to the restitution co-efficient.
This means that you could set restitution to 0 to prevent the bouncing, without affecting the objects horizontal movement and freezing it to a stop.

http://www.harveycartel.org/metanet/tutorials/tutorialA.html
has a section on this that talks about splitting the velocity to deal with bounciness and slipperness seperately.


Thanks for the link. I like the idea of the different restitution to simulate the bouncing and friction. I will definitely implement this. At the moment though, I think my main problem is that the collision is happening too soon into the movement.

I am using the penetration to move the object back along it's original path, but you mention to move the object backwards along the collision normal. Why move it along the normal? Isn't the idea to get back to the point of the original collision? Shouldn't it be moved back along it's original path? Also, after I move it back along the original path (which means is hardly moves horizontally at all), I then try and move it along the new path again for the rest of the distance it should have originally moved. This obviously results in it being embedded back in the terrain again.

I guess my question is then, how do I keep is moving without being embedded back in the terrain? Do I have to keep trying to move it and testing collision until it has moved the correct amount and is not embedded? Sounds processor intensive.

Thanks!

If you restore it to it's original position then it will never be able to slide smoothly along a surface, because regardless of it's velocity, it will hit the terrain every frame and return to its orginal position.

Projecting it along the normal is simplification of a technique involving the "Minimum Translation Distance". Basically you don't want to move the object back to where it used to be, or it wont be able to slide along things. The trick is to translate it the smallest possible distance so that the two objects no longer intersect. A full explanation of MTD and collision detecting in general can be found here:
http://uk.geocities.com/olivier_rebellion/Polycolly.zip

Projecting the object along the normal is a bit of a hacked variation of the MTD technique, but it works.
Lets say that your object has moved down 5 and right 10, resulting in it being embedded 5 units into the terrain. If you restore it back to it's original position, then it gets moved left 10 and up 5, resolving the overlap but at the cost of removing any sideways component of the velocity.

Instead of restoring it's original position, you could try the following:
Translate the object by its velocity, say, right 10 and down 5. Find the collision normal, (say, (0, 1) for a level surface). Project the object 5 units in the direction of the normal. Start the projection from the objects NEW position.
Now the object will be separated from the terrain, but it will still have moved left 10 units.

To find the distance you have to translate the object along the collision normal you could either project all the vertices that make up the object onto the normal, and also project all the vertices that make up the terrain onto the normal, and find the overlap (this is the technique that Oliii's tutorials use).
Or, if you want a simpler way, just translate it a small distance along the normal and then check to see if they are still overlapping. If they are, project it again.
Thanks again for the info. I think I am starting to make progress now. I have the terrain working and have the actor collision with other objects working too. When hitting other objects though, the player should keep walking as opposed to just stopping or sliding constantly along the plane parallel to the intersection. Should I just check the users velocity in the direction they are facing when they are in a walking state and force an update to bring them back into the correct direction/velocity. Is this cheating?

Thanks!
It's not cheating if it works. You haven't posted many details of your engine, so I can't give very detailed answers on how to solve problems as I don't know what their cause would be. All the answers that I have given you so far were general solutions that should work with any collision detection or rigid body system.

Judging by the way that you were just reflecting the velocity, it sounds like you have put together a fairly simple engine using basic principals. The simpler your engine is, the less general it will be, and the more likely you are to need to "cheat" and put in special code to deal with specific situations.

Keep in mind that cheating can result in more fun gameplay. In relation to the case you mention, think of how you walk: Do you feel yourself accelerating at a constant velocity and having to accelerate in the other direction to turn around? No, because of the effects of friction it feels like you can almost instantanously achieve a good walking speed and turn quickly.
It could be that applying impulses to your character doesn't result in fun, easy movement. Setting the characters velocity when the user pushes left or right (rather than applying impulses) could be easier and provide better control. Most of the old platforms games you played as kid set the velocity when keys were pressed (or translated them by x pixels in one frame, same thing), and they were easy enough to control.
Hi,

Thanks again for your reply. Yes, you are right, my physics engine right now is very rudimentary. I am using it for a role playing game, so I really only need basic collision detection and not even rotational dynamics. Would be nice to put everything in later though. Seems even RPG's are using physics these days (been playing Oblivion... can you tell?!)

I have it working now, thank you for the advice and the great articles. I did the reflection using the friction and bounce modifiers relative to the normal and the plane that is being reflected from. The physics engine then generates a collision event and the game logic then resets the velocity to keep the player walking forward in his intended direction. Seems to work pretty good and because it is using bounding spheres, the character walks around the object (just like in real games! :P). I plan to enhance it to use capsules next and then OBBs.

Thanks!

This topic is closed to new replies.

Advertisement