Search code examples
c#farseer

Body not rotating to face downward with gravity


I have a rectangle body that is being fired from a canon at a 45degree Angle. The body is also rotated up at a 45 degree angle and I have set the mass to be at the front of the body.

The body goes up in the air fine, however, as the body comes back down to earth it does not rotate. Is there a way so that the mass side comes down first?

My real world example is, throwing a tennis ball with a string attached into the air. Currently the string doesn't fall behind the ball when gravity comes into affect.

Here is my 'ball'

Body = BodyFactory.CreateRectangle(world, ConvertUnits.ToSimUnits(texture.Width), ConvertUnits.ToSimUnits(texture.Height),100f, postition, this);
Body.Mass = 1;
Body.LocalCenter = new Vector2(ConvertUnits.ToSimUnits(Texture.Width), ConvertUnits.ToSimUnits(Texture.Height / 2));
Body.UserData = this;
Body.BodyType = BodyType.Dynamic;
Body.CollisionCategories = Category.All;
Body.CollidesWith = Category.All;
Body.IgnoreGravity = false;
float ang = BarrelJoint.JointAngle;
Body.Rotation = ang;

Then I do this to fire it:

Body.ApplyLinearImpulse(new Vector2((float)Math.Cos(ang) * 100, (float)Math.Sin(ang) * 100));

I am guessing there is some setting or calculation I am forgetting.


Solution

  • For anyone who will read this in the future, I did work it out.

    I realized that the velocity would be changing in a similar fashion as I wanted the rotation to change. So I based the rotation on the velocity, the more gravity pulls down the more the object will turn to face down.

    In my objects update class, I put the following (note: potentially bad maths)

    public override void Update(GameTime gameTime)
        {
            Vector2 velocity = Body.LinearVelocity;
    
            float radians = (float)(Math.Atan2(-velocity.X, velocity.Y) + Math.PI/2.0);
    
            Body.Rotation = radians;
    
            base.Update(gameTime);
        }
    

    And ta da we have a rotating object.