[Solved] Love.physics / box2d Weld Joint Failures after collision

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
timmeh42
Citizen
Posts: 90
Joined: Wed Mar 07, 2012 7:32 pm
Location: Cape Town, South Africa

[Solved] Love.physics / box2d Weld Joint Failures after collision

The basics:
• I have a truss/beam thing of physics square bodies connected by weld joints.
• If the forces in a weljoint become too large, that weld joint is destroyed.
• This produces a fairly destructible object.

However, once a weld breaks from a collision, 'residual' forces seem to stay in the other welds of the remaining parts of the beam; and instead of dissipating, these forces seem to grow without any outside force acting on them, eventually tearing the parts apart once they reach the break threshold. Is this a problem with my implementation, or is it some box2d restriction?

In the .love example, forces in each joint are printed above the joints, so its easy to see what happens:
Note the pieces after collision break up after a while.
weld_joints_failure.love
Last edited by timmeh42 on Thu Nov 10, 2016 9:48 pm, edited 1 time in total.

pgimeno
Party member
Posts: 2338
Joined: Sun Oct 18, 2015 2:58 pm

Re: Love.physics / box2d Weld Joint Failures after collision

It may not be an error. Welds are somewhat flexible, the object keeps shaking, if imperceptibly, and it's quite possible that the strain grows. Have you tried modelling the force via the distance instead? Welds should behave more or less like a spring, and break when the spring elongation is too big.

I've made a similar construction using [wiki]DistanceJoint[/wiki] instead, to model the connections of a slab on which another one falls, and graph the force on each slab. I varied the frequency (which is a weird way to specify a spring constant, by the way) and used the distance to model the breakage.

timmeh42
Citizen
Posts: 90
Joined: Wed Mar 07, 2012 7:32 pm
Location: Cape Town, South Africa

Re: Love.physics / box2d Weld Joint Failures after collision

Even with restitution (angular and linear) which should stop all motion after a while, the forces still grow or stay constant instead of decreasing. I've tried using distance joints, but they are too loose (and dont collide properly for some reason), and rope joints are both too loose (at least in a single-width beam) and still suffer some residual force.

pgimeno
Party member
Posts: 2338
Joined: Sun Oct 18, 2015 2:58 pm

Re: Love.physics / box2d Weld Joint Failures after collision

My suggestion was to use distance between elements as an indicator of strain, rather than getReactionForce.

timmeh42
Citizen
Posts: 90
Joined: Wed Mar 07, 2012 7:32 pm
Location: Cape Town, South Africa

Re: Love.physics / box2d Weld Joint Failures after collision

Ah, sorry i didn't catch that at first. Problem is I want my structure to be rigid, so any measurable distance would already be well past the breaking point.

Effectively like the example given here:
https://gamedevelopment.tutsplus.com/tu ... medev-2610
but with ships breaking into 2 pieces instead of having the broken-off bits just disintegrate as they do.

Separate bodies for each ship square seems to be the easiest for accurate breaking, since analysing the stress from multiple forces on a complex body would be fairly hard.

raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Love.physics / box2d Weld Joint Failures after collision

And it is, and that's exactly what happens under the hood anyway. You may want to give a go to soft bodies (rigid bodies don't exist either way) and use separate graphics that may mimic rigid structure if you need that.

pgimeno
Party member
Posts: 2338
Joined: Sun Oct 18, 2015 2:58 pm

Re: Love.physics / box2d Weld Joint Failures after collision

Well, I've modified your loop as follows, and it seems quite convincing to me:

Code: Select all

    --for i=1, length do
for i = 2, length do
if blocks[i].jointTop:isDestroyed() == false then
--fx, fy = blocks[i].jointTop:getReactionForce(1/dt)
--forc = ((fx^2)+(fy^2))^0.5
--if forc>8000 then
--      blocks[i].jointTop:destroy()
--end
local x, y = blocks[i-1].body:getPosition()
local x1, y1 = blocks[i].body:getPosition()
x, y = x-x1, y-y1
if math.sqrt(x*x+y*y) > 20.05 then -- or x*x+y*y > 402, if you want to save a square root
blocks[i].jointTop:destroy()
end
end

Which is no surprise because strain is proportional to elongation, and weld joints behave as springs too (thus the frequency parameter), and they will break when the strain exceeds a threshold.

timmeh42
Citizen
Posts: 90
Joined: Wed Mar 07, 2012 7:32 pm
Location: Cape Town, South Africa

Re: Love.physics / box2d Weld Joint Failures after collision

You're right, that does make sense, and I suppose if the joint force is simply based on distance then the behaviour between using distance vs force should be the same.

Why the residual forces exist in the first place doesn't matter anymore to me then, so thank you.

Who is online

Users browsing this forum: No registered users and 34 guests