no rotation causes penetration :(

Jan 20, 2009 at 1:23 PM

Hi dear friends, i am a beginner..below code of my project works very fine.
There is only a box and a ball with gravitation. when they collide a perfect collision occurs on every pixel with eachother.
However , My Problem is :
  in the code when i replaced bold and underlined "Body2.Rotation" with "0" (why am i doing that ? coz i dont want the box rotate !) ball penetrates the box very badly.
  pls help me to fix that..

  thx in advance..regards,

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Collisions;

namespace FarseerPhysicsTry {
       public class Game1 : Microsoft.Xna.Framework.Game {
        GraphicsDeviceManager graphics;
        ContentManager content;

        //display variables
        SpriteBatch spriteBatch;
        Texture2D ball;
        Texture2D box;

        //declare physics variables
        PhysicsSimulator physicsSimulator;       

        Body Body1;
        Body Body2;

        Geometry Geometry1;
        Geometry Geometry2;

        public Game1() {
            graphics = new GraphicsDeviceManager(this);
            content = new ContentManager(Services);

               protected override void Initialize() {
            IsFixedTimeStep = true;
            TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 10);
            //create the simulator with gravity = 200
            physicsSimulator = new PhysicsSimulator(new Vector2(0,200));

            //create body for ball
            Body1 = BodyFactory.Instance.CreateCircleBody(physicsSimulator, 50, 1);
            //set the body position
            Body1.Position = new Vector2(400, 100);
            //create the geometry for ball
            Geometry1 = GeometryFactory.Instance.CreateCircleGeometry(physicsSimulator, Body1, 50, 100); 

            //create the body for box  and set it's position
            Body2 = BodyFactory.Instance.CreateRectangleBody(physicsSimulator, 190, 190, 1);
            Body2.Position = new Vector2(400, 400);
            //create the geometry for box 
            Geometry2 = GeometryFactory.Instance.CreateRectangleGeometry(physicsSimulator, Body2, 190, 190);


               protected override void LoadGraphicsContent(bool loadAllContent) {
            if (loadAllContent) {
                spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
                ball = content.Load<Texture2D>("ball");
                box = content.Load<Texture2D>("box");


                protected override void UnloadGraphicsContent(bool unloadAllContent) {
            if (unloadAllContent) {


                protected override void Update(GameTime gameTime) {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            if(Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit();

            if (Keyboard.GetState().IsKeyDown(Keys.Left)) Body2.ApplyForce(new Vector2(-400, 0));
            if (Keyboard.GetState().IsKeyDown(Keys.Right)) Body2.ApplyForce(new Vector2(400, 0));
            if (Keyboard.GetState().IsKeyDown(Keys.Up)) Body2.ApplyForce(new Vector2(0, -400));
            if (Keyboard.GetState().IsKeyDown(Keys.Down)) Body2.ApplyForce(new Vector2(0, 400));

            if (Body1.Position.Y>700) Body1.ApplyForce(new Vector2(0,-4000));
            if (Body2.Position.Y>500) Body2.ApplyForce(new Vector2(0,-4000));

            physicsSimulator.Update(gameTime.ElapsedGameTime.Milliseconds * .001f);


           protected override void Draw(GameTime gameTime) {

            spriteBatch.Draw(ball, Body1.Position, null, Color.White, Body1.Rotation, new Vector2(ball.Width / 2, ball.Height / 2), 1, SpriteEffects.None, 0);
            spriteBatch.Draw(box, Body2.Position, null, Color.White, Body2.Rotation, new Vector2(box.Width / 2, box.Height / 2), 1, SpriteEffects.None, 0);

Jan 20, 2009 at 1:30 PM
From what I can see you are using an old version of Farseer Physics. Try the latest version. (It's 2.0.1)
As alternative to setting the rotation to zero on each update, you could use an AngleLimitJoint with the same max and min angle.

Oh, and our samples are a great way to learn Farseer Physics. They have a simple game structure and shows you how to create some common scenarios with Farseer Physics.
Jan 20, 2009 at 2:13 PM
truly; the code is old. it is converted within 2.0.1,so i use 2.0.1. this is important for me genbox, let me ask this : if i recode it from scratch in 2.0.1 does it work well ?
Jan 20, 2009 at 6:30 PM
I have not tried your code yet. I only noticed that your geometries was actually called Geometry and not Geom as it was renamed to in some versions back.

Have you tried the solution with AngleLimitJoints?
Jan 20, 2009 at 7:15 PM
i tried but couldn't figure out how i will use it with min and max angles ... as a matter of fact i need help indeed . dear master;  can u show me according to my code about how i will replace for an alternative way , passing zero value to rotation ?

really appreciate it..

Jan 20, 2009 at 8:10 PM
Sorry Myriac, I have not had a lot of time lately. I took a second look at your code and it seems that you are only drawing the box with no rotation and not changing the rotation of the box itself.
This causes your box to be drawn as not rotation, but behind the screen, it actually is rotating.

To stop your box from rotating is not so hard. You have 2 options as mentioned before:

1. Create an AngleLimitJoint on your box with same max and min angle. You just put this line of code into your Initialize() method just below the line where you create your box body and geometry.

JointFactory.Instance.CreateFixedAngleLimitJoint(physicsSimulator, Body2, 0, 0);

2. Set the body's rotation property on each update (Inside the Update() method) to 0 would have the same affect. You just do it like this:

Body2.Rotation = 0f;

But use the first one if it works for you.

Jan 20, 2009 at 8:40 PM
thank you very much genbox , u r great worked like a charm !

thank you , all i want was this line :)