Restitution not working.

Topics: User Forum
Jun 28, 2011 at 4:47 AM

I'm creating a projectile that should follow an elliptical trajectory. I've set Restitution because I want the projectile to bounce against the ground, but it doesn't seem to be working.

This is my Projectile class:

    public class Projectile : Entity
    {
        public Projectile(Engine parent, float radius)
            : base(parent)
        {
            body = BodyFactory.CreateCircle(Parent.World, ConvertUnits.ToSimUnits(radius), 1, body);
            body.BodyType = BodyType.Dynamic;
            body.Restitution = 1;
            body.Friction = 1;
            body.Position = ConvertUnits.ToSimUnits(new Vector2(80, 240));
        }

And this is the ground where it should bounce:

    public class Ground : Entity
    {
        public Ground(Engine parent, float width, float height)
            : base(parent)
        {
            body = BodyFactory.CreateBody(Parent.World,
                ConvertUnits.ToSimUnits((float)width),
                ConvertUnits.ToSimUnits((float)height), 0);
            body.BodyType = BodyType.Static;
            body.Position = ConvertUnits.ToSimUnits(new Vector2((float)(width / 2), 465));
            body.Restitution = 1;
            body.Friction = 1;
       }

But the projectile just hits the ground and stays there. My world has gravity but it's very low: new World(new Vector2(0, 0.02f)); I'm using FarseerPhysicsSilverlight.dll version 3.3.1.

Do you see any obvious mistakes in there? Perhaps something I'm missing to initialize.

Thanks

Jun 28, 2011 at 7:54 AM

Just a moment ago, I had the same problem with friction. It turns out both of them are reset when a fixture is assigned to the body. My solution was to set the friction to the fixture, instead of the body (why does the body have a friction property anyway?). You can also set it to the body, but after you've added a fixture.

Jun 28, 2011 at 6:38 PM

I've changed my projectile to this:

            body = BodyFactory.CreateBody(Parent.World);
            body.BodyType = BodyType.Dynamic;
            body.Restitution = 1;
            body.Friction = 1;
            body.Position = ConvertUnits.ToSimUnits(new Vector2(80, 240));

            var circle = FixtureFactory.AttachCircle(ConvertUnits.ToSimUnits(radius), 1, body);
            circle.Restitution = 1;
            circle.Friction = 1;

And ground now looks like this:

            body = BodyFactory.CreateBody(Parent.World);
            body.BodyType = BodyType.Static;
            body.Position = ConvertUnits.ToSimUnits(new Vector2((float)(width / 2), 465));
            body.Restitution = 1;
            body.Friction = 1;
            var rect = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits((float)width), ConvertUnits.ToSimUnits((float)width), 0,
                Vector2.Zero, body);
            rect.Restitution = 1;
            rect.Friction = 1;
            rect = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(10), ConvertUnits.ToSimUnits(1000), 0,
                ConvertUnits.ToSimUnits(new Vector2((float)(-Graphic.ActualWidth / 2), 480 - 1000)), body);

Still the same problem. The ball just touches the ground and follows it along.  Does density has anything to do with Restitution? I've tried setting it to 0 and 1 and doesn't seem to make a difference.

Jun 28, 2011 at 7:28 PM

I guess this should work. Although 1 for restitution isn't huge. 

Density should never be zero as far as I know, that would make a fixture mass-less. Try increase the gravity, decrease friction, check the body's LinearDamping, otherwise download the testbed (from the download page) and see the Restitution Difference Test.

Jun 30, 2011 at 2:59 AM
Edited Jun 30, 2011 at 2:59 AM

I've changed density and friction as you suggested and set restitution to several values up to float.MaxValue but still doesn't work. I've uploaded a minimal test here http://www.megaupload.com/?d=3C41SH87

Hope you can take a look at it and tell me what I'm doing wrong.

Thank you.

Jun 30, 2011 at 3:08 AM

BTW. I don't know how to check the "LinearDamping". Any pointers?

Thanks

Jun 30, 2011 at 4:47 PM

Hi jordos.

Just found the LinearDamping property in Body. It's at zero always. Tried to change it to something else and didn't have any effect or Restitution.

I've downloaded the Testbed XNA but couldn't find the "Restitution Difference Test". Couldn't find it in the repository either. I'm looking at CirclePenetrationTest.cs but I don't see much difference to what I'm doing. Is there anything you can do to help me?

Thanks

Jul 3, 2011 at 4:19 PM

Hi pepecantillo, sorry for replying so late. I looked at your code and although I couldn't run it (some SilverLight thing was missing), I think the problem is that you don't call World.ClearForces(). This is required for a good working simulation. You need to call it right after you call World.Step().

Next, don't set restitution to float.MaxValue. I understand this is for testing, but this will crash your simulation. A restitution of 1 means no energy will be lost, higher means energy will be added on collision. I think you can test best with just setting it to 1. 

Dec 16, 2014 at 8:17 PM
if you circle is jumping to much, increase LinearDamping, decrase if it is not jumping.
set LinearDamping to zero to test if the restitution is working.