Welding bodies together becomes unstable

Official forum for the Chipmunk2D Physics Library.
Post Reply
User avatar
AmIMeYet
Posts: 6
Joined: Mon Aug 15, 2011 8:32 am
Contact:

Welding bodies together becomes unstable

Post by AmIMeYet »

I'm building a space-ship game, where you can continously attach and remove all kinds of modules to your ship. This is how a ship looks like right now: http://i.imgur.com/iQbo1.jpg. You can see the shapes and constraints.

The player can freely add more modules, like thrusters. However, if you add too much modules, things somehow start to shake violently when an impulse is applied. The structure becomes more volatile, the more modules are attached, sometimes getting so severe that modules get twisted out of place. Here are some images demonstrating this

I currently have each module connected like this:

Code: Select all

PinJoint.new(anchr_a.shape.body, anchr_b.shape.body, Vec2.new(0, 0), Vec2.new(10, 0))
PinJoint.new(anchr_a.shape.body, anchr_b.shape.body, Vec2.new(10, 0), Vec2.new(0, 0))
PinJoint.new(anchr_a.shape.body, anchr_b.shape.body, Vec2.new(0, 0), Vec2.new(0, 10))
This works by pushing the modules together, so they are bound by the constraints as well as collisions. I previously had only 2 joints positioned in a cross shape ( (0, 10) to (10, 0) and (0, -10), to (-10, 10) ), but because the modules can be mounted at different angles, this is not always a cross shape, allowing the modules to slide alongside their mount points.

If I add more constraints, the structure becomes more volatile. But if I remove constraints, the modules can move too freely, sliding alongside their mount points. I just want to 'weld' the modules together.

Any ideas how to fix this? Thank you in advance.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Welding bodies together becomes unstable

Post by slembcke »

So when you chain a lot of joints together like that with very specific solutions, they can get unstable very quickly. Because each set of joints (and collisions) is trying to enforce a very specific relative angle/position, when they try to correct the bodies they are attached to they uncorrect other sets of joints and vice versa. This causes a lot of jitter as you've seen.

The ideal way to solve this is to build the ship out of a single rigid body. When a piece is added or removed, recalculate where the center of gravity is of the whole thing by doing a weighted average of the CoGs of the individual pieces. The moment of inertia can be calculated by adding all the moments like this: sum += momentOfPiece + massOfPiece*cpvlengthsq(cpvsub(cogOfShip, cogOfPiece)) At that point all you need to do is to offset the collision shapes and add them all to the shared body. Because all of the pieces are added to a single rigid body, you should have 0 stability problems and your CPU load would be greatly decreased as well.

There was a contest game somebody I knew made a couple years back called GwOrp that is similar to yours. He used the procedure I described above and it worked really well for him. http://nehex.idevgames.com/articles/gw0rp_postmortem
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
AmIMeYet
Posts: 6
Joined: Mon Aug 15, 2011 8:32 am
Contact:

Re: Welding bodies together becomes unstable

Post by AmIMeYet »

Yeah, that could work. The code from Gw0rp's successor, Gluball is also quite useful.

You are saying total_moment += momentOfPiece + massOfPiece*cpvlengthsq(cpvsub(cogOfShip, cogOfPiece)). Is this the same as sum += CP.moment_for_poly(massOfPiece, vertsOfPiece, offsetOfPiece) (as I see Gluball is doing it), or am I mixing stuff up here?

Actually, I don't even have a clue how I should set the center of gravity.. it seems like what Gluball is doing would shift the structure, and then reposition the shapes to compensate, but I'd think that would cause the next update to shift everything again as the offsets for each unit (or module in my case) have changed.. Any further help would be appreciated.

Also, interesting postmortem. Thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Welding bodies together becomes unstable

Post by slembcke »

It's close-ish but not quite the same. Recalculating the moment using cpMomentForPoly() trusts you that the center of gravity really is at (0, 0) in poly coordinates after the offset is applied. The snippet I posted assumes the shape's CoG is still at it's original place, but has been shifted. Explaining it any better is sort of hard unless you know more about how the math works...

Anyway the numerical difference can be pretty big, maybe 2-3x off in a lot of cases, but the value can be off by a lot more before it becomes visibly wrong. I tried explaining the difference between the two in the docs, but I figured it would just cause more confusion. Most people want to use the moment function with an offset, and the ones that don't probably won't notice. :-\

So if it was possible to make the jointed together version work well, it would act similar to a single body with the moment calculated using the method above. On the other hand, the moment of inertia really doesn't need to be that close to a real value to feel correct and the moment functions are really only doing simple estimates by assuming uniform density which doesn't really ever happen anyway.

Long post short, it probably doesn't matter that much.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
AmIMeYet
Posts: 6
Joined: Mon Aug 15, 2011 8:32 am
Contact:

Re: Welding bodies together becomes unstable

Post by AmIMeYet »

So far I've only added some untested mass and inertia functions (good enough for now), and I am also able to attach module shapes to a single ship. I should have detachment done soon. The vector logic was a pain, but the speed benifits alone were worth it.

Thanks again for your help!
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests