Incorrect rotated position of factory-spawned child objects (SOLVED)

I have a collection with a root object called “game”. There are creature objects which are spawned through factories that are parented to a child of “game”. Here’s how they look normally:

Since I can’t set an x-scale of -1, in order to flip the world I’m setting the rotation of the root “game” to 180° (i.e. π radians) in both x and z:
go.set_rotation(vmath.quat_rotation_x(3.141592653) * vmath.quat_rotation_z(3.141592653), "game")

But the positions of some (not all) factory-created children are now off-by-one in x and/or y:

All of the creatures have shifted up one pixel, half the stingers of the jellyfish on the left have shifted one pixel horizontally (the stinger is made up of multiple game objects each with an 8x8 sprite), one of the fish has shifted horizontally etc.

The positions of everything that was already a child of “game” in the collection are still pixel-perfect, only dynamically created objects through factories suffer from whatever is causing this, perhaps a precision error? My game is very low resolution (128x128) so a precision error might not have been noticed until now, I’m guessing.

Interesting. Maybe @sven, @Mathias_Westerdahl, @Johan_Beck-Noren or @ragnar.svensson have any ideas why this is happening?

Me, @sven and @Mathias_Westerdahl have discussed this and I played around with the same scenario in a sample project. It’s definitely a rounding error caused by the rotation. I did a setup where the “game” game object was on 64,64 and the childed game objects where in the range ±32,±32. Is this the same setup as you are using?

Game objects on negative positions, for example -32,-32 ended up at world position vmath.vector3(96, 31.999996185303, -2.7975290777249e-06) after rotation (it didn’t matter if they were spawned using a factory or there from the start).

Mathias pointed out that you’re using 3.141592653 instead of math.pi, but it didn’t help. It still got fractional values.

We did also discuss that it felt kinda strange to first rotate around the x-axis and the around the z-axis when a single rotation around the y-axis would suffice. And sure enough, with

go.set_rotation(vmath.quat_rotation_y(math.pi), "game")

the results had no rounding errors. Would you mind trying the same and see if that helps?

5 Likes

Thanks for checking this out! Just after I posted this I rediscovered math.pi in some older code but it similarly didn’t help.

My game was originally ported from PICO-8 where (0, 0) is the top-left and y increases down the screen. As a result my entire game takes place in negative y space so that I could take all y values from the PICO-8 version and simply negate them. Not quite the setup you had, but yes negative coordinates seems to be the issue.

I have no idea how I ended up rotating around x then z instead of simply y, but yes of course that does the same thing - and with no rounding errors! I get pixel-perfect rotations in negative y space using vmath.quat_rotation_y(math.pi), same as you. Thanks a lot!

5 Likes

Excellent! Good to hear that it works for you as well!

3 Likes