# Jittering due to gravity and restitution

This topic is 1816 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello,

I've been implementing a 3d physics engine using impulse resolution, following this series of tutorials, porting them to 3d:

http://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-core-engine--2778

Now I'm at a state where I've got the basic collision pair generation and resolution (using friction, mass, restitution), as well as gravity and velocity/position integration, no angular velocity yet. Now I'm experiencing some issues under the following scenario:

I've got a sphere with radius 1 and mass 1 eigther falling straigth on to or lying directly on an AABB with infinte mass. Restitution of both these bodies is 0.75, gravity is 10.0, static and dynamic friction is both 0.1 (but it doesn't have any effect here anyway). Now the issue happens when the sphere has los most of its momentum due to gravity, and should lay quitely on the AABB. Instead, it yitters around quite noticable, obviously due to the gravity pulling it down into the box, which pushes the box out further away then it originally was, causing it to fall down again in the next frame, etc... hope you get the idea. Now, this gets effect gets less noticable the more I turn down the restituation, and completely dissappears once it reaches 0.0f, obivously since the sphere will now loose all its momentum instantly as it hits the AABB. But every other value will cause such a noticable yittering.

Without showing any of my code (I checked a hundred times to ensure that there are no typos and its pretty much equivalent to the one from the tutorial algorithm-wise), is there any solution for this problem? I've already read about the problem of sinking bodies due to gravity and that you should use position correction, but doing so didn't help, and it appears to be a utterly different problem anyways. Any ideas? Or let me know if you'd have to see some code in order to help. Thanks!

##### Share on other sites

It sounds like you need to add damping. This is reinforced by your findings with changing the coefficient of restitution. Since both remove energy from the system.

Edited by brucedjones

##### Share on other sites

It sounds like you need to add damping. This is reinforced by your findings with changing the coefficient of restitution. Since both remove energy from the system.

Thanks for your suqqestion, however adding damping didn't remove the jittering issue, even when using a huge damping coefficient (like 0.5f) without accounting for the timestep, there is still some jittering (it isn't even anywhere nearly as restricted as the "normal" velocities are. I'm using damping method 2 from this site:

http://www.digitalrune.com/Support/Blog/tabid/719/EntryId/78/Damping-in-Computer-Games.aspx

which in my code basically looks like this:

for(auto pBody : m_vBodies)
{
// c = 0.5f
pBody->m_vVelocity *= (1.0f - c);
}


Is there anything wrong with this form of damping? If not, any other suggestions what I could do?

##### Share on other sites

The damping you mention seems wrong. It should always apply force along some axis (along the constraint or normal to intersection), not just remove a fraction of all movement per game loop.

The folowing equation will compute the exact force to make your object align with the floor and come to rest in one step:

correction force = - ( object mass / timestep^2 ) * overlap distance along axis * coefficient - ( object mass / timestep ) * velocity along axis * coefficient

If you are dealing with impulses or velocities then the equation should be:

Correction impulse = - ( object mass / timestep ) * overlap distance along axis * coefficient - velocity along axis * coefficient

The coefficient is just a number between 0 and 1 determining how soft / rigid you want it to behave. Setting the coefficients to 1 will do the job in 1 loop, but may also introduce instability if there are several objects interacting at one time. Setting them between 0.5 and 0.05 should work just fine.

Cheers,

Mike

Edited by h4tt3n

##### Share on other sites

The damping you mention seems wrong. It should always apply force along some axis (along the constraint or normal to intersection), not just remove a fraction of all movement per game loop.

The folowing equation will compute the exact force to make your object align with the floor and come to rest in one step:

Thanks for that hint, and I tried to implemented your second correction impulse, but for some reason I'm still not getting the results I expect. When I set the coefficient to 0.5f, the sphere immediately stops when hitting the floor once, with something around 0.25f it will only bounce 2-3 times (instead of 7-10 as it was used to), and after that still jitter a little, and if I choose 0.05f, jittering is still visible, though somewhat reduced. I'm not to sure if I implemented it correctly, so I'd be glad if you could help me out some more regarding that:

Am I right to assume that this correction impulse should go where the collison resolution happens, in detail after I applied the impulse to seperate the two objects? If so, am I also right to assume that this correction impulse should simply be added to the objects velocity afterwards? See my code for example:

//... calculate everything need for the seperation impulse

const math::Vector3 vVelocityA = m_pBodyA->GetInvMass() * vImpulse;
m_pBodyA->m_vVelocity -= vVelocityA;

/********************************************
* Damping
*********************************************/

const float coefficient = 0.25f;
math::Vector3 vCorrectionA = -(m_pBodyA->GetInvMass() * (1.0f / 60.0f)) * m_penetration * m_vNormal * coefficient - vVelocityA * coefficient;
m_pBodyA->m_vVelocity += vCorrectionA;


I explicitely left out the impulse for the second body, since it is of no concern for this example. Does that code, as well as my explanation, look right to you, or is there something that should have been done differently?

##### Share on other sites

Hello Juliean,

Sorry, I wasn't beeing too clear in my explanation. The two coefficients aren't necessarily the same number. The first one is the stiffness coefficient, the secon one the damping coefficient.

correction impulse = - ( object mass / timestep ) * overlap distance along axis * stiffness coefficient - velocity along axis * damping coefficient

or shorthand:

Jc = -(m / dt ) x Ck - v Cd

If you set Ck and Cd to 1.0 the object should stop completely when it hits the floor. If Ck is 1.0 and Cd is 0.0 it should keep bouncing indefinitely.

Cheers,

Mike

##### Share on other sites

Sorry, I wasn't beeing too clear in my explanation. The two coefficients aren't necessarily the same number. The first one is the stiffness coefficient, the secon one the damping coefficient.

Ah, I see, since both were named the same I assumed they where the same variable Now it makes more sense.

But I'm still having some trouble getting some acceptable results. If I set stiffness to 1.0f and damping to 0.5f, the sphere already stops almost instantly. All smaller values, like 0.25f, already reduce the bouncing of the sphere to virtually nothing (from e.g. ~10 meters on first bounce without the daming, to ~2 with 0.25). In addition, even a large value like 0.5f will still leave some jittering, which you notice at least if you stick your face up to the spheres. Everything less does reduce the jitter, but by an amount that still leaves it noticable unless you go to a birds-eye perspective. Do you think there is something wrong with my implementation? I mean, I have found a way to remove the jittering, but it is a little hacky:

void World::IntegrateVelocities(double dt)
{
// TODO: fix for gravities that are set in other directions than straigth down/up the y-axis
const float bias = abs(m_vGravity.y * 0.05f);

for(auto pBody : m_vBodies)
{
if(pBody->GetInvMass() == 0.0f)
continue;

// fixes gravity jittering
// TODO: find out better, less hacky and more physical based solution
if(pBody->m_vVelocity.y > 0.0f)
pBody->m_transform.vPosition += math::Vector3(pBody->m_vVelocity.x, max(0.0f, pBody->m_vVelocity.y - bias), pBody->m_vVelocity.z) * dt;
else if(pBody->m_vVelocity.y < 0.0f)
pBody->m_transform.vPosition += math::Vector3(pBody->m_vVelocity.x, min(0.0f, pBody->m_vVelocity.y + bias), pBody->m_vVelocity.z) * dt;
}
}


What this pretty much does is bias or clamp the velocity along the x-axis by 5% of the gravity on integration, which seems to be the approximate value in which range the bodies jitter around, so that the bodies only begin to move due to gravity after it extents this bias. This works without noticably changing the way the bodies move/bounce, though it does naturally slightly change their positions. Don't get me wrong, I'd much rather have a less-hacky solution, but would you consider this something that is viable in a pyhsics engine (given that it works best so far without altering the simulation by a noticable amount), or do you think this can bite me in the a** later in the progress?

Edited by Juliean

##### Share on other sites

Are you still applying restitution? and are you modifying the position manually after collision has occured?

Assuming your body is spherical and simply falling downward, then the body colliding with the surface is essentially a 1d mass-spring-damper. It is possible to model such a system, and achieve a steady (rest) state. If I were you, I would begin by implementing such a model to see how it should work. This would give you a minimum working example which you can base your collision model on.

Check out wikipedia for reference material.

##### Share on other sites

Are you still applying restitution? and are you modifying the position manually after collision has occured?

Yes, I am applying restitution, in the same amount I used before. I actually found the solution why the article I was reading didn't have the problem, they where calculating a bias much similar than me, and set the restitution to 0.0f if velocity went under a certain amount.

    // Determine if we should perform a resting collision or not
// The idea is if the only thing moving this object is gravity,
// then the collision should be performed without any restitution
if(rv.LenSqr( ) < (dt * gravity).LenSqr( ) + EPSILON)
e = 0.0f;


After going through the even more, I think I've come to the conclusion that damping wouldn't be going to help anyway. From what I understand, dampings main purpose is to reduce the amount of energy of a body over time (very simplified), am I right? Now the problem with the jittering comes from the fact that the small amount of gravity that is applied each frame will push the body a certain amount higher over the body, just by a tiny amount, almost equal to the negative gravity. In the next frame, gravity will drag the body down again, moving it to a slighly different position than it was before. This happens frame by frame, the body pretty much alternates between rising and falling by a very small amount around the contact point of the sphere with the floor. (e.g. in the range of -0.05 to 0.05). Now in my limited understanding of the subject, in order for damping to remove this effect, it would need to be so strong that it would cancel out most of the other forces on the body (pretty much which I am experience with the damping implementation by h4tt3n). Am I right to assume so, or did I miss anything?

Edited by Juliean

##### Share on other sites

Are you still applying restitution? and are you modifying the position manually after collision has occured?

Assuming your body is spherical and simply falling downward, then the body colliding with the surface is essentially a 1d mass-spring-damper. It is possible to model such a system, and achieve a steady (rest) state. If I were you, I would begin by implementing such a model to see how it should work. This would give you a minimum working example which you can base your collision model on.

Check out wikipedia for reference material.

The method I described is such a mass-spring-damper, and it works very well in my simulations. I am using it on force level, not velocity level, but it should react just the same. I think you might get rid of the jittering if you apply gravity as a downward velocity beofre calculating spring forces, then the damper would cancel it out.

Cheers,

Mike

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 9
• 11
• 9
• 9
• ### Forum Statistics

• Total Topics
634134
• Total Posts
3015743
×