Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quaternion storage order inconsistent #916

Closed
sauraen opened this issue Jun 21, 2019 · 6 comments
Closed

Quaternion storage order inconsistent #916

sauraen opened this issue Jun 21, 2019 · 6 comments
Assignees
Milestone

Comments

@sauraen
Copy link

sauraen commented Jun 21, 2019

The members of the quaternion structs are stored in the order x, y, z, w, but the constructor takes them in the order w, x, y, z.

As explained further here https://stackoverflow.com/questions/48348509/glmquat-why-the-order-of-x-y-z-w-components-are-mixed , this also means that:

  • make_quat uses x, y, z, w
  • string_cast uses w, x, y, z
  • operator[] uses x, y, z, w

I don't see any good reason for inconsistency here. I believe w, x, y, z is the more natural way to represent it, though of course this can be argued. However, I do think more external code is likely to use the constructor and string_cast than memcpy / operator[], so I think it would be best to change the storage order to w, x, y, z. I'm happy to put in a pull request for this if you'd like--it's just swapping the letters on lines 58 and 63 of glm/detail/type_quat.hpp .

However, I would guess that this inconsistency is because there is some need for the storage to be x, y, z, w--perhaps it's this way in OpenGL? If so, then I would say everything needs to be changed to that order to be consistent, even though this will break everyone's code.

@jmatzen
Copy link

jmatzen commented Jun 25, 2019

This can't possibly be the first time or even the tenth that this has come up.

@Groovounet Groovounet self-assigned this Jul 12, 2019
@Groovounet Groovounet added this to the GLM 0.9.9 milestone Jul 12, 2019
@Groovounet
Copy link
Member

This issue is fixed in master branch for GLM 0.9.9.6 release.

This will cause some backward compatibility break to some application, this is why it wasn't change before...

Thanks for contributing,
Christophe

@sauraen
Copy link
Author

sauraen commented Jul 20, 2019

Thank you! I guess my statement above that it was only changing two lines was wrong, but thanks for keeping everything consistent!

@Barricade
Copy link

This has broken the glm::decompose function due to the behaviour of operator[] changed. May be this breaks other functions that use operator[] or quat{ x, y, z, w } initialization.

@pwipf
Copy link

pwipf commented Aug 6, 2019

Can this be re-opened or changed back?
Am I the only one for whom this change broke a lot of code?

I understand it would be nice to have consistency in the constructor, but changing the storage and operator[] is a huge huge break (and also very very confusing to figure out what happened). As an awesome, great-performance library to use with openGL, I think the constructor order weirdness is far less important than storage order consistency.

Quick examples, pushing memory holding many glm::quats to openGL. Also copying to other library formats... many more examples that would be very difficult to refactor to use .member syntax, and would create a significant performance hit.

When mentioning quaternions in general, one could argue the order, especially if the coefficients were named a,b,c,d. But in OpenGL i would argue that the expected order for 4-component things is x,y,z,w. I know there is no quat in OpenGL, but vec4 works just fine, assuming x y z w are in the same order.

My function for mimicking glm's quat functionality in glsl:

vec3 rotate_vertex_position(in vec3 v, in vec4 q)
{
// this is equivalent to glm:: v * q
return v + 2.0 * cross(cross(v, q.xyz) + q.w * v, q.xyz);
}

This would be very strange if I had to write ... q.yzw) + q.x ...
The other (much worse) option would be rearranging the order of large arrays of quaternions before getting them into gpu memory.

My recommendation is to change this back to the way it was, to avoid breaking lots of people's code in a way that they will not know anything has changed until far in the future when they build grab the latest glm version, and strange things happen.

As for this issue #916, I don't think this inconsistency is really a problem. Eigen library does the constructor and storage exactly the same (the same as glm used to):

"Warning
Note the order of the arguments: the real w coefficient first, while internally the coefficients are stored in the following order: [x, y, z, w]"

Changing the basic interface of glm is really going to cause people problems.

This might sound weird but instead you could add a 5 argument constructor that takes w on both ends (and ignores the second one).

Sorry to make this difficult. Please ignore me if I'm the only one thinking this way or using glm::quats this way!

Thanks!
Philip Wipf

@jmatzen
Copy link

jmatzen commented Aug 7, 2019

I agree this is going to break a lot of code. It could have some unintended consequences, especially in codebases that have poor testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants