Box2D and sticky collisions on low speed

My problem is that at low speeds objects do not bounce at all. They loose speed (=0).

I updated to last daily build: 2015.2779 and looked around and found that solution should be to set Box2D engine parameter b2_velocityThreshold which coresponds to “velocityThreshold” in physics.setMKS( key, value )

So i did test with code:

[lua]local physics = require(“physics”)

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

print( physics.getMKS( “velocityThreshold” ) )
physics.setMKS( “velocityThreshold”, 0 )
print( physics.getMKS( “velocityThreshold” ) )

local bottomWall = display.newRect( 100, 200, 300, 10 )
physics.addBody(bottomWall, “static”, {density = 1.0, friction = 0, bounce = 1, isSensor = false})

– create a ball and set it in motion
ball = display.newCircle( 20, 100, 15 )
physics.addBody(ball, “dynamic”, {density = 1.0, friction = 0.0, bounce = 1.0, isSensor = false, radius = 15} )
ball.isBullet = true
ball:setLinearVelocity( 0, 30 )[/lua]

This results in ball “falling” on rectangle and not bouncing.

will  not  bounce ball:setLinearVelocity( 0, 30 ),   ball:setLinearVelocity( 50, 30 )

will bounce ball:setLinearVelocity( 0, 31 ),   ball:setLinearVelocity( 50, 31 ),

My observations and test show that setMKS is not working as expected. Am i doing some mistake here ?

Thanks in advance

Hi @qwe0,

This is an uncommonly-used API so I’m not too familiar with what the “expected” behavior should be. Did you see this Box2D forum post?

http://www.box2d.org/forum/viewtopic.php?f=9&t=6131

Brent

use applyLinearImpulse() or applyForce() instead of setLinearVelocity()

@ Brent

ty for reply

the thing is when object bounces in nature there is no perfect bounce(like bounce=1.0). Always there is energy loss due to heat or transformation so you can achieve maybe 0.9999 but not 1.

This results (with gravity active) in smaller bounces every bounce.

In math this would result in lot of small bounces as you approach closer. Looking at time scale when they are very close number of bounces would go to infinity. And that is dangerous area when you have game. (you cant handle 1000 collisions in 1 sec).

So they put limit to stick object when it is performance intensive. I guess it was 30 px / sec.

 

both of these will result in same = object will have speed. They are just different physics models how to achieve this.

if you replace in my example ball:setLinearVelocity() with:

ball:applyLinearImpulse( 0, 0.785)  --> will result in speed 29.984792709351 --> which  will  stick

or

ball:applyForce( 0, 23.5 )  --> will result in speed 29.921129226685  --> which  will  stick

 

ty both for replays

sorry, was just a “drive by” reply - they’ll integrate differently, thought it might matter, but not if you’re intentionally trying to get under 1m/s*dt.  never had any success with velocityThreshold, you could trying faking it “in reverse” by decreasing physics scale (tho may have other side effects you won’t care for)

…or fake it with a bigger (fixed) time step (increase iterations to partially compensate), again potential side effects

fwiw, actually had a chance to run your code – here’s how i might set it up for very slow bounces

(caveat, again, is that if you “tune” it too much toward “slow”, then it may “suffer” with “fast” == tradeoffs)

local physics = require("physics") physics.start() physics.setGravity(0, 0) local PHYSICS\_SCALE = 5.0 local EPS = 0.000001 -- just some little bit physics.setScale(PHYSICS\_SCALE) -- local bottomWall = display.newRect( 100, 200, 300, 10 ) physics.addBody(bottomWall, "static", {density = 1.0, friction = 0, bounce = 1, isSensor = false}) -- -- create a ball and set it in motion ball = display.newCircle( 20, 100, 15 ) physics.addBody(ball, "dynamic", {density = 1.0, friction = 0, bounce = 1, isSensor = false, radius = 15} ) ball.isBullet = true ball:setLinearVelocity( 0, PHYSICS\_SCALE+EPS ) -- this is the bounce limit

Hi @qwe0,

This is an uncommonly-used API so I’m not too familiar with what the “expected” behavior should be. Did you see this Box2D forum post?

http://www.box2d.org/forum/viewtopic.php?f=9&t=6131

Brent

use applyLinearImpulse() or applyForce() instead of setLinearVelocity()

@ Brent

ty for reply

the thing is when object bounces in nature there is no perfect bounce(like bounce=1.0). Always there is energy loss due to heat or transformation so you can achieve maybe 0.9999 but not 1.

This results (with gravity active) in smaller bounces every bounce.

In math this would result in lot of small bounces as you approach closer. Looking at time scale when they are very close number of bounces would go to infinity. And that is dangerous area when you have game. (you cant handle 1000 collisions in 1 sec).

So they put limit to stick object when it is performance intensive. I guess it was 30 px / sec.

 

both of these will result in same = object will have speed. They are just different physics models how to achieve this.

if you replace in my example ball:setLinearVelocity() with:

ball:applyLinearImpulse( 0, 0.785)  --> will result in speed 29.984792709351 --> which  will  stick

or

ball:applyForce( 0, 23.5 )  --> will result in speed 29.921129226685  --> which  will  stick

 

ty both for replays

sorry, was just a “drive by” reply - they’ll integrate differently, thought it might matter, but not if you’re intentionally trying to get under 1m/s*dt.  never had any success with velocityThreshold, you could trying faking it “in reverse” by decreasing physics scale (tho may have other side effects you won’t care for)

…or fake it with a bigger (fixed) time step (increase iterations to partially compensate), again potential side effects

fwiw, actually had a chance to run your code – here’s how i might set it up for very slow bounces

(caveat, again, is that if you “tune” it too much toward “slow”, then it may “suffer” with “fast” == tradeoffs)

local physics = require("physics") physics.start() physics.setGravity(0, 0) local PHYSICS\_SCALE = 5.0 local EPS = 0.000001 -- just some little bit physics.setScale(PHYSICS\_SCALE) -- local bottomWall = display.newRect( 100, 200, 300, 10 ) physics.addBody(bottomWall, "static", {density = 1.0, friction = 0, bounce = 1, isSensor = false}) -- -- create a ball and set it in motion ball = display.newCircle( 20, 100, 15 ) physics.addBody(ball, "dynamic", {density = 1.0, friction = 0, bounce = 1, isSensor = false, radius = 15} ) ball.isBullet = true ball:setLinearVelocity( 0, PHYSICS\_SCALE+EPS ) -- this is the bounce limit