🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Parent -> Child Rotation Quaternions not behaving as expected

Started by
1 comment, last by DrDeath3191 5 years, 5 months ago

Hello, everyone.

I have begun using quaternions in my game code, as my game logic occurs in 3D space. My rendering, however, is done with sprites. So I use swing-twist decomposition to get the component of the quaternion in the Z-Axis, and the sprite rotates appropriately. So far, so good.

However, when I have a parented transform, it appears the quaternions act a bit strangely. I was under the impression that I could, from the accumulated world rotation, perform the swing-twist decomposition as normal, and apply the relative rotation to set my world rotation to this value for rendering. This did not work as planned. So I investigated, and found something that seems to be rather distressing.

As a test, I set my child quaternion to the conjugate of the parent (all quaternions are unit length). You would expect that this would result in no rotation at all. It does not. In fact, as far as I could tell, there seemed to be little change at all. I checked the quaternion multiplication; I get the identity quaternion, so that checks out. It appears that when I apply it to the world transformation calculation something is lost, but I don't know what. The calculation of the matrix is as follows (using the conjugate as the child rotation):


glm::mat4 childTransform = glm::translate(parentPosition)
* glm::mat4_cast(parentRotation)
* glm::scale(parentScale)
* glm::translate(childPosition)
* glm::mat4_cast(glm::conjugate(parentPosition))
* glm::scale(childScale)
* glm::translate(glm::vec3(-.5f, -.5f, 0));

Nothing seems wrong here in terms of matrix multiplication order. The position and scale are correct, but its not cancelling out the rotation as planned.

So I guess the questions are as follows:

  1. Why does inverting the parent quaternion in the child not cancel out the rotation?
  2. Is this actually the best means of accomplishing my goal of extracting the rotation on the Z-axis? Perhaps I am missing a more obvious solution to this issue.

Thank you very much for your help.

Advertisement

Alright, I think I figured it out at least partially.

My sprite's rotation was actually fine. The problem was scaling. Since the child scaling takes place in local rotated space, when I rotate it back using the conjugate the sprite is distorted by the parents rotation. I'm using an orthographic projection, so it was hard to tell the difference in my test case.

I can fix the issue by calculating each component of the transformation separately, and multiplying them together at the end, notably removing the rotation from the scale calculations. So if I want to do my decomposition trick, I can just do it with the final world rotation and use the resulting quaternion for the rendering matrix calcuation. But I worry doing things this way will introduce artifacts that I can't immediately see. Scaling in rotated space is actually the correct thing to do, so I'm not fully convinced that I'm doing things correctly, but I can't think of another way to solve the issue.

This topic is closed to new replies.

Advertisement