Complex bodies pass through other bodies

  ... the Physics Box2D Extension for AndEngine.

Complex bodies pass through other bodies

Postby bobdebouwer » Mon Apr 23, 2012 12:13 pm

I seem to be having a problem where a sprite consisting of multiple bodies seems to pass through other object (static and dynamic), it does get affected by gravity though.
Any help would be appreciated.
The following is the code I use to create a cross consisting of 5 bodies (top,right,bottom,left and mid).

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.                                 gearCount++;
  2.                                 Vector2[] topVertices = {
  3.                                         new Vector2(-20,62),
  4.                                         new Vector2(20,62),
  5.                                         new Vector2(20,20),
  6.                                         new Vector2(-20,20),
  7.                                 };
  8.                                 Vector2[] rightVertices = {
  9.                                         new Vector2(20,20),
  10.                                         new Vector2(62,20),
  11.                                         new Vector2(62,-20),
  12.                                         new Vector2(20,-20),
  13.                                 };
  14.                                 Vector2[] bottomVertices = {
  15.                                         new Vector2(-20,-20),
  16.                                         new Vector2(20,-20),
  17.                                         new Vector2(20,-62),
  18.                                         new Vector2(-20,-62),
  19.                                 };
  20.                                 Vector2[] leftVertices = {
  21.                                         new Vector2(-62,20),
  22.                                         new Vector2(-20,20),
  23.                                         new Vector2(-20,-20),
  24.                                         new Vector2(-62,-20),
  25.                                 };
  26.                                 Vector2[] midVertices = {
  27.                                         new Vector2(-20,20),
  28.                                         new Vector2(20,20),
  29.                                         new Vector2(20,-20),
  30.                                         new Vector2(-20,-20),
  31.                                 };
  32.  
  33.                         entity = new Sprite(pX,pY,pWidth,pHeight,this.gear125_125);
  34.                         entity.setUserData("gear"+gearCount);
  35.                         entity.setRotation(pRotation);
  36.                         Body top = null;
  37.                         Body left = null;
  38.                         Body bottom = null;
  39.                         Body right = null;
  40.                         Body mid = null;
  41.                        
  42.                         top = PhysicsFactory.createPolygonBody(mPhysicsWorld, entity, topVertices, BodyType.DynamicBody, GEAR_NORMAL_FIXTURE_DEF);
  43.                         top.setUserData("gear"+gearCount);
  44.                     mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(entity, top, true, true));
  45.                    
  46.                     right  = PhysicsFactory.createPolygonBody(mPhysicsWorld, entity, rightVertices, BodyType.DynamicBody, GEAR_NORMAL_FIXTURE_DEF);
  47.                     right .setUserData("gear"+gearCount);
  48.                     mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(entity, right , true, true));
  49.                    
  50.                     bottom = PhysicsFactory.createPolygonBody(mPhysicsWorld, entity, bottomVertices, BodyType.DynamicBody, GEAR_NORMAL_FIXTURE_DEF);
  51.                     bottom.setUserData("gear"+gearCount);
  52.                     mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(entity, bottom, true, true));
  53.                    
  54.                     left = PhysicsFactory.createPolygonBody(mPhysicsWorld, entity, leftVertices, BodyType.DynamicBody, GEAR_NORMAL_FIXTURE_DEF);
  55.                     left.setUserData("gear"+gearCount);
  56.                     mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(entity, left, true, true));
  57.                    
  58.                     mid = PhysicsFactory.createPolygonBody(mPhysicsWorld, entity, midVertices, BodyType.DynamicBody, GEAR_NORMAL_FIXTURE_DEF);
  59.                     mid.setUserData("gear"+gearCount);
  60.                     mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(entity, mid, true, true));
  61.                    
  62.                     try{
  63.                     pScene.attachChild(entity);
  64.                    
  65.                     }
  66.                     catch (NullPointerException e) {
  67.                                                 e.printStackTrace();
  68.                                         }
  69.  
Parsed in 0.043 seconds, using GeSHi 1.0.8.4
bobdebouwer
 
Posts: 11
Joined: Sun Apr 22, 2012 7:14 pm

Re: Complex bodies pass through other bodies

Postby Primadawn » Tue Apr 24, 2012 2:40 am

You have three problems:
1. You have to divide all the coordinates by PIXELS_PER_METER (default is 32)
2. You can't set multiple bodies to one sprite, you need to create one complex body. (I can pull out some code for you that does it if you'd like)
3. The direction should go clock-wise because the y axis is upside down.

Also, you can create this body from 3 vertices, you don't need 5. (P2M = 32.0f)
1. (-62 / P2M, -20 / P2M) (62 / P2M, -20 / P2M) (62 / P2M, 20 / P2M) (-62, 20 / P2M)
2. (-20 / P2M, -62 / P2M) (20 / P2M, -62 / P2M) (20 / P2M, -20 / P2M) (-20 / P2M, -20 / P2M)
3. (-20 / P2M, 20 / P2M) (20 / P2M, 20 / P2M) (20 / P2M, 62 / P2M) (-20 / P2M, 62 / P2M)
Last edited by Primadawn on Thu Apr 26, 2012 1:32 am, edited 1 time in total.
Primadawn
 
Posts: 414
Joined: Fri Sep 23, 2011 3:28 am

Re: Complex bodies pass through other bodies

Postby bobdebouwer » Tue Apr 24, 2012 10:39 am

Primadawn wrote:You have two problems: (possibly 3)
1. You have to divide all the coordinates by PIXELS_PER_METER (default is 32)
2. You can't set multiple bodies to one sprite, you need to create one complex body. (I can pull out some code for you that does it if you'd like)
3. I think the direction should go clock-wise because the y axis is upside down (I'll verify it later)

Also, you can create this body from 3 vertices, you don't need 5. (P2M = 32.0f)
1. (-62 / P2M, -20 / P2M) (62 / P2M, -20 / P2M) (62 / P2M, 20 / P2M) (-62, 20 / P2M)
2. (-20 / P2M, -62 / P2M) (20 / P2M, -62 / P2M) (20 / P2M, -20 / P2M) (-20 / P2M, -20 / P2M)
3. (-20 / P2M, 20 / P2M) (20 / P2M, 20 / P2M) (20 / P2M, 62 / P2M) (-20 / P2M, 62 / P2M)

An example of a complex body would be helpful.
Why do you need to divide by P2M? I didn't do that with normal bodies (less than 8 vertices) and they seem to work fine.
bobdebouwer
 
Posts: 11
Joined: Sun Apr 22, 2012 7:14 pm

Re: Complex bodies pass through other bodies

Postby OzLark » Tue Apr 24, 2012 12:05 pm

bobdebouwer wrote:Why do you need to divide by P2M? I didn't do that with normal bodies (less than 8 vertices) and they seem to work fine.


Box2d works in meters whereas AE works in pixels (taken from http://code.google.com/p/box2d/wiki/FAQ ):

What units does Box2D use?
Box2D is tuned for meters-kilograms-seconds (MKS). Your moving objects should be between 0.1 - 10 meters. Do not use pixels as units! You will get a jittery simulation.

How do I convert pixels to meters?
Suppose you have a sprite for a character that is 100x100 pixels. You decide to use a scaling factor that is 0.01. This will make the character physics box 1m x 1m. So go make a physics box that is 1x1. Now suppose the character starts out at pixel coordinate (345,679). So position the physics box at (3.45,6.79). Now simulate the physics world. Suppose the character physics box moves to (2.31,4.98), so move your character sprite to pixel coordinates (231,498). Now the only tricky part is choosing a scaling factor. This really depends on your game. You should try to get your moving objects in the range 0.1 - 10 meters, with 1 meter being the sweet spot.
Did this post help you? Feel free to return the gesture by downloading Ninja Bees, creating a level (or more) and sharing it to the Ninja Bees website!

Ninja Bees - Our latest Android game, check it out on Google Play (free) or paid with no ads
OzLark
 
Posts: 1130
Joined: Sun Feb 05, 2012 3:19 am

Re: Complex bodies pass through other bodies

Postby Primadawn » Tue Apr 24, 2012 1:07 pm

An example of a complex body would be helpful.
Why do you need to divide by P2M? I didn't do that with normal bodies (less than 8 vertices) and they seem to work fine.

When you create the body with PhysicsFactory.createBoxBody(...), the PhysicsFactory divides by P2M for you.
Here is an example of a function that creates a complex body (not tested):
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public static Body createComplexBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio, Vector2[][] vertices)
  2. {
  3.         final BodyDef bodyDef = new BodyDef();
  4.         bodyDef.type = pBodyType; // Edited (was static)
  5.  
  6.         final float[] sceneCenterCoordinates = pIShape.getSceneCenterCoordinates();
  7.         bodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / PIXEL_TO_METER_RATIO_DEFAULT;
  8.         bodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / PIXEL_TO_METER_RATIO_DEFAULT;
  9.  
  10.         final Body body = pPhysicsWorld.createBody(bodyDef);
  11.  
  12.         PolygonShape polyShape = new PolygonShape();
  13.         pFixtureDef.shape = polyShape;
  14.        
  15.         final int length = vertices.length;
  16.         for (int i = 0; i < length; i++)
  17.         {
  18.                 polyShape.set(vertices[i]);
  19.                 body.createFixture(pFixtureDef);
  20.         }
  21.         polyShape.dispose();
  22.  
  23.         return body;
  24. }
Parsed in 0.034 seconds, using GeSHi 1.0.8.4

You can create the vertices like this:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. final float P2M = PIXEL_TO_METER_RATIO_DEFAULT;
  2. Vector2[][] vertices1 =
  3. {
  4.   {
  5.     new Vector2(-62 / P2M, -20 / P2M),
  6.     new Vector2(62 / P2M, -20 / P2M),
  7.     new Vector2(62 / P2M, 20 / P2M),
  8.     new Vector2(-62 / P2M, 20 / P2M)
  9.   },
  10.   {
  11.     new Vector2(-20 / P2M, -62 / P2M),
  12.     new Vector2(20 / P2M, -62 / P2M),
  13.     new Vector2(20 / P2M, -20 / P2M),
  14.     new Vector2(-20 / P2M, -20 / P2M)
  15.   },
  16.   {
  17.     new Vector2(-20 / P2M, 20 / P2M),
  18.     new Vector2(20 / P2M, 20 / P2M),
  19.     new Vector2(20 / P2M, 62 / P2M),
  20.     new Vector2(-20 / P2M, 62 / P2M),
  21.   }
  22. };
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
Last edited by Primadawn on Thu Apr 26, 2012 1:34 am, edited 1 time in total.
Primadawn
 
Posts: 414
Joined: Fri Sep 23, 2011 3:28 am

Re: Complex bodies pass through other bodies

Postby bobdebouwer » Wed Apr 25, 2012 11:26 pm

I tried out your code without much luck I'm afraid.
When changing the bodytype to either static or kinetic, other objects seem to get glued to the complex body.
By this I mean that when another object touches the cross (no matter where) it gets stuck at the point where they touch.
Changing the bodytype to dynamic still seems to let objects move through it.
The shape of the body does seem to be correct (a cross in this case).
Any ideas?
And thanks, you guys have been a big help already .
bobdebouwer
 
Posts: 11
Joined: Sun Apr 22, 2012 7:14 pm

Re: Complex bodies pass through other bodies

Postby Primadawn » Thu Apr 26, 2012 12:31 am

Can you show your code?
Primadawn
 
Posts: 414
Joined: Fri Sep 23, 2011 3:28 am

Re: Complex bodies pass through other bodies

Postby bobdebouwer » Thu Apr 26, 2012 9:45 am

Primadawn wrote:Can you show your code?




Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. final FixtureDef GEAR_NORMAL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(20, 0, 0.5f);
  2.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. float p2m = PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
  2.                                 gearCount++;
  3.                                 Vector2[][] vertices =
  4.                                         {
  5.                                 new Vector2[] {
  6.                                         new Vector2(-20/p2m,62.5f/p2m),
  7.                                         new Vector2(20/p2m,62.5f/p2m),
  8.                                         new Vector2(20/p2m,20/p2m),
  9.                                         new Vector2(-20/p2m,20/p2m),
  10.                                 },
  11.                                 new Vector2[] {
  12.                                         new Vector2(20/p2m,20/p2m),
  13.                                         new Vector2(62.5f/p2m,20/p2m),
  14.                                         new Vector2(62.5f/p2m,-20/p2m),
  15.                                         new Vector2(20/p2m,-20/p2m),
  16.                                 },
  17.                                 new Vector2[] {
  18.                                         new Vector2(-20/p2m,-20/p2m),
  19.                                         new Vector2(20/p2m,-20/p2m),
  20.                                         new Vector2(20/p2m,-62.5f/p2m),
  21.                                         new Vector2(-20/p2m,-62.5f/p2m),
  22.                                 },
  23.                                 new Vector2[] {
  24.                                         new Vector2(-62.5f/p2m,20/p2m),
  25.                                         new Vector2(-20/p2m,20/p2m),
  26.                                         new Vector2(-20/p2m,-20/p2m),
  27.                                         new Vector2(-62.5f/p2m,-20/p2m),
  28.                                 },
  29.                                 new Vector2[] {
  30.                                         new Vector2(-20/p2m,20/p2m),
  31.                                         new Vector2(20/p2m,20/p2m),
  32.                                         new Vector2(20/p2m,-20/p2m),
  33.                                         new Vector2(-20/p2m,-20/p2m),
  34.                                 },
  35.                                         };
  36.  
  37.                         entity = new Sprite(pX,pY,pWidth,pHeight,this.gear125_125);
  38.                         entity.setUserData("gear"+gearCount);
  39.                         entity.setRotation(pRotation);
  40.                         entityBody = ShapeHelper.createComplexBody(pPhysicsworld, entity, convertToBodyType(pBodyType), GEAR_NORMAL_FIXTURE_DEF,p2m, vertices);                        
  41.                    
  42.                     try{
  43.                     pScene.attachChild(entity);
  44.                     pPhysicsworld.registerPhysicsConnector(new PhysicsConnector(entity, entityBody, true, true));
  45.                     }
  46.                     catch (NullPointerException e) {
  47.                                                 e.printStackTrace();
  48.                                         }
  49.  
Parsed in 0.043 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.     public static Body createComplexBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio, Vector2[][] vertices)
  2.     {
  3.             final BodyDef bodyDef = new BodyDef();
  4.             bodyDef.type = pBodyType;
  5.      
  6.             final float[] sceneCenterCoordinates = pIShape.getSceneCenterCoordinates();
  7.             bodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / PIXEL_TO_METER_RATIO_DEFAULT;
  8.             bodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / PIXEL_TO_METER_RATIO_DEFAULT;
  9.            
  10.             final Body body = pPhysicsWorld.createBody(bodyDef);
  11.      
  12.             PolygonShape polyShape = new PolygonShape();
  13.             pFixtureDef.shape = polyShape;
  14.            
  15.             final int length = vertices.length;
  16.             for (int i = 0; i < length; i++)
  17.             {
  18.                     polyShape.set(vertices[i]);
  19.                     body.createFixture(pFixtureDef);
  20.             }
  21.             polyShape.dispose();
  22.      
  23.             return body;
  24.     }
  25.  
Parsed in 0.040 seconds, using GeSHi 1.0.8.4
bobdebouwer
 
Posts: 11
Joined: Sun Apr 22, 2012 7:14 pm

Re: Complex bodies pass through other bodies

Postby Primadawn » Thu Apr 26, 2012 11:04 am

Like I said in point 3 of my first post, the vertices have to be created in a clock-wise direction!
Yours are anti-clock-wise.
Use the vertices I gave in the code example, they will do exactly what you want.
Primadawn
 
Posts: 414
Joined: Fri Sep 23, 2011 3:28 am

Re: Complex bodies pass through other bodies

Postby bobdebouwer » Thu Apr 26, 2012 11:45 am

Primadawn wrote:Like I said in point 3 of my first post, the vertices have to be created in a clock-wise direction!
Yours are anti-clock-wise.
Use the vertices I gave in the code example, they will do exactly what you want.

Yours do indeed work.
However on a side note : your vertices are anti-clockwise and mine are clockwise, which is the opposite of what you said.
Thanks for the help guys!
bobdebouwer
 
Posts: 11
Joined: Sun Apr 22, 2012 7:14 pm

Next

Return to Physics Box2D

Who is online

Users browsing this forum: No registered users and 6 guests