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
andget_world_rotation
then setting the position and rotation of the new object in thecollectionfactory.create
call; - then I tried not setting them in
create
and instead usingb2d.body.set_transform
to set them, same result; - then I tried using
b2d.body.get_position
andb2d.body.get_angle
and setting those on the newly created object’sbody
- 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.