Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glm::quat why the order of x,y,z,w components are mixed

I just started working with quaternions and noticed that the order of glm::quat elements are mixed. This is what I mean by this. If I declare a glm::quat like this

glm::quat quat = glm::quat(1, 2, 3, 4);

and then print the x,y,z,w like this

std::cout << quat.x << " " << quat.y << " " << quat.z << " " << quat.w;

it prints 2 3 4 1. Is this expected behavior? And if it is, what is the reason behind this?

like image 543
Saik Avatar asked Jan 19 '18 19:01

Saik


1 Answers

This is really frustrating. Various maths libs use different conventions, but GLM seems to be inconsistent even internally (at least as of early 2018).

The constructor glm::quat(...) is w, x, y, z:

quaternion.hpp:
GLM_FUNC_DECL GLM_CONSTEXPR tquat(T w, T x, T y, T z);

* beware empty constructors no longer initialize to the identity. See GLM_FORCE_CTOR_INIT. Could add to CFLAGS.

The internal order is x, y, z, w:

quaternion.hpp:
struct { T x, y, z, w;};

Using glm::make_quat simply does a memcpy, which is x, y, z, w:

type_ptr.inl:
memcpy(value_ptr(Result), ptr, sizeof(tquat<T, defaultp>));

Using glm::string_cast gives w, x, y, z:

string_cast.inl:

return detail::format(FormatStr.c_str(),
          static_cast<typename cast<T>::value_type>(x[3]),
          static_cast<typename cast<T>::value_type>(x[0]),
          static_cast<typename cast<T>::value_type>(x[1]),
          static_cast<typename cast<T>::value_type>(x[2]));

Note: The [] operator is return (&x)[i]; (which assumes x is first)

like image 110
jozxyqk Avatar answered Nov 11 '22 09:11

jozxyqk