[Solved] love.physics Rotation Problem

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
User avatar
nat1192
Prole
Posts: 3
Joined: Tue Jan 25, 2011 4:40 am

[Solved] love.physics Rotation Problem

Post by nat1192 »

I've been having a problem with the Box2D system in Love. Most everything works properly, except what you might call rotational falls. Falls like when a box has passed its center of mass over a ledge, but doesn't fall. I have explicitly setFixedRotation(false) on all objects. I have even tried starting out one of the blocks with an initial angle of somewhere around 120 degrees, but it still remains constant. Any ideas? Also the "theta-meter" at the top is getAngle-ing the top most brick just in case it was a rendering glitch, which it isn't.

Image
Last edited by nat1192 on Tue Jan 25, 2011 5:15 pm, edited 1 time in total.
Thanks.
User avatar
tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

Re: love.physics Rotation Problem

Post by tentus »

Are you perhaps accidentally using setAngle somewhere? That could create the behavior I think you described.

The easiest thing to do would be to post the code you have so far so we can look at it and see exactly whats happening.
Kurosuke needs beta testers
User avatar
nat1192
Prole
Posts: 3
Joined: Tue Jan 25, 2011 4:40 am

Re: love.physics Rotation Problem

Post by nat1192 »

Right, I knew I forgot to post something.

Code: Select all

-- Object layout:
-- id = stringy-name, body = physics-body, shape = physics-shape, sprite = string-index-into-sprite-table

function love.load()
   world = love.physics.newWorld(0, 0, 1024, 600)
   world:setGravity(0, 700)
   world:setMeter(64)
   
   -- Open up a bottle of sprite(s)
   sprites = {}
   sprites["floor"] = love.graphics.newImage("floor.png")
   sprites["man"] = love.graphics.newImage("man.png")
   sprites["brick"] = love.graphics.newImage("brick.png")

   -- Manufacture some delicious objects
   objects = {}
   objects[0] = createRectangleObject("floor", 1024/2, 575, 1024, 50, 0, world, "floor")
   objects[1] = createCircleObject("man", 1024/2, 600/2, 32, 15, world, "man")
   objects[2] = createRectangleObject("brick1", 600, 500, 30, 16, 4, world, "brick")
   objects[3] = createRectangleObject("brick2", 600, 435, 30, 16, 4, world, "brick")
   objects[4] = createRectangleObject("brick3", 600, 484, 30, 16, 4, world, "brick")

   objects[2]["body"]:setFixedRotation(false)
   objects[3]["body"]:setFixedRotation(false)
   objects[4]["body"]:setFixedRotation(false)

   for id = 1, 4 do
      objects[id]["shape"]:setFriction(0.25)
   end
   objects[1]["shape"]:setFriction(0.17)

   local f = love.graphics.newFont(12)
   love.graphics.setFont(f)
   
   love.graphics.setBackgroundColor(131,192,240)
   love.graphics.setMode(1024, 600, false, true, 0)
   
end

function love.update(dt)
   world:update(dt)
   
   if love.keyboard.isDown("up") then
      objects[1]["body"]:applyForce(0, -1000)
   end
   

   if love.keyboard.isDown("right") then
      objects[1]["body"]:applyForce(300,0)
   elseif love.keyboard.isDown("left") then
      objects[1]["body"]:applyForce(-300,0)
   elseif love.keyboard.isDown("escape") then
      love.event.push('q')
   end
end

function love.draw()
   local boxwidth, boxheight = getBoxDims(objects[0]["shape"])
   love.graphics.print("theta", 10, 10)
   love.graphics.print(objects[3]["body"]:getAngle(), 50, 50)
   love.graphics.draw(sprites[objects[0]["sprite"]], objects[0]["body"]:getX() - boxwidth / 2, objects[0]["body"]:getY() - boxheight / 2)
   renderCircleObject(1,0)
   renderRectanlgeObject(2)
   renderRectanlgeObject(3)
   renderRectanlgeObject(4)
end

function getBoxDims(shape)
   local x1, y1, x2, y2, x3, y3, x4, y4 = shape:getBoundingBox()
   local boxwidth = x3 - x2 --calculate the width of the box
   local boxheight = (-1) * (y2 - y1) --calculate the height of the box
   return boxwidth, boxheight
end

function createRectangleObject(name, posx, posy, width, height, mass, worldT, spriteID)
   obj = {}
   obj["id"] = name
   obj["body"] = love.physics.newBody(worldT, posx, posy, mass, 0)
   obj["shape"] = love.physics.newRectangleShape(obj["body"], 0, 0, width, height, 0)
   obj["sprite"] = spriteID
   return obj
end

function createCircleObject(name, posx, posy, radius, mass, worldT, spriteID)
   obj = {}
   obj["id"] = name
   obj["body"] = love.physics.newBody(worldT, posx, posy, mass, 0)
   obj["shape"] = love.physics.newCircleShape(obj["body"], 0, 0, radius)
   obj["sprite"] = spriteID
   return obj
end

function renderRectanlgeObject(id)
   love.graphics.push()
   love.graphics.translate(objects[id]["body"]:getX(), objects[id]["body"]:getY())
   love.graphics.rotate(objects[id]["body"]:getAngle())
   local boxwidth, boxheight = getBoxDims(objects[id]["shape"])
   love.graphics.draw(sprites[objects[id]["sprite"]], -boxwidth / 2, -boxheight / 2)   
   love.graphics.pop()
end

function renderCircleObject(id, dOffset)
   if dOffset == nil then
      dOffset = 0
   end
   love.graphics.push()
   love.graphics.translate(objects[id]["body"]:getX(), objects[id]["body"]:getY())
   love.graphics.rotate(math.rad((objects[id]["body"]:getX() + dOffset) % 360))
   
   local radius = objects[id]["shape"]:getRadius()
   
   love.graphics.draw(sprites[objects[id]["sprite"]], -radius, -radius)
   love.graphics.pop()
end

No setAngle (although I did use setAngle to tip the box on its side to see if it would fall over; it didn't)
Attachments
src.zip
Here's the runnable code
(4.37 KiB) Downloaded 117 times
Thanks.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: love.physics Rotation Problem

Post by BlackBulletIV »

The first thing I can think of is, are you setting inertia? Inertia makes objects behave a lot more natural (say a level of 20-50), and usually helps to stop problems like this. With a quick glance at your code, I don't think you are, as you are passing 0 as the last argument (inertia) for the creation of your bodies. Try bumping that up to a number of 20-50 and see what it does.
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Denver, CO
Contact:

Re: love.physics Rotation Problem

Post by TechnoCat »

Code: Select all

   objects[2]["body"]:setMassFromShapes()
   objects[3]["body"]:setMassFromShapes()
   objects[4]["body"]:setMassFromShapes()
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: love.physics Rotation Problem

Post by Robin »

BlackBulletIV wrote:The first thing I can think of is, are you setting inertia? Inertia makes objects behave a lot more natural (say a level of 20-50), and usually helps to stop problems like this. With a quick glance at your code, I don't think you are, as you are passing 0 as the last argument (inertia) for the creation of your bodies. Try bumping that up to a number of 20-50 and see what it does.
That's it, I think.
TechnoCat wrote:

Code: Select all

   objects[2]["body"]:setMassFromShapes()
   objects[3]["body"]:setMassFromShapes()
   objects[4]["body"]:setMassFromShapes()
That would be even better, though not necessary to fix the problem (note that the mass argument passed to those functions has become useless)

Also, nat, FYI:

Code: Select all

object[1].body == object[1]["body"]
Help us help you: attach a .love.
User avatar
nat1192
Prole
Posts: 3
Joined: Tue Jan 25, 2011 4:40 am

Re: [Solved] love.physics Rotation Problem

Post by nat1192 »

Thanks a bunch guys. It was the inertia thing. For whatever reason I always get inertia and momentum mixed up (perhaps from "moment" of inertia), and I wondered why you would want to set an initial momentum. Anyways, that fixed it for me.

And thanks for that object[id].body tip Robin, that should save me from a lot of tedious typing. I should probably go actually learn Lua instead of picking it up from the few examples I've seen.
Thanks.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: [Solved] love.physics Rotation Problem

Post by BlackBulletIV »

nat1192 wrote:Thanks a bunch guys. It was the inertia thing. For whatever reason I always get inertia and momentum mixed up (perhaps from "moment" of inertia), and I wondered why you would want to set an initial momentum. Anyways, that fixed it for me.
No worries. I had the same issue happen, and I wondered why the physics system was so unrealistic; but then I remembered what inertia did, and there you go.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 5 guests