Basic Collision Issue

Aug 4, 2009 at 2:21 AM
Edited Aug 4, 2009 at 2:23 AM

Hello All

First I'd just like to say I am excited to encorporate Farseer into the project I have been working on. I had a basic collision system set up, but it wasn't as effecient as utilizing an entire physics engine! Alright, here is my problem.

I have a class for collidable objects, a subclass of my standard game objects. The collidableObject should handle creating the body and geometry for each, but for some reason I am having an issue. It started when I first encorporated the bodies and gemoetry, so I remove all of the collidable objects except for one. I think created a simple ball with a body and geom, added it to the physics engine, etc. The collidableObject is static and I am just experimenting dropping the ball. However, the geometry is apparently off from the objects position. Here's my code from the collidableObject class upon initialization

<font size="12">

 

</font>

            physicsBody = BodyFactory.Instance.CreateRectangleBody(texture.Width, texture.Height, 100.0f);
            collisionBox = GeomFactory.Instance.CreateRectangleGeom(physicsBody, texture.Width, texture.Height);
            physicsBody.Position = position;
            physicsBody.IsStatic = true;
           
            Farseer.Physics.Add(physicsBody);
            Farseer.Physics.Add(collisionBox);

If my ASCII art comes out right, this is sort of how the collision seems to be reading

         ___________
     ___|__________|   <--object
    |___________|      <--colliding 

Here's the ball

body = BodyFactory.Instance.CreateCircleBody(50.0f, 100.0f);
body2.Position = new Vector2(300, 400);
geometry2 = GeomFactory.Instance.CreateCircleGeom(body, 50.0f, 20);
 Farseer.Physics.Add(body);
 Farseer.Physics.Add(geometry);
Coordinator
Aug 4, 2009 at 2:47 AM

The position of bodies are relative to the center of the geometries. That means whenever you position a geometry you need to offset it. It is also described here in the manual.

I hope you find Farseer Physics useful. If you have any further questions not already answered in our manual or FAQ feel free to ask on the forums.

Aug 4, 2009 at 4:00 AM

Hmm, alright I tried that, to no avail. I understand what you are saying. I saw that part in the manual, but I misread thinking that it was all taken care of if you used the BodyFactory. Here's what I am trying now instead.

physicsBody = BodyFactory.Instance.CreateRectangleBody(texture.Width, texture.Height, 50.0f);
            collisionBox = GeomFactory.Instance.CreateRectangleGeom(physicsBody, texture.Width, texture.Height, new Vector2(texture.Width/2, texture.Height/2), 0f);

 

The only thing I can get to work is if I draw with an offset. If this is what I have to so, then so be it, I wasn't keen on it though because there are a lot of instances where the physics objects need to be positioned corretly with sprites, so I will have to draw everything with an offset. Maybe I am just not understanding how to offset the geometry to the body.

Coordinator
Aug 4, 2009 at 4:05 AM

Bodies are just a point in space. A single vector that tells the position of the body. When you add a geometry to the body, the centroid (the real center) of the geometry is positioned at the body's position.

When you draw the geometry, you need to give it a origin. The origin will in most cases be the center of the geometry (width/2, height/2), but if you use polygons, you will have to use the centroid of the geometry.
Just save a origin variable in your collidableObject that contains a vector2 of value (width/2, height/2). In your draw method, there is an argument called origin - use the origin variable there. Then you should be all set.

Aug 4, 2009 at 5:12 AM

Alright got it! Although now I came across another problem! Objects are... sinking? I created an array of collidable objects for a floor, I initialize my character a little higher so he drops, and collides with the floor. This works, he definately collides properly. However, after a second he just slowly drops through. I tried just changing the position of one of my floor objects and setting it to not static, it does the same thing. It falls and collides correctly but then sinks through after a second. Is this common? When I was playing around earlier with circles they didn't fall through. I tried changing the gridCellSize, creating each object with vertices and subdividing. Somehow subdividing and changing the gridCellSize makes it worse, it barely collides before sinking though. All of my trouble is most likely that I have been up for way too long, and need sleep :P However, I saw a few other posts in the forums where people had this same issue, but none were resolved.

Coordinator
Aug 4, 2009 at 8:32 PM

I suspect that the grid cell size is the cause of that. You need to give it a smaller value - this will cause the grid cells to become smaller and thus a more precise collision detection. Try giving a really low value and work your way up until you hit a value that causes the problem. Then you simply use a value lower than the one giving you trouble. It is a matter of precision vs performance.

Aug 4, 2009 at 10:37 PM

Alright I'm a little more rested tonight and ready to tackle this again! Alright, I have narrowed the prblem down to being when the geometry is created with a position offset.

collisionBox = GeomFactory.Instance.CreateRectangleGeom(physicsBody, texture.Width, texture.Height);
           
The above works fine, but I have having the same visual bug, meaning I will have to draw all my game objects with an offset in the Draw methods

collisionBox = GeomFactory.Instance.CreateRectangleGeom(physicsBody, texture.Width, texture.Height, new Vector2(texture.Width/2, texture.Height/2), 0f);
           
This draws appropriately, but results in the sinking problem

 

The strange thing it, the geometries are not passing completely through, but falling until the top of each rectangle collides.

      ___________
      |            |
 ____|__________|__   <------- Hit and stops for a second
 |                     |  
 |                     |
 |                     |
 |_________________|



  __________________
 |      |          |    |     <---- drops, and stops here
 |      |________|    |
 |                     |
 |_________________|
Changing the collision grid size has no effect
Coordinator
Aug 4, 2009 at 10:42 PM

You should not offset the geometry. You should offset the drawing.

Take a look at the SimpleSamples on how to draw the geometries correctly. I explained it further up in this discussion.

Aug 4, 2009 at 11:22 PM

Alright, my mistake. I thought when you said "That means whenever you position a geometry you need to offset.." meant to use the overload with the Vector2 offset. Sorry for the confusion, this should not have been such an issue :P