Getting an object to roll/slide

Started by
11 comments, last by Boov 11 years, 8 months ago
Hello all of gamedev, I've visited this wonderful site countless times, I've finally signed up because I've hit a problem.
I'm writing a basic physics engine in C++ using SDL, this project is mainly for the learning experience as I'm told using an existing physics engine is always a better option for games.


At the moment all I've got are collision planes (lines), and several particles. Gravity, collision detection, and the reflection vector all work fine. But here's the problem, each particle currently loses half the energy after a bounce. So you can imagine what happens when you try and slide a particle down a slope, the ball bounces down the slope (instead of sliding down), continues to lose energy, and eventually comes to a halt.
I'm not sure how well I've explained myself, so a picture can't hurt.
diagrame.png

Any suggestions/solutions are much appreciated, thanks.
Advertisement
I think you have a good point about bouncing vs rolling. Ideally even when bouncing, if the bounce direction is at an angle to the surface a component should turn into rotational velocity. Eventually the bounce should subside and the main component should be the roll (which is not reduced by further bounce collisions on the same slope).

However one question does come to mind: Why does your ball stop? Gravity should still be applying a force while on the slope. Unless your code is effectively performing very small very fast bounces when in contact with a surface. You may want to check that gravity is applied correctly on a slope and that bounces are turned off when the bounce height/time goes under a threshhold.
My best bet is that the ball get encroached with the plane. Further sweeps therefore hit the plane itself (in case you're sweeping) and thus the ball is locked in place. I've had a few issues with that myself.
How do you evaluate restitution?

Previously "Krohm"


However one question does come to mind: Why does your ball stop? Gravity should still be applying a force while on the slope. Unless your code is effectively performing very small very fast bounces when in contact with a surface. You may want to check that gravity is applied correctly on a slope and that bounces are turned off when the bounce height/time goes under a threshhold.


The ball stops because of what you described. The velocity keeps getting smaller and smaller after every bounce (never actually reaching zero), but it becomes so small that it stops. I never even thought about "turning bounces off".

Thanks for the reply, I'm also going to have a play around in the main loop, maybe I have something in the wrong order.
When the velocity component towards the collision surface becomes too low you could just make it touch the surface (or slightly further to avoid rounding-based penetration) and zero the velocity component in the direction of the collision. One note, when bouncing do remember to only apply damping to the motion component perpendicular to the collision surface. The motion component in the direction of roll should have remained untouched apart from perhaps rounding errors.
As jefferytitan notes, you want to have a tolerance that is the cutoff point where you set it to zero. Some energy is lost on impact to friction, etc.

One note, when bouncing do remember to only apply damping to the motion component perpendicular to the collision surface.

Thanks for the reply. This is basically what I'm doing for a collision (simplified)...

if (distance <= 0)
{
vector reflection = reflectionVector();
reflection.x = reflection.x * 0.5;
reflection.y = reflection.y * 0.5;
}

I do this for every collision. Is this wrong? If so, how do I work out which component to dampen more? For some reason I presumed the x and y components both decreased proportionally.
I assume for the reflection vector you just treat it like a light reflecting in a mirror. That's not correct. What you want to do is split the un-reflected vector into two components: parallel to the surface and perpendicular to the surface. Reflect and apply damping to the perpendicular component, keep the parallel component. The pseudo-code would be something like the below:

[source lang="plain"]if (distance <= 0)
{
vector parallel = dot(surfaceNormal, velocity) * surfaceNormal;
vector perpendicular = velocity - parallel;
vector reflection = parallel - perpendicular * damping;
}[/source]

I assume for the reflection vector you just treat it like a light reflecting in a mirror. That's not correct. What you want to do is split the un-reflected vector into two components: parallel to the surface and perpendicular to the surface. Reflect and apply damping to the perpendicular component, keep the parallel component. The pseudo-code would be something like the below:

[source lang="plain"]if (distance <= 0)
{
vector parallel = dot(surfaceNormal, velocity) * surfaceNormal;
vector perpendicular = velocity - parallel;
vector reflection = parallel - perpendicular * damping;
}[/source]


Many thanks for your reply, I now understand why the ball was stopping. I've fixed my reflection based on your code snippet, bouncing now works correctly, and in turn it has fixed the problem of rolling/sliding!
Cheers!
Hello Boov,

I've attached a small physics doodle with windows .exe file and source code that implements ball-to-wall and ball-to-ball collision with static and dynamic friction. It's written in FreeBASIC. All the equations you're looking for are in there, but I don't know how easy they are to read. Ask if you have questions.

Warning: playing with the attached doodle is really addctive :-)

Cheers,
Mike

This topic is closed to new replies.

Advertisement