Physics object goes asleep, but not waking up?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
bizziboi
Citizen
Posts: 57
Joined: Sat Apr 16, 2011 9:24 am

Physics object goes asleep, but not waking up?

Post by bizziboi »

I have something that puzzles me.
Below is a bit of code that creates a circle, a static box and a rotating (kinematic box).
When the circle falls down it falls on the static box and goes to sleep - however, collision with the kinematic body doesn't wake it up so the collision goes totally unnoticed. Is that supposed to be like that?

If I set the circle to never go to sleep it works as expected but that's not optimal - a sleeping object is supposed to be woken up at collision?
I tried making the box dynamic instead of kinematic but it makes no difference (at least, if I set rotation explicitly, I'd rather not use forces myself, that's what kinematic bodies are for after all).

Anyone have an explanation, or solution (outside of disabling sleep on objects or, heaven forbid, the world?)

Thanks,
Kaj

Code: Select all

love.physics.setMeter(64)
world = love.physics.newWorld( 0 * 64, 0.981 * 64, true )
-- create a body
local body = love.physics.newBody(world, 100, 100, "dynamic")
local sphere = love.physics.newCircleShape( 30 )
local fixture = love.physics.newFixture(body, sphere, 100)    

--body:setSleepingAllowed(false)	-- >> putting this line in makes it work

-- create a body for the ground  - rectangle
local ground = love.physics.newBody(world, 90, 400, "kinematic")
local rect = love.physics.newRectangleShape( 800,100 )
local fixture = love.physics.newFixture(ground, rect, 100)
-- chainshape
--local polybody = love.physics.newBody(world, 90, 300, "static")
--local poly = love.physics.newChainShape( false, -100,0, 100, 0, 100, 100 )
--local fixture = love.physics.newFixture(polybody, poly, 100)
-- chainshape
local polybody = love.physics.newBody(world, 90, 300, "static")
--local poly = love.physics.newEdgeShape( -100,0, 100, 0 )
local poly = love.physics.newRectangleShape( 200,100 )
local fixture = love.physics.newFixture(polybody, poly, 100)


function love.update(dt)
	ground:setAngle(ground:getAngle()+0.1*dt)
	world:update(dt)
end

function DrawPhysicsShape(body,shape)
	love.graphics.push()
	love.graphics.translate(body:getPosition())
	love.graphics.rotate(body:getAngle())
	local type = shape:getType()
	if type == "circle" then
		love.graphics.circle("line",0,0,shape:getRadius())
	elseif type == "polygon" then
		love.graphics.polygon("line",shape:getPoints())
	elseif type == "chain" then
		love.graphics.line(shape:getPoints())
	end
	love.graphics.pop()
end

function DrawPhysicsBody(body)
	if body:getType() == "static" then
		love.graphics.setColor(255,0,0,255)
	else
		love.graphics.setColor(0,255,0,255)
	end
	local fixtures = body:getFixtureList()
	for i=1,#fixtures do
		local fixture = fixtures[i]
		local body = fixture:getBody()
		local shape = fixture:getShape()
		DrawPhysicsShape(body,shape)
	end
end
	
function DrawPhysicsWorld(world )
	local r,g,b,a = love.graphics.getColor()
	local bodies = world:getBodyList()
	for i=1,#bodies do
		DrawPhysicsBody(bodies[i])
	end
	love.graphics.setColor(r,g,b,a)
end

function love.draw()
	DrawPhysicsWorld(world)
end
User avatar
OmarShehata
Party member
Posts: 259
Joined: Tue May 29, 2012 6:46 pm
Location: Egypt
Contact:

Re: Physics object goes asleep, but not waking up?

Post by OmarShehata »

The reason the collision does not wake it up is because it "teleports".

There are three ways to move things in box2d. Applying forces, setting the velocity or skipping all that and setting the position. The last one is the least favorable because, to box2d, the object just teleports there, whether you set its angle or x and y, so it wouldn't really know how fast it was going or how the collision should resolve.

If I'm not mistaken, that's why it doesn't wake up when they collide. I understand not wanting to bother with forces, it can usually be hard to get the behavior you want, but setting the angular velocity to a constant value should make it rotate how you want it to. Try that, and it should work.

Also, setting an object to never sleep isn't such a big issue if it's something like the main player or something you know should never sleep.
bizziboi
Citizen
Posts: 57
Joined: Sat Apr 16, 2011 9:24 am

Re: Physics object goes asleep, but not waking up?

Post by bizziboi »

You're right, setting angular velocity instead of rotating manually does the trick.

This is strange, because that's what kinematic bodies are usually for (at least in other engines) - when you set the position they internally calculate the needed velocities to reach that position. I guess Box2D treats it differently which makes kinematic bodies pretty pointless, and also makes it tricky when you want something to follow an exact trajectory. Alas, I'll implement proper kinematics myself then - it's not that hard to derive the needed velocity and torque, I just assumed Box2D did that for me.

I know having one object not sleep is not a big issue, but it's not necessarily the player in a physics based game. Ah well, I'll cross that bridge when I get there.

Thanks for the help :o)
bekey
Party member
Posts: 255
Joined: Tue Sep 03, 2013 6:27 pm

[]

Post by bekey »

-snip-
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 198 guests