Strange Polygon Collisions

Jan 4, 2008 at 12:41 AM
I have a Silverlight 1.1 Alpha sample of something I am playing with:

http://www.andybeaulieu.com/silverlight/spritejitter/testpage.html

If you take a peek at the sample, and use the mouse to draw out a shape, it creates a PolygonGeom and Body and it crashes to the ground. But notice the odd behavior (you may have to draw out a few shapes to see it) - the objects generally slide way to the right of the playfield, or sometimes "float" on edge.

I've noticed other posts with issues concerning polygon collisions, and I've tried tweaking PhysicsSimulator.BiasFactor, PhysicsSimulator.AllowedPenetration, and collisionGridCellSize, but I can't seem to get rid of the odd physics. The collisions themselves seem fine and occur where I would expect, but why am I seeing the odd thrashing or floating effect after some collisions?




Coordinator
Jan 4, 2008 at 1:10 AM
Edited Jan 4, 2008 at 1:10 AM
I've seen this before in my own work and I know the cause.

When you create your polygons, the vertices should be relative to the origin then positioned where you want it.

For instance if you draw a triangle at (100,100), (50,200), (150,200) the engine will assume the center of mass of the object is at 0,0.

In your demo, what is happening is the mass of the object is ending up offset from the actual geom. The body with it's mass is at 0,0 while the geom is at the spot where it was drawn. Notice how your objects sort of sway back and forth as though a heavy weight is attached. The objects fall, hit the ground, then the offset weight swings down below the ground and rocks the object.

To avoid this, the vertices in the example above should instead be (0,-50), (-50,50), (50,50) note how the triangle verts are now relative to 0,0. Then you can set the position of the body to get it where you want it.

This is actually something I'm going to address soon. I will be adding some additional overloads to the BodyFactory and GeomFactory to automatically calculate the centroid of the verts no matter where they are then do some math to calculate what the verts would be if the centroid of the verts were translated to the origin. I'll then counter adjust the position so the body and geom end up where you would expect.

For now you will need to do something similar your self. I think there is a CalculateCentroid (or something similar) in the vertice class.

Another thing you should do is use the CalculateMomentOfInertia, also in the vertice class I think, to calc a good moment of inertia for your bodies. I plan to add a new overload to CreateBody that will take a set of verts. I'll use these verts to calc the MOI.

Hope this helps. Let me know if you still have trouble. I'll try to make the changes to the factory objects to address this issue over the next week or so.

btw, cool demo!
Jan 4, 2008 at 2:16 AM
Awesome, that really made a difference - and such a simple change!

You can check out the diff if interested (probably will need to do a refresh in your browser) - http://www.andybeaulieu.com/silverlight/spritejitter/testpage.html

I'm hoping to clean this demo up soon and post it up on my blog.
Jan 4, 2008 at 4:20 AM
Looks like it's still doing weird stuff to me.
Jan 4, 2008 at 11:47 AM

Yes - it is still doing weird stuff, you're right. I just got excited because it was an order of magnitude better :)

Now it seems especially bad when drawing with curved objects like circles. Flat objects like rectangles and triangles seem ok.

Any other ideas?
Coordinator
Jan 4, 2008 at 4:30 PM
I haven't run the new stuff yet as i'm at work.

Can you write some debug view code to show the vertices of the geom and the position of the body? I have a feeling they are not in alignment.

Are you sure the silverlight shape is aligned properly with the body/geom? The center point of the silverlight path needs to be aligned with the body position.

If you can get a good view of the geom and body with a debug view you should be able to see the problem.

-Jeff

Jan 4, 2008 at 8:18 PM
Ok, I "think" I have it now. You were right - depending on how the polygon was drawn, it could have its body object off center.

I added some debug elements showing the center of the body and position, if you use the Debug button:

http://www.andybeaulieu.com/silverlight/spritejitter/testpage.html

So I think this is as good as it gets as far as polygon collisions and physics with Farseer, right? (I am using a generic CreateBody function and passing in vertices.CalculateMomentOfInteria as well)
Jan 4, 2008 at 10:05 PM
So, is the problem fixed now? It's a little hard to tell, possibly because the friction on the bodies due to the ground is so low. They just keep sliding sideways until they hit something.
Coordinator
Jan 5, 2008 at 9:36 AM
Edited Jan 5, 2008 at 9:44 AM
Looks good, but the bodies seem to dance around more than they should.

I think michael brooks is right. You need to add a bit of friction between the bodies to keep them from sliding around so much.

I'm sure there are some other tweaks you can make but for the little bit I looked at it it seemed pretty good.

Is there something you're noticeing that seems not quite right? Is so I can take a closer look.

-Jeff
Jan 5, 2008 at 11:48 AM
Guys, thanks for the feedback, it is really appreciated!

I just added some FrictionCoefficient and RestitutionCoefficient to the ground and walls, and it looks like that took care of the sliding effect (you should see a new comment in the header to that effect)

http://www.andybeaulieu.com/silverlight/spritejitter/testpage.html

But please let me know if you have any other comments or suggestions!

Jan 5, 2008 at 4:34 PM
Looks good.

I noticed a different problem that may or may not be a bug with the physics engine. I was creating semicircles by drawing half a circle and letting the program complete the flat face. That's fine, but if you draw a large semicircle this way that lands with the flat side up and then draw a smaller one above it with the flat side down, they slide together until the smaller one reaches the edge of the larger, and then they fall into each other. Maybe this comes from the perfectly sharp corner that the shape completer no doubt creates.

Another bug: if you draw an object with no volume (like a perfectly straight line, or a dot), the program freezes. You are still permitted to draw objects, but the physics stops updating.
Coordinator
Jan 5, 2008 at 5:52 PM
Looks good, but I confirmed the same thing Michael mentioned.

I think the problem might be that you are not adding any vertices on the straight line that closes the shape. Fareer's collision detection works best if you add a few verts even on straight edges.

Also, sharp edges usually require smaller grid sizes but I'm assuming you already figured that out.

Anyway, it's looking very good. Can't wait to see where you are going with it.

-jeff
Jan 23, 2008 at 11:37 AM
Edited Jan 23, 2008 at 11:38 AM
Guys, thanks again for the help in troubleshooting.

For anyone needing a how-to on polygon collisions (with Farseer and Silverligt), I finally got the blog post up at http://www.andybeaulieu.com/Home/tabid/67/EntryID/91/Default.aspx