Creating a WELD joint after 180º causes sudden jumps/glitches

In my game I can enable an upgrade that uses a WELD joint to add an item to the player spaceship. When creating the new object at the right position and rotation, then using physics.create_joint to WELD it, everything works exactly correctly most of the time. However, if I rotate the craft past 180º (by applying forces) then perform this operation (create and weld), the craft and new object jump to a different angle as the physics engine attempts to rectify some kind of mis-match in the wrapping of the angles. The objects get welded together at the correct angle.

I have used b2d.body.dump to determine that the angles seem to wrap around -pi to +pi but I think in some circumstances they are allowed to exist from -2pi to +2pi.

  • At first I was using get_world_position and get_world_rotation then setting the position and rotation of the new object in the collectionfactory.create call;
  • then I tried not setting them in create and instead using b2d.body.set_transform to set them, same result;
  • then I tried using b2d.body.get_position and b2d.body.get_angle and setting those on the newly created object’s body - in case it was some transformation between how defold stores these and how Box2D does, but even with this approach, I get the same results;

I have also tried wrapping the angles manually before setting them, to various limits (0-2pi, -pi to pi, etc.), and setting both bodies (the original and the newly created one) to the exact same value… but the problem remains. The interesting thing is that it’s not the absolute value of the angle that causes it, because if I destroy and re-create the object at the new angle, and also do this repeatedly as I approach the 180º point, it all works great, until I move past 180º again back to the first side of it, then the problem happens again. For example:
178º : Works
179º : Works
180º : Works
Then it wraps…
-179º : Problem
-178º : Works
Now I rotate back again…
-179º : Works
-180º : Works
Then it wraps…
179º : Problem

Notice how it works correctly on both sides of 180º except for the first time after passing that point. For this reason I am wondering if it’s something to do with a quaternion conversion (how they wrap round twice before repeating - which I don’t really understand), or perhaps there’s a LERP somewhere that there should be a SLERP? However, since this is converting to pass into Box2D, I would have thought that such things would be lost when converted to a simple z-angle, which is all Box2D is aware of. My other theory is that the way Defold wraps 2D angles vs the way Box2D does it is different.

Can anyone help me figure this out and provide a workaround, or suggestions? I found the source code for create_joint it in the engine, but it just passes things down to Box2D and so the issues must be in other places, but I don’t really know what to look for.

Oh, and I have also tried using a HINGE joint instead of WELD just to test what happens, and it works perfectly, so I am pretty sure the jerk is caused by Box2D trying to rectify the 2 angles (of the two bodies) to achieve the reference angle of zero, rather than anything wrong with the positioning. To re-iterate - this problem still happens when I set the angle of both bodies to the same value (with various wrapping-ranges) before creating the weld. So maybe that helps?

Please, try this Defold Physics Hinge Bug? - #7 by AGulev

1 Like

That is already turned off.