Box2d, collisions and how it fails sometimes.

Before I begin, I will let you know I have read extensively box2d manual, I utilize every API in Corona for physics and I have looked at every post regarding this issue, including “resolutions to most common physics issues”

If you are lazy, I created video at bottom, and also what I need :slight_smile:
I’ve read the following

general information about bodies

http://developer.anscamobile.com/content/game-edition-physics-bodies#physics.addBody

more detailed information

http://developer.anscamobile.com/content/game-edition-box2d-physics-engine

note for box2d users

http://developer.anscamobile.com/content/game-edition-box2d-physics-engine#A_note_for_current_Box2D_users

corona sdk collision detection

http://developer.anscamobile.com/content/game-edition-collision-detection

The problem I face is I think A common one, but seems to be one of those issues I have not seen one person solve completely, or at least to a point of where its acceptable.
HEre is the scenario, I’m not providing code at this point, as the issue is pretty easy to describe.

The problem is this:
Lets say I have a long rectangle, which is “static”.
Now, I spawn a ball on top and let it fall onto the object. The ball will bounce off the rectangle and will not even get anywhere close to going partially through the object.
Now, if I have that same rectangle in place and it’s welded to a couple of anchor points and the rectangle is “dynamic” and the rectangle is NOT moving AND I let the ball fall onto the rectangle the ball will partially penetrate the rectangle.
What gets me is how Box2d treats a dynamic object that isn’t moving… it’s just ODD.
That’s scenario 1, now we have scenario 2:
Same rectangle, but now it’s a draggable. I could use it to drag the rectangle around to bounce the ball around have fun etc.
The ball would sometimes penetrate the rectangle. Sometimes the ball would just go through it, and it was like the rectangle wasn’t even considered in the first place. It’s like sometimes the box2d engine forgets what it’s doing and just allows the ball to pass through.
So I said ok, I’ll go to battle on this thing! Here is what I tried

physics.setPositionIterations(128)
physics.setVelocityIterations(128)
physics.setDrawMode( “normal”)
physics.setScale(60 )

body.angularDamping
body.linearDamping
body.angularVelocity
body:setLinearVelocity
body.isBullet = true
body.isBodyActive
body.isAwake
body.isSleepingAllowed
body:getLinearVelocity( )
body:resetMassData( )

I’ve played with those numbers, and on iterations I’ve done 0 through 5000! It seems above 128 to 200 the effectiveness fades with a sort of heavy performance hit.

The scale, I’ve been up and down from 0 to a 1000, it doesn’t seem to matter. I’ve tried combinations of things. This has been going on for at least 2 months.

So then, iNSERTCODE on twitter reached out to me and pointed me to this:

http://www.gamedev.net/blog/1350/entry-2253939-intelligent-2d-collision-and-pixel-perfect-precision/
This is a pretty interesting read. The problem I have is this is I think for cocos2d or something, which me being a coding noob, I can’t decipher it. I get the logic, but the code usually tells more than what’s being said. I was wondering, anyone want to take a stab at this and see if this would be applicable for Corona SDK and translate it to Corona SDK.
I think this would be helpful to everyone who has this problem, right now It’s the #1 thing preventing me from releasing. Character going through walls and off screen is a big big bug, which I can’t release it that way. So basically, I’m spinning my wheels trying to figure this out.
If someone really wants sample code, I could whip something up. But since this is more of an advanced topic…ok I changed my mind lol. Here is some sample code

  
 local physics = require "physics"  
  
 --physics.setGravity(0, 80) -- set this down at the bottom!!  
 physics.setPositionIterations(128)  
 physics.setVelocityIterations(128)   
 physics.setDrawMode( "hybrid")  
 physics.setScale(30)  
 physics.start(true)  
  
 --shorcut variables to call the content width and height  
 local \_W = display.contentWidth  
 local \_H = display.contentHeight   
  
local ball = display.newCircle (\_W/2 -30, \_H/2-300, 11)  
physics.addBody( ball, { density=.01, friction=.50, bounce=0.01, radius=11} )  
ball.linearDamping = 0  
ball.isBullet = true  
ball:setFillColor (30,144,255)  
ball.alpha = 1  
  
 local Lrect = display.newRect (3,20, 20, \_H -20)  
physics.addBody( Lrect, "static")  
Lrect.alpha = 0  
  
local Rrect = display.newRect (747,20, 20, \_H-18)  
physics.addBody( Rrect, "static")  
Rrect.alpha = 0  
  
local Trect = display.newRect (\_W/2 -385,0, \_W+10, 20)  
physics.addBody( Trect, "static")  
Trect.alpha = 0  
  
local Brect = display.newRect (\_W/2 -400,1005, \_W, 20)  
physics.addBody( Brect, "static")  
Brect.alpha = 0  
  
local platform = display.newRect (\_W/2,\_H/2,200,20)  
physics.addBody( platform, "static")  
platform.isFixedRotation = true  
platform.alpha = 1  
local ground = display.newRect (0, \_H/2+200,800,20)  
ground.isFixedRotation = true  
physics.addBody(ground, "static")  
  
local function dragBody( event )  
 local body = event.target  
 local phase = event.phase  
 local stage = display.getCurrentStage()  
  
 if "began" == phase then  
 stage:setFocus( body, event.id )  
 body.isFocus = true  
 --Change body to dynamic while we are moving the maze around  
 event.target.bodyType = "dynamic"  
  
 -- Create a temporary touch joint and store it in the object for later reference  
 body.tempJoint = physics.newJoint( "touch", body, event.x, event.y )  
   
 elseif body.isFocus then  
 if "moved" == phase then  
  
 -- Update the joint to track the touch  
 body.tempJoint:setTarget( event.x, event.y )  
   
 elseif "ended" == phase or "cancelled" == phase then  
 stage:setFocus( body, nil )  
 body.isFocus = false  
 event.target:setLinearVelocity( 0, 0 )  
 event.target.angularVelocity = 0  
  
 --After the event ends, change body back to static.   
 --event.target.bodyType = "static"  
  
 -- Remove the joint when the touch ends   
 body.tempJoint:removeSelf()  
  
 end  
 end  
   
 -- Stop further propagation of touch event  
 return true  
end  
platform:addEventListener( "touch", dragBody )   

Oh and if that is too much for you, here I created a video of it as well :slight_smile:
http://www.youtube.com/watch?v=KwmocWSUojQ&feature=youtube_gdata_player
In the video , I make a change on the iterations and go to 512, almost instantly I get the same issue. Lol

[import]uid: 61600 topic_id: 19839 reply_id: 319839[/import]

In config.lua are you using 30 or 60 fps?

Jay [import]uid: 9440 topic_id: 19839 reply_id: 76972[/import]

I have the same problem in my game when you drag basket fast:

http://itunes.apple.com/us/app/eggz-saver/id480545649?l=pl&ls=1&mt=8

(game is free right now).

It happens on Corona simulator, Xcode simulator and on device with 30 and 60fps.

Corona use quite old Box2D implementation.

[import]uid: 12704 topic_id: 19839 reply_id: 76986[/import]

I think Corona can only update things as quickly as 60 times per second, so could you be moving your objects faster than that? In other words, you whip one object past another in less than 1/60 of a second and that’s how it is able to slip past.

Yes? No? Not sure if that’s technically possible but it sounds good to me. :slight_smile:

Could you test it programmatically so you can see if the movement of one object at a certain speed is what triggers the problem?

Just program that test case in the video to have the bar smack that ball every second for a hundred times or so, every tenth second for anther hundred, every twentieth second, etc. Whenit switches have it print the speed to the terminal and just watch and see if the problem happens at the same speed threshold each time.

Something to think about?

Jay [import]uid: 9440 topic_id: 19839 reply_id: 76991[/import]

Major issue is implementation of Box2D dependent on fps. Time based implementation should be available for fast moving object. [import]uid: 12704 topic_id: 19839 reply_id: 76992[/import]

@Jay

on my config it’s 60fps, but doesn’t matter.

Build settings are based on ipad.

Basically, have to do some time stepping offset to get it right, I think?

Hmmmm…grrr. [import]uid: 61600 topic_id: 19839 reply_id: 77084[/import]

I could just be blowing smoke, because I haven’t been at a very low level since the “olden days” when I was doing assembly language game programming. I can remember chasing bugs that resulted from moving objects too fast – before the screen even had a chance to refresh it would be somewhere else and so didn’t look like it was even there.

Not sure if that type of thing could be happening in your case, but creating test case to discard or highlight that possibility might be worth the time.

Especially if you’re at the point where you’re just throwing things at it to see what happens. :slight_smile:

Jay
[import]uid: 9440 topic_id: 19839 reply_id: 77127[/import]

The problem with the “too fast” theory is WHY would it happen at a lower velocity, and happen at a higher velocity.
The problem I have is my whole world moves as a whole, with a lot of interactive stuff that goes on. That’s the most I can say about it :slight_smile:
For demonstrative purposes, the video shows what I need it to. But perhaps I can show another one that shows some different examples and post the code here.

What I find interesting is it happens MORE after something moves fast and then interacts with a slower object. It’s almost like the physics engine forgets what the hell is going on.
I’m exploring alternate methods to control the speed, but I rather not :slight_smile:

-ng

[import]uid: 61600 topic_id: 19839 reply_id: 77328[/import]

I have made some progress tonight.
So there are a few things I tried that GREATLY reduced my problems. I can’t say that it eliminated, but I can say over the last several tests, I only had one incident of pass through vs several pass throughs on each play through.

So, what I did is I dumped scale down to 1 and started messing with damping, Here it’s commented out with a few things and the velocity I had tied to another function. I basically provided it as something for others to mess with. :slight_smile:

 physics.setPositionIterations(128)  
 physics.setVelocityIterations(128) --   
 physics.setDrawMode( "normal")  
 physics.setScale(5 )  
 --  
local ball = display.newCircle (\_W/2 -30, \_H/2-300, 15)  
physics.addBody( ball, { density=.1, friction=.50, bounce=0.01, radius=15} )  
--ball.angularDamping = 40  
ball.linearDamping = 0 --.50  
--ball.angularVelocity = 10  
ball.isBullet = true  

And the kicker!

physics.start( true )  
 physics.setGravity( 0, 400 )  

So what the hell does all that mean above? Basically I wanted to get the same “feel” of a heavy object but take away some of the things that I believe increase chance of object pass through when colliding with a wall.
Density I set to lightest possible .1 and scale I put at 1, and that was weird, so I creeped up to 5 that was perfect, 6 was too much. So when it’s that light, gravity at 10 its like things are floating. So I had to increase gravity by a TON. 400 to 600 (still messing with it).

These settings were used in my actual game, I didn’t try them on the sample I provided as that doesn’t do me any good, but maybe it will do you some good.

Also, the grid/sectional set up I’m working on. It’s not quite functional, but I may not need it if I can pull this off.
Anyway, thought I share, I know people are having a hard time with this. Basically, keep density really low, gravity high and scale things down and utilize other parameters in order to achieve a “real” world feel in terms of weight, gravity etc. It’s not perfect, but I’m still fine tuning the whole thing :slight_smile:

-ng

[import]uid: 61600 topic_id: 19839 reply_id: 77510[/import]

Well, I used to get pass through objects within seconds, even after all the position iterations and damping etc etc etc.
What does it take to basically 99,99% cure this problem with pass through objects.
A LOT OF DAMN TIME THATS WHAT.
You REALLY REALLY REALLY REALLY REALLY REALLY REALLY REALL (100 more reallys in there) mess with things. I mean TEAR THINGS APART!!!

  
 local physics = require "physics"  
 physics.setPositionIterations(128)  
 physics.setVelocityIterations(128) --   
 physics.setDrawMode( "normal")  
 physics.setScale(7 )  
 --for some of the bodies in my game  
 myBody.angularDamping = 1   
  
 --Some other options that may or may not work for you  
--myBody.linearDamping = 25  
--myBody.angularVelocity = 10  

That code above (obviously you have to tune things to fit your project) is 97% gets you almost perfect.

The last 3% I had to write a extremely complex algorithm (keep in mind I’m new to coding since June 2011, so this was TOUGH)
I call it:
MLMOMGADALCA = MULTI LAYER MULTI OBJECT MULTI GRID ADAPTIVE DAMPING ADAPTIVE LINEAR ANGLE CALCULATING ALGORiTHM

Basically, what that means is I had objects welded to objects with sensors on inside and outside that detect pre collision and it ups the iterations, damping etc intelligently based on velocity parameters.
Basically in plain english, if something is hauling ass, it increases the ‘tools’ effectiveness by ramping up damping, and velocity stuff.

So lets say you have a wall
|| << thats my wall. and lets say you have a ball traveling towards the wall

|| As the ball gets closer a pre collision checks and gets velocity and distance and ‘slowly’ ramps up the # on damping and iterations. So instead of 128 on position iterations, it’s actually at 16, but ramps up (if it went instantly you get a BIG frame drop).
Before I wrote that, this is what helped me out to get me 97% correct. When I release my game, people will UNDERSTAND why these things were so important to me!
Some things you can do to prevent things going through other things:

-Increase the thickness of an object
-‘embed’ an object within another one

—ie, here is a normal wall || here is a wall within a wall |[]| the [] is a rect inside of a rect, but thinner than the original one. What happens is an objet will hit the first one, slow down and then reach the second where it usually (not always) will stop the object. This method helped me (I made it up lol, I was like hey soothing inside of something, maybe that works?) but it only got me so far…
–now you need an player within a player so when it hits the wall within the wall, you get 4x better collision (at a cost of performance

So lets say you have a ball. You put a circle within a circle, and weld them. So if one has a radius of 15 you put the other one as half of that (not an exact science). So essentially you have 4 physics objects, 2 of what a player sees, 2 of them are at alpha 0 (hidden from view, but taking up more space and cpu time).
Those things above helped. Then we get into Grids…omg this was crazy!!!
Above, in a previous post I recommend reading that. It’s applicable to our situation. If you are doing objects within objects, then you want to break out your world so only things getting processed that are within a grid get cpu time…
Wow, its late now. I’m just so amped I got this working after MONTHS of experimentation:)
If you are having problems with your project let me know, I can steer you in the right direction and help you out :slight_smile:
ng

The problem that was big for me was the “feel” of the control mechanism, which is purely one finger touch based. [import]uid: 61600 topic_id: 19839 reply_id: 77723[/import]

Hi,

first of all thanks a lot for this blog. I am racking my brain with similar problem.

I’m using: Corona SDK on MacOSX

Steps to reproduce:

In Simple Pool game try to strike the cue at the edge of any other balls it
simply passes through it.

Similar behavior with games involving pucks or short cylindrical(round)
objects.

-take two pucks and strike one puck using function cueShot()
on the edge of another puck in a board game.
-when you hit the edge of another puck with speed, the collision is not
detected and the first puck simply passes through the edge of the second
puck.


(Tried to set the bullet property but its not working) [import]uid: 95127 topic_id: 19839 reply_id: 78035[/import]

@girishvinr
Challenge accepted. Ok so I’m going to go ahead and get the pool project and take a look.

Let’s see what I come up with

First I am going to focus on this, which usually will solve some other problems:

#1 In Simple Pool game try to strike the cue at the edge of any other balls it
simply passes through it.

I’ll take a crack at this, then post the code here ( I won’t post the entire project, just the lines or chunks of code modified.

-Keep an eye on this thread :slight_smile:

ng [import]uid: 61600 topic_id: 19839 reply_id: 78232[/import]

Ok, I was just taking a look at simple pool and simple pool plus, but I am not sure what you might be talking to in regards to
#1 In Simple Pool game try to strike the cue at the edge of any other balls it
simply passes through it.

 physics.setPositionIterations(128)  
 physics.setVelocityIterations(128) --   
 physics.setDrawMode( "normal")  

The draw mode was just something I put in there so I could test “debug” and “hybrid” to see what the actual physics bodies looked like vs what’s being shown on screen.
When I pull the “cue” back, I don’t have a choice of a “side” it’s just a circle target that allows me to pull back. Could you shed some more light on what you are after?
By the way, the code above, will GREATLY increase collision effectiveness at the cost of performance (depends on the game, I tested it on both simple pool and pool plus and it wasn’t really noticeable).

ng [import]uid: 61600 topic_id: 19839 reply_id: 78234[/import]

Hi,
Thanks for the quick reply.

When I pull the “cue” back, I don’t have a choice of a “side” it’s just a circle target that allows me to pull back. Could you shed some more light on what you are after?

-> When you pull the “cue” back, aim at the edge of the any other ball.
-> Use maximum speed of the cue.
-> When you take the shot, you’ll see that the cue simply passes through the targeted ball.
-> The “hybrid” mode also shows that the collision is detected but the target ball remains at its place.

Ideally the cue should hit the other ball at the edge and they both should divert at an angle.
(Might I suggest that you run the iPad version of the Game so that it’ll be easy to observe the collision)
[import]uid: 95127 topic_id: 19839 reply_id: 78634[/import]

physics.setPositionIterations(128)
physics.setVelocityIterations(128)

is not solving my problem completely. I might be missing something.

I have a board game similar to the pool game where I am using Pucks instead of the object balls in the pool game. I have a “striker” and a number of “coins” (both pucks). I want the user to be able to take an angular shot at the coin with the striker. However the collisions are not detected when the striker hits the coin on its circumference.
Interestingly the collision is detected if the striker is aiming at the center of the coin. The collision is not detected when the striker aims at the edge of the coin.

I found similar bugs in the Corona’s sample apps.
Let me know if the scenario is clear to you or not, also if you’d like me to send you the part of the code of my project. [import]uid: 95127 topic_id: 19839 reply_id: 78647[/import]

i have the same problem, when i hit the cueball with full speed and aim at the edge of the any other ball, it doesnt collide, anyone found a solution?

physics.setPositionIterations(128)
physics.setVelocityIterations(128)

doesnt work for me either.
[import]uid: 92107 topic_id: 19839 reply_id: 82770[/import]

@gtatarkin,
I’m facing similar problem as yours.
can you please tell me how you solved your problem.
[import]uid: 97420 topic_id: 19839 reply_id: 87335[/import]

I didn’t. You can try several settings to minimize the problem but I don’t see way to get rid of. [import]uid: 12704 topic_id: 19839 reply_id: 87338[/import]

@gtatarkin

thanks for letting me know.

major problem is,
container has linear velocity.
when objects, which are inside container, is trying to pass through the container walls, container is slowing down. I’m not able to prevent this. any ideas on this [import]uid: 97420 topic_id: 19839 reply_id: 87340[/import]

@gtatarkin

can you please tell me what settings you adjusted to minimize this problem. I tried few settings, but couldn’t get hold of it [import]uid: 97420 topic_id: 19839 reply_id: 87396[/import]